Skip to content

Commit

Permalink
Initial working web app scanner
Browse files Browse the repository at this point in the history
Functionally this seems to be working, one issue at the moment
is the original request is not available from the response
object. This means we don't know what the original backend ip
was.
  • Loading branch information
RyanJarv committed Dec 15, 2021
1 parent 63c7cff commit 70aba1b
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 44 deletions.
2 changes: 2 additions & 0 deletions cdn_proxy/lambdas/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
"@types/jest": "^26.0.24",
"@types/node": "^12.20.24",
"@types/react": "^17.0.20",
"@types/react-bootstrap-table-next": "^4.0.15",
"@types/react-dom": "^17.0.9",
"@types/react-router-bootstrap": "^0.24.5",
"@types/react-router-dom": "^5.1.8",
"ip-address": "^8.1.0",
"react": "^17.0.2",
"react-bootstrap": "^1.6.1",
"react-bootstrap-table-next": "^4.0.3",
"react-dom": "^17.0.2",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.3.0",
Expand Down
22 changes: 16 additions & 6 deletions cdn_proxy/lambdas/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import {HashRouter, Route, Switch} from 'react-router-dom';
import {LinkContainer} from 'react-router-bootstrap';

import {Nav, Navbar, NavDropdown} from "react-bootstrap";
import {Nav, Navbar, NavDropdown, Row} from "react-bootstrap";
import Container from "react-bootstrap/Container";

