Giter VIP home page Giter VIP logo

cursedchrome's Introduction

CursedChrome

NOTICE

I thought this was clearly-implied, and that these disclaimers were redundant at this point, but:

This is a tool written for professional red teams. It helps simulate an often unpracticed attack scenario involving malicious browser extensions. If you're planning on using this to maliciously spy on your friend/girlfriend/victims, let me know your address and intent and I'll gladly forward your message to your local LEO for your convenience.

Blue Teams/Defenders/CorpSec

If you're on the blue team and wondering about ways to defend against this, take a look at my ChromeGalvanizer project, which generates easy-to-install Chrome enterprise policies to defend against attacks like this. An easy-to-use hosted version is available here.

What is it?

A (cursed) 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.

Why make it?

More and more companies are moving toward the "BeyondCorp" model (e.g. no flat internal network, zero trust everything). This is usually implemented via a reverse proxy/OAuth wall gating access to services, eliminating the need for a VPN. As access and tooling move towards being strictly available via the web browser, having a way to easily hijack and use victim's web sessions becomes an ever increasing necessity.

This is also especially useful for locked down orgs that make use of 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.

Screenshots

Web Admin Panel

Browsing Websites Logged In as Victim (using Firefox with HTTP Proxy)

(Rough) Infrastructure Diagram (docker-compose Used)

Ports & Listening Interfaces

  • 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.
  • 127.0.0.1:4343: Websocket server, used for communicating with victim Chrome instances to transfer HTTP requests for proxying and sending commands.
  • 127.0.0.1:8118: Admin web panel for viewing victim Chrome instances and getting HTTP proxy credentials.

IMPORTANT: If you are proxying through CursedChrome using Firefox please use FoxyProxy. The built-in proxy support for Firefox has bugs in its implementation of authenticated HTTP proxies which will drive you to madness.

Requirements

Installation & Setup (~5-10 Minutes)

Step-By-Step Video Tutorial

If you're looking for an easy video walkthrough on setting up CursedChrome check out this video created by @TurvSec.

If you'd prefer just reading the installation instructions, continue on.

Setting Up the Backend

The backend is entirely dockerized and can be setup by running the following commands:

cd cursedchrome/
# Start up redis and Postgres containers in the background
docker-compose up -d redis db
# Start the CursedChrome backend
docker-compose up cursedchrome

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).

Installing the CursedChrome CA for Proxying HTTPS

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.

You will need to install this CA into your root store, the following are instructions for various OS/browsers:

IMPORTANT: If you are proxying through CursedChrome using Firefox please use FoxyProxy. The built-in proxy support for Firefox has bugs in its implementation of authenticated HTTP proxies which will drive you to madness.

Setting Up the Example Chrome Extension Implant

To install the example chrome extension implant, do the following:

  • Open up a Chrome web browser and navigate to chrome://extensions.
  • Click the toggle in the top-right corner of the page labeled Developer mode to enable it.
  • Click the Load unpacked button in the top-left corner of the page.
  • Open the extension/ folder inside of this repo folder.
  • Once you've done so, the extension will be installed.

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.

After you've install the extension it will show up on the admin control panel at http://localhost:8118.

Required for some sites: Sync Cookies from Remote Victim

Some sites* require client-side (e.g. JavaScript utilized) cookies, for these sites you'll need to have the cookies permission in your implant's manifest.json in addition to the other required permissions.

