Tips & tricks #1: MITM proxy with fakenet and realnet mode

This post will be the first of quick tips & tricks series. I don’t have the time, and to be honest nor the inspiration lately to write longer in-depth posts as I would like to. Therefore I will stick to shorter forms, hopefully this will make this blog a little bit more alive.

In this short tip, I would like to share with you my setup for a Man-in-the-Middle proxy for my malware analysis lab. When porting my lab to the new machine I had to reconfigure few things, and to my surprise I found out that there seems to be no good tutorial to correctly set a MITM proxy for malware analysis.

There are multiple tutorials showing how to set up a malware lab with a fake net and HTTPS interception using both inetsim and burp. You can find them here:

Because of them I won’t be making another tutorial how to set up your lab. You can use tutorials above. If you are curious, I am using a very similar setup with Flare VM on my main Windows 10 box and an intercept router based on Debian with both fakenet and realnet modes (which I will explain later).

Burp port redirection

Before diving into details of setting up the multimode mitm proxy I would like to share a smaller tip, which may be useful if you follow tutorials linked above. They are good tutorials and I also followed them when setting up my lab, but there is one thing that in my opinion you should change in this setup.

If you configure your burp to redirect to localhost as per instructions above, the fakenet connection to inetsim will work correctly however due to burp interpretation of these redirected packets, it will list all of the connections from your infected box as localhost.

Burp listing all connections as localhost in default configuration

The only way you can distinguish between connection targets in this setup is by looking at the host header of each request. Due to the amount of http traffic that Win10 box is generating this may be a tiresome task.

Fortunately a simple trick exists to get around that. If you have your inetsim set up to listen on 0.0.0.0 then you don’t actually have to redirect to localhost. Burp allows you to redirect only ports, just leave the host option empty and burp will redirect only port. As inetsim is listening on every interface it will grab this traffic anyway. Although if you have 2 interfaces up it may not work every time as I will explain in next section. So it is advised to have only 1 interface up in the fakenet mode.

Burp correctly set up to redirect only port
Correct redirection to inetsim

Fakenet and realnet

Second thing that irritated me in this setup was lack of ability to actually simply redirect malware traffic to internet but keeping the ability to peek into https traffic. Sometimes you just want malware to download this second stage payload or want to eavesdrop on communication with C2. Then you want to have an easy switch from fakenet to realnet. This is actually a simple reconfiguration, and it can also be achieved with the same setup we had before, just changing config files for burp and inetsim.

First thing you have to do is of course to connect the linux box to the internet. Just enable second interface on your hypervisor in NAT mode and linux should automatically route all traffic from internal network to internet via hypervisor. If this is not the case, you might want to set up your NAT gateway as default gateway.

Double interface setup

Second step is to modify an inetsim config so it will act only as a DNS server forwarding all traffic to burp. Just grab the old inetsim config, copy it and remove all services from it except for DNS. Save it with a different name and it should be fine.

InetSim acting as DNS only

Third and last step is to modify burp to act as standard MitM proxy, forwarding all requests to the internet. The only thing you have to change is port you forward a request to, routing table will take care of the rest. You may want to save your realnet burp config in a different file.

Burp setup to forward requests to internet

That’s all! You should now be able to redirect traffic from your malware box to internet, keeping the burp mitm proxy in between.

Burp in MitM mode – redirecting traffic to the internet

Now you just have to do a few simple steps on your linux machine to switch from fakenet to realnet and back.

To switch from fakenet to realnet:

  1. Bring NAT interface up
  2. Restart InetSIM with DNS-only config
  3. Load realnet config into Burb

To switch from realnet to fakenet:

  1. Bring NAT interface down
  2. Restart InetSIM with all services simulation config
  3. Load fakenet config into Burp

Done! You can even write a script for this if you have a need, although it is simple enough to just do these 3 things manually.

Enjoy your mitm box!

Extracting IP and port from a meterpreter payload

When attacker has already gained access to our network and he managed to steal some passwords or hashes, he is usually looking to break into something more interesting than HR workstation. This is a time when he uses stolen passwords to gain access to servers crucial for his operations.

If you see a service installation event (7045) in your System log, with powershell code containing a gzipped payload, this is most likely an evidence of attacker’s lateral movement.

Evidence of lateral movement

This is how it looks like form attacker’s perspective. Note that despite the 6 hours time difference (different timezone – something to always check for during your investigations), this is the same event.

Attacker exploiting stolen credentials to gain access to a server

Unfortunately the windows event doesn’t tell us straight away who performed the attack. User account that installed a service is the one that got compromised but we don’t know by who. There are multiple ways to associate this event with the attacker. For example you may want to try to correlate with User Logon type 3 from Security log. This will tell you which IP was used to login on compromised credentials, which will be most likely an IP of the attacker.

User logon on compromised credentials. Visible IP of the attacker.

However if you don’t have this information available immediately (let’s say you received only this one event as alert from monitoring) or you just want to confirm it, or you suspect that attacker are using different IPs to login that to perform rest of his actions, you may want to dive into the powershell code.

If you take a closer look this is a gzip compressed payload, so we should decompress it for further investigation. It can be done by powershell of course, CyberChef, Linux command, python and many other tools. After unpacking, code looks like this:

Meterpreter payload after unpacking