import './App.css';
Expand Down Expand Up @@ -56,15 +56,25 @@ const OurNavBarRouter = () => (
<HashRouter>
<Switch>
<Route path="/help">
<OurNavBar name="Help" />
<Help/>
<Row>
<OurNavBar name="Help" />
</Row>
<Row>
<Help/>
</Row>
</Route>
<Route path="/scanner">
<OurNavBar name="Scanner" />
<Scanner/>
<Row>
<OurNavBar name="Scanner" />
</Row>
<Row>
<Scanner/>
</Row>
</Route>
<Route path="/">
<OurNavBar name="Home" />
<Row>
<OurNavBar name="Home" />
</Row>
</Route>
</Switch>
</HashRouter>
Expand Down
8 changes: 4 additions & 4 deletions cdn_proxy/lambdas/src/CloudFrontScanner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test('calling request does not throw an error', () => {
jest.spyOn(global, "fetch").mockImplementation(() =>
Promise.resolve(new Response(Readable.from('asdf')))
);
scanner.request('1.1.1.1')
scanner.cdnRequest('1.1.1.1')
expect(fetch).toBeCalledTimes(1)
expect(fetch).toBeCalledWith('cdn-proxy.cloudfront.net', {
headers: expect.any(Headers),
Expand All @@ -31,12 +31,12 @@ test('calling request does not throw an error', () => {

test('calling scan does not throw an error', () => {
let scanner = setupScanner()
jest.spyOn(scanner, "request").mockImplementation((backendHost: string) =>
jest.spyOn(scanner, "cdnRequest").mockImplementation((backendHost: string) =>
Promise.resolve(new Response(Readable.from('asdf')))
);
scanner.scan(['1.1.1.1'])
expect(scanner.request).toBeCalledTimes(1)
expect(scanner.request).toBeCalledWith('1.1.1.1')
expect(scanner.cdnRequest).toBeCalledTimes(1)
expect(scanner.cdnRequest).toBeCalledWith('1.1.1.1')
});

test('calling textToIps with /32 results in single address', () => {
Expand Down
20 changes: 14 additions & 6 deletions cdn_proxy/lambdas/src/CloudFrontScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class CloudFrontScanner {
// host headers. Only one host header is supported now, but later this list will include hosts we want to test for
// each ip/domain and scheme combination. This allows for brute forcing the domain when we have several we might be
// expecting.
public request(backendHost: string) {
public cdnRequest(backendHost: string): Promise<Response> {
let hdrs = new Headers({
'Cdn-Proxy-Origin': backendHost,
})
Expand All @@ -30,15 +30,23 @@ export class CloudFrontScanner {
hdrs.set('Cdn-Proxy-Host', backendHost)
}

fetch(this.cdnProxy, {headers: hdrs})
.then(resp => console.log(resp.text()))
return fetch(this.cdnProxy, {headers: hdrs})
}

public scan(backends: Array<string>) {
for (const i in backends) {
this.request(backends[i])
scan(
backends: Array<string>,
// onfulfilled?: ((value: Response) => PromiseLike<Response>) | undefined | null,
onfulfilled?: ((value: Response) => any),
onrejected?: ((reason: any) => any),
) {
for (const backend of backends) {
this.cdnRequest(backend).then(onfulfilled, onrejected)
}
}

public forEachResult(backends: Array<string>) {

}
}


Expand Down
93 changes: 67 additions & 26 deletions cdn_proxy/lambdas/src/Scanner.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,83 @@
import React, {ChangeEvent, FormEvent, useState} from "react";
import {Button, Form, Row} from "react-bootstrap";
import {Button, Col, Form, Row, Table} from "react-bootstrap";
import Container from "react-bootstrap/Container";
import {CloudFrontScanner, textToIps} from "./CloudFrontScanner";
import BootstrapTable from 'react-bootstrap-table-next';

const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'url',
text: 'URL'
}, {
dataField: 'result',
text: 'Result'
}];

function Scanner() {

const [isLoading, setLoading] = useState(false);
function Scanner() {
// const [isLoading, setLoading] = useState(false);

const [ipRange, setIpRange] = useState("");
const [scanner,] = useState(new CloudFrontScanner(window.location.hostname));
let [products, setProducts] = useState<Array<{ id: Number, url: string; result: string; }>>([]);


return <Container>
<Row>
<Form>
<Form.Group className="mb-3" controlId="formBasicEmail" >
<Form.Label>IPs to Scan</Form.Label>
<Form.Control type="text" placeholder="IP CIDR" onChange={(e: ChangeEvent<HTMLInputElement>) => {
setIpRange(e.currentTarget.value);
console.log("ipRange: " + ipRange);
}} />
<Form.Text>
Enter the IP range to scan in CIDR notation.
</Form.Text>
</Form.Group>

<Button
variant="primary"
// className="scan-shit"
disabled={isLoading}
onClick={isLoading ? undefined : () => {
scanner.scan(textToIps(ipRange));
setLoading(true);
}}
>
Submit
</Button>
<Row>
<Col sm={1}>
<Button
variant="primary"
type="submit"
// className="scan-shit"
// disabled={isLoading}
onClick={() => {
scanner.scan(
textToIps(ipRange),
(resp) => {
console.log("response is: " + JSON.stringify(resp));
console.log("products currently is: " + JSON.stringify(products));
setProducts((prev) => {
prev.push({
'id': products.length,
'url': resp.url,
'result': resp.status.toString(),
}); return prev
})
},
(resp) => {
console.log(resp);
}
);
// setLoading(true);
}}
>
Submit
</Button>
</Col>

<Col sm={4}>
<Form.Group>
{/*<Form.Label>IPs to Scan</Form.Label>*/}
<Form.Control type="text" placeholder="IP CIDR" onChange={(e: ChangeEvent<HTMLInputElement>) => {
setIpRange(e.currentTarget.value);
console.log("ipRange: " + ipRange);
console.log("products: " + JSON.stringify(products));
}} />
<Form.Text>
Enter the IP range to scan in CIDR notation.
</Form.Text>
</Form.Group>
</Col>

</Row>
</Form>
<Row>
<Col sm={12}>
<BootstrapTable keyField='id' data={ products } columns={ columns } />
</Col>
</Row>
</Container>
}
Expand Down
25 changes: 23 additions & 2 deletions cdn_proxy/lambdas/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1922,6 +1922,13 @@
resolved "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz"
integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==

"@types/react-bootstrap-table-next@^4.0.15":
version "4.0.15"
resolved "https://registry.yarnpkg.com/@types/react-bootstrap-table-next/-/react-bootstrap-table-next-4.0.15.tgz#8f011af46d16722fb70016be817d7dba21035698"
integrity sha512-VvhfXZof42smWxadZGvsnggC2CXkfaSjn/qtaiCApyUURAo3U9dJ/QU8WpIY4VzNHfEVstL5OPf0e4jA9lZqfg==
dependencies:
"@types/react" "*"

"@types/react-dom@^17.0.9":
version "17.0.9"
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz"
Expand Down Expand Up @@ -3417,7 +3424,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"

classnames@^2.3.1:
classnames@^2.2.5, classnames@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
Expand Down Expand Up @@ -9234,6 +9241,15 @@ react-app-polyfill@^2.0.0:
regenerator-runtime "^0.13.7"
whatwg-fetch "^3.4.1"

react-bootstrap-table-next@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/react-bootstrap-table-next/-/react-bootstrap-table-next-4.0.3.tgz#b55873b01adfe22a7181904b784a9d24ac2822cf"
integrity sha512-uKxC73qUdUfusRf2uzDfMiF9LvTG5vuhTZa0lbAgHWSLLLaKTsI0iHf1e4+c7gP71q8dFsp7StvkP65SxC1JRg==
dependencies:
classnames "^2.2.5"
react-transition-group "^4.2.0"
underscore "1.9.1"

react-bootstrap@^1.6.1:
version "1.6.3"
resolved "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.6.3.tgz"
Expand Down Expand Up @@ -9437,7 +9453,7 @@ [email protected]:
optionalDependencies:
fsevents "^2.1.3"

react-transition-group@^4.4.1:
react-transition-group@^4.2.0, react-transition-group@^4.4.1:
version "4.4.2"
resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz"
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
Expand Down Expand Up @@ -11023,6 +11039,11 @@ uncontrollable@^7.2.1:
invariant "^2.2.4"
react-lifecycles-compat "^3.0.4"

[email protected]:
version "1.9.1"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==

unicode-canonical-property-names-ecmascript@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz"
Expand Down

0 comments on commit 70aba1b

Please sign in to comment.