If you have this permission declared, you can then use the Firefox/Chrome extension found in the cookie-sync-extension/ folder. Load it into your web browser, enter the web panel URL (usually http://localhost:8118) and your bot's username/password and click the Sync Remote Implant Cookies to load all of your victim's cookies locally.

NOTE: For Firefox you will need to load the manifest.json file as a temporary add on.

How magical!

Google Cloud Console is one of these sites - why Google? Why?

Production/Operational Usage

Modifying Implant Extension

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.

The following extension permissions are needed by the implant to operate:

"permissions": [
	"webRequest",
	"webRequestBlocking",
	"<all_urls>"
]

If you want to utilize the Cookie Sync extension to sync the remote browser's cookies with your own (required for some sites), ensure the permission cookies is also declared.

This code contains comments on how to modify it for a production setup. Basically doing the following:

  • Minifying/stripping/uglifying the JavaScript code
  • 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.
  • If you are using this in an attack scnario, you will also need to find where redirect-hack.html is referenced in background.js and replace instances with an HTML file which already exists in the extension you're overriding. Viewing the extension's source should make this easy.

In a real world attack, this extension code would be used in one of the following ways:

  • Injected into an existing extension with proper permissions via Chrome debugging protocol.
  • Hidden inside of another extension
  • Force-installed via Chrome enterprise policy

These topics are outside of the scope of this README, but eventually will be covered separately.

Further Notes on Production Deployments

  • 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. If you go this route, you'll want to update your Websocket address from ws:// -> wss://.
  • 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.
  • 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.

Attributions

  • The AnyProxy source code was heavily modified and used for part of this project.
  • The icon for this project was designed by monochromeye on Fiverr (paid), if you're looking for graphic design work check her services out.

cursedchrome's People

Contributors

mandatoryprogrammer avatar matir avatar psie-corp avatar telwell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cursedchrome's Issues

License?

What license is this code under? Can you add a LICENSE/COPYING file to clarify that?

Failed to parse or set cookie named "__Host-xxxxx".

Not sure why the cookie sync extention is failing to parse these Gmail cookies

Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-1PLSID".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-3PLSID".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-GAPS".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-GMAIL_SCH_GMN".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-GMAIL_SCH_GMS".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-GMAIL_SCH_GML".
Unchecked runtime.lastError: Failed to parse or set cookie named "__Host-GMAIL_SCH".

Chrome Plugin Error

The chrome plugin wont connect back to my server it says cant establish a session i have followed the steps correctly but it wont work? Any help would be appreciated.

Unauthenticated WebSocket has disconnected from us.

cursedchrome_1 | [March 9th 2022, 7:21:36 pm] A new browser has connected to us via WebSocket!
cursedchrome_1 | [March 9th 2022, 7:21:36 pm] Authenticating newly-connected browser...
cursedchrome_1 | [March 9th 2022, 7:21:36 pm] Unauthenticated WebSocket has disconnected from us.
cursedchrome_1 | (node:20) UnhandledPromiseRejectionWarning: A timeout occurred when authenticating WebSocket client.
cursedchrome_1 | (node:20) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

Crash when hitting the proxy without credentials

Hosting this on an Ubuntu 18.04 server with Docker version 19.03.8, build afacb8b7f0.

I am using a socks proxy to view the interface on 8118. When I go to localhost:8080 in my browser without proving creds, the container crashes with the following log:

cursedchrome_1  | [April 30th 2020, 8:32:47 pm][::ffff:172.18.0.1] Request denied for URL http://localhost:8080/, no authentication information provided in proxy HTTP request!
cursedchrome_1  | [April 30th 2020, 8:32:47 pm] No proxy credentials provided!
cursedchrome_1  | undefined
cursedchrome_1  | [April 30th 2020, 8:32:47 pm][::ffff:172.18.0.1] Request denied for URL http://localhost:8080/favicon.ico, no authentication information provided in proxy HTTP request!
cursedchrome_1  | /work/node_modules/brotli/build/encode.js:3
cursedchrome_1  | 1<process.argv.length?process.argv[1].replace(/\\/g,"/"):"unknown-program");b.arguments=process.argv.slice(2);"undefined"!==typeof module&&(module.exports=b);process.on("uncaughtException",function(a){if(!(a instanceof y))throw a;});b.inspect=function(){return"[Emscripten Module object]"}}else if(x)b.print||(b.print=print),"undefined"!=typeof printErr&&(b.printErr=printErr),b.read="undefined"!=typeof read?read:function(){throw"no read() available (jsc?)";},b.readBinary=function(a){if("function"===
cursedchrome_1  |                                                                                                                                                                                                                               ^
cursedchrome_1  |
cursedchrome_1  | TypeError: Cannot convert undefined or null to object
cursedchrome_1  |     at Socket.<anonymous> (/work/anyproxy/lib/requestHandler.js:288:50)
cursedchrome_1  |     at Socket.emit (events.js:322:22)
cursedchrome_1  |     at TCP.<anonymous> (net.js:672:12)
cursedchrome_1  | [April 30th 2020, 8:32:47 pm] worker 19 died

Binary Request Body Gets Corrupted

I'm sorry for such a vague bug, but I've been trying to narrow it down better for a while with little success.

Steps to reproduce:

  1. Go to a file upload page and upload a non-ascii file (i.e., an image is a good choice)
  2. Note that the file received on the server is changed (seems to always be larger) -- some servers will reject due to checking length

I traced things through the websocket protocol to the implant and things appear fine at the point it's inserted into the fetch request. My working theory is that the fetch api does not like the body being invalid unicode, but I don't know nearly enough about fetch to say that for sure.

Javascript setting a cookie client-side is not propagated to victim

If a cookie is set in a javascript this will not be properly propagated back to the victim and used in requests. One potential way this could be fixed is to run some kind of helper/extension on the attacker side which could send some kind of control messages to the proxy to set these cookies on the victim side as well.

PS. Sorry for dropping a batch of issues like this. We have an ambition of providing PRs as well but letting you know about these things straight away in the meantime.

Blank Screen

Provided all the correct information but still, it's not loading any site.
image
image

Improperly handling lazy loading of content.

This plugin fails on pages that load some content after landing and fails to process any loading after a 301 or 302. I suspect it is now confused about the origin of the request. We should probably still process requests from domains where we reside - and that are permitted by the CSP of the page or server.

Try to use this plugin to visit Twitter or Facebook. You'll see the issue right away.

WebSocket connection Fails

Great work here, having an issue with the extension end, WebSocket connection to 'ws://"my_ip":4343/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT

I did this routing on CursedChrome directory before installing as directed by Turv, any help somebody, thanks.

Provide way to enable anyproxy logging

Just spent ~hours debugging an issue that became immediately clear when silent was set to false for anyproxy. It would be great if that was either the default (much more verbose logs, of course) or at least configurable.

later?

Hi Bryant, once I have installed CursedChrome CA for Proxying HTTPS in Kali Linux, google-crome, what should I do ??
Thanks and sorry for my English

Streaming HTTP responses not handled

The current setup requires the HTTP response to completely finish to be able to return the response to the headers. In some situations, a website will reply with a response of unknown length and use it to stream data as response to other events. This will not work and the request will instead just timeout on the attacker side.

PS. Sorry for dropping a batch of issues like this. We have an ambition of providing PRs as well but letting you know about these things straight away in the meantime.

Show UUID in UI

To help correlate log files to the UI, it would be nice to have the UUID visible, even if when clicking the gear for settings or something.

Duplicate headers are not properly handled

If the HTTP response to the victim contains multiple headers with the same key, for example:

...
Set-Cookie: A=B; attr1; attr2
Set-Cookie: X=Y; attr3; attr4
...

They will not be properly returned as separate headers from the proxy but instead concatenated into one like this:

Set-Cookie: A=B; attr1; attr2, X=Y; attr3; attr4

This breaks setting multiple cookies and possibly other response headers (though Set-Cookie is the only header explicitly forbidden to merge) as well. This can be solved by replacing the headers object with a list of key-value pairs to allow for multiple headers of the same key.

PS. Sorry for dropping a batch of issues like this. We have an ambition of providing PRs as well but letting you know about these things straight away in the meantime.

Ability to delete Bots

It would be great to have a UI option to delete bots, so that any test/known expired bots can be removed to clean up the UI.

2023-07-06

CursedChrome encountered an error while requesting the page.

Injecting into strict mode fails

If the extension code is injected into another extension running in strict mode ("use strict"), it currently throws an exception on undeclared variable cookies.

I'll send a PR.

Cookies already present on the victim not propagated to attacker

In some cases, cookie values are used inside javascript code to calculate for example CSRF headers. If this cookie is already set on the client when the attack begins. It would be good if there was a way to "sync" previously set cookies back to the attacker to make sure the state is as similar as possible between the two browsers.

PS. Sorry for dropping a batch of issues like this. We have an ambition of providing PRs as well but letting you know about these things straight away in the meantime.

Permissions required?

Is there a meaningful difference between <all_urls> and "https://*/*", "http://*/*" in how this extension uses things? It would seem to preclude file://, ftp://, and chrome-extension:// URLs, though I believe it can still access its own extension resources.

npm issue

I have problem in step 6. Output:
npm

`Step 6/22 : RUN npm install
---> Running in 7f45c4fbab3a
npm WARN [email protected] No description
npm WARN [email protected] No repository field.

npm ERR! network timeout at: https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz

npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2020-05-01T06_30_49_675Z-debug.log
ERROR: Service 'cursedchrome' failed to build: The command '/bin/sh -c npm install' returned a non-zero code: 1
`

Requesting Assistance with Slow Server-Browser Connection ๐Ÿ’๐Ÿ‘Œ

I am encountering some difficulties with the setup process, specifically regarding the connection between the server and the browser. I have followed a video tutorial by [@TurvSec], which provided some guidance, but unfortunately, it was not comprehensive enough to resolve my issue. Consequently, I am reaching out to request your assistance.

If you could spare some time to provide us with detailed instructions on how to establish a smooth and efficient connection between the server and the browser, I would be extremely grateful. Any additional guidance, tips, or troubleshooting steps you could offer would be invaluable to me and others who may be facing similar challenges.

Thank you in advance for your time and support. I understand that you may be busy, but any assistance you can provide will be highly appreciated. Please let me know if there are any specific details or logs I can provide to assist you in diagnosing the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.