Without diving into details it is a powershell code injecting a particular shellcode (the long base64 string) into the memory. However all the artifacts that we are interested in are in the shellcode itself. Therefore we can decode and disassemble it with any x86 disassembler (CyberChef also has this option). After going through code that mostly resolves required WinAPI functions, finally we can see that it pushes two 32-bit values on the stack:

They are related to WinSock API data structure sockaddr (more info here: https://docs.microsoft.com/en-us/windows/desktop/WinSock/sockaddr-2). First value from top is an IP address (be careful bytes are reversed on disassembly!) and the second one is a port and a constant 0002 (AF_INET) which indicates it is a TCP/IP stack. If you decode these values you will get the port and the IP.

There is also an x64 version of this payload, it looks a little different on disassembly because of a different calling convention for x64 architecture:

Note that here the entire structure is moved to the stack (not pushed) as a single QWORD (64-bit value)

I created a CyberChef recipe that allows to extract IP address and port from both 32 and 64-bit versions.

{"op":"Regular expression","args":["User defined","[a-zA-Z0-9=/+]{30,}",true,true,false,false,false,false,"List matches"]},{"op":"From Base64","args":["A-Za-z0-9+/=",true]},{"op":"Gunzip","args":[]},{"op":"Regular expression","args":["User defined","[a-zA-Z0-9=/+]{30,}",true,true,false,false,false,false,"List matches"]},{"op":"From Base64","args":["A-Za-z0-9+/=",true]},{"op":"To Hex","args":["None"]},{"op":"Conditional Jump","args":["68([0-9a-f]{8})680200([0-9a-f]{4})",false,"standard",10]},{"op":"Conditional Jump","args":["49bc0200([0-9a-f]{4})([0-9a-f]{8})",false,"reverse",10]},{"op":"Label","args":["standard"]},{"op":"Regular expression","args":["User defined","68([0-9a-f]{8})680200([0-9a-f]{4})",true,true,false,false,false,false,"List capture groups"]},{"op":"Split","args":["\n",":"]},{"op":"Subsection","args":[":([0-9a-f]{4})$",true,true,false]},{"op":"From Base","args":[16]},{"op":"Merge","args":[]},{"op":"Subsection","args":["^([0-9a-f]{8}):",true,true,false]},{"op":"From Hex","args":["Auto"]},{"op":"To Decimal","args":["Space",false]},{"op":"Split","args":[" ","."]},{"op":"Jump","args":["finish",10]},{"op":"Label","args":["reverse"]},{"op":"Regular expression","args":["User defined","49bc0200([0-9a-f]{4})([0-9a-f]{8})",true,true,false,false,false,false,"List capture groups"]},{"op":"Split","args":["\n",":"]},{"op":"Subsection","args":[":([0-9a-f]{8})$",true,true,false]},{"op":"From Hex","args":["Auto"]},{"op":"To Decimal","args":["Space",false]},{"op":"Split","args":[" ","."]},{"op":"Subsection","args":["^([0-9a-f]{4}):",true,true,false]},{"op":"From Base","args":[16]},{"op":"Label","args":["finish"]}]

It can also be found here:
https://github.com/lasq88/CyberChef-Recipes/blob/master/README.md

Unfortunately CyberChef seems to be a little bit bugged lately (regular expressions doesn’t load correctly) and it seems to have some issues with branching so I also created a simple JavaScript tool for the same purpose. You can find it here:

https://github.com/lasq88/IR-Tools/blob/master/meterpreter.html

It is a standalone script so you can launch it in any browser (tested in Chrome though), paste a meterpreter payload, press Extract IP and it should work.

That should be working for most default meterpreter payloads, although I did not test it enough to be sure. Also for any custom lateral movement payloads this will most likely break. 

How I accidentally found a clickjacking “feature” in Facebook

I would’ve never thought that one of my first blog posts will be about looking for bugs in Facebook. I don’t consider myself a bounty hunter, and had never actively looked for bugs. I focus mostly on Incident Response, Forensics and Malware Analysis. To my surprise then I am sharing this particular story with you. It’s about my first bug report, a short spam campaign and a strange Facebook feature.

So, yesterday there was this very annoying SPAM campaign on Facebook, where a lot of my friends published a link to what seemed like a site hosted on AWS bucket. It was some link to a french site with funny comics, who wouldn’t click it right?

One of the SPAM links
Continue reading “How I accidentally found a clickjacking “feature” in Facebook”

Deobfuscating Emotet’s powershell payload

Emotet is a banking trojan, targeting computer users since around 2014. During that time it has changed its structure a lot. Lately we see massive emotet spam campaigns, using multiple phishing methods to bait users to download and launch a malicious payload, usually in the form of a weaponized Word document.

Emotet's chain of infection
Emotet’s chain of infection

First user receives a fake e-mail, trying to persuade him to click on the link, where the weaponized doc is being downloaded. Document is then trying to trick user to enable content and allow macros in order to launch embedded VBA code. VBA is obfuscated. We can also deobfuscate it, but in the end it launches a powershell command. Let’s skip VBA deobuscation today, as I want to focus on powershell. We can obtain powershell command launched by VBA code without deobfuscation, by using any sandbox with powershell auditing. Continue reading “Deobfuscating Emotet’s powershell payload”