In my recent webcast for SANS Levelup (http://sans.org/u/ZAX) I suggest that all of you out there who want to become security professionals or want to improve their skills join forces to build DFIR labs (Hackmes) together.
The idea was, that you find like-minded people using the hashtag #leveluplabs on twitter. In the last weeks I had many people ask me how I’d set up something like that. In this and the next few episodes I’ll show how I set up my training lab.
The upcoming tutorials not only show how to set up a small fake company network but also how to set up a basic attacker infrastructure. The fake company network will consist of a domain controller and a few clients joined to the domain and maybe later a web server to increase the attack surface a bit. On the attacker site, I’ll use something like Metasploit, powershell empire or covenant. If you are lucky, you can team up with a penetration tester if you are a DFIR person or the other way round.
There will be at least 7 video tutorials to address the following topics. Today I’ll release the introduction part. Next week I’ll continue with building the fake company infrastructure.
Many security products monitor process trees very carefully to detect when for instance office applications spawn Powershell, cmd or other suspicious subprocesses. But is that enough?
Still many organisations are unable to deactivate macros in office documents as they are still widely used. Hence they introduce compensating controls to detect malicious macros as soon as they execute. Many security products mainly focus on process trees to detect when macros execute Powershell code or behave strangely in other ways. At first, that looks like a good idea and it actually is. But is it enough. So let’s see what it takes to get around pure process tree monitoring and how to still detect what’s going on.
I’m really bad in writing Powershell code so please bear with me. So my target was to write a simple Powershell backdoor that calls back to an even simpler php based C2 server. The reason I choose php for the C2 is, that you could run the C2 on any compromised shared webspace and don’t need to set up a full server.
So essentially every victim gets a unique id. As soon as the malware is running, it asks the C2 server for new commands every 4 seconds. If the command is anything other than “wait” it executes the command in cmd.exe. The results will then be transferred to the C2 server. Note that I used GET as method and transferred the results in a get parameter. I did to test a network based detection mechanism I’m working on. In a real attack I’d use POST requests as usually the full URI including GET parameters ends up in proxy logs while POST parameters in the body don’t.
Ok that part was easy. Now I needed a crappy backend to control the malware. It’s not beautiful but It get’s the job done.
So at that point it’s all about getting that into a production system that’s set up with all the usual security measures and more. Under the assumption, that you will always be able to get an employee to execute a macro as long as it’s not blocked, I created a fake word document. It looks something like that – you know the drill, right?
There are two things I want to prevent when my code fires:
I don’t want Word to spawn a sub process
I don’t want to load System.Management.Automation.dll with any process other than powershell.exe (Some monitor that as well)
Honouring the points above, I can load a WScript.Shell object but I can’t use it’s .Run or .Exec methods as that would spawn a cmd.exe process as child of the Word process. So what I did instead was creating a batch script loading my Powershell backdoor. I just placed that script in the startup folder. That will not give me a shell right away, but as soon as the user logs off and on again I’m in. So this is the macro I ended up using.
Today I had the pleasure of dissecting Shadow Hammer for together with our top malware analyst at InfoGuard(@InfoGuardAG) Stefan Rothenbuehler (@creative83).
ShadowHammer is a piece of malware that was distributed in a supply chain attack mimicking ASUS security updates. Once the malicious update explodes on the target system it loads various libraries it uses to determine the mac addresses of the machine. Only if the MAC address matches a set of predefined addresses it will actually load the next stage and infect the machine.
While some of the functionality is already well documented we feel like it would make sense to show how you can get the hashes out of the malware. Stefan and myself also want to make sure to do this writeup in an educational fashion. That might lead to some “overdocumenting” at some points. So skilled malware analysts out there, please bear with us.
Finding the malicious part
This sample as a little bit more complex as it contains benign code as well as the malware code.
When starting the analysis using static methods like Ghidra, the functionality of ShadowHammer is not immediately observable as it only executes once the benign part of the software update finished executing. The malware author placed the entry point of the malware just before the Process exit into the __crtExitProcess function. We tagged the function accordingly in win32dbg.
So how do we get there. Using the Symbols tab in win32dbg, we see that the file uses the VirtualAlloc and VirtualProtect function from kernel32.dll. Whenever we find those functions used by a binary we want to look at them more closely. Stefan pointed out a nice way to set a useful breakpoint at the end of the function. This way the eax register shows the target address of the memory allocation. When found jump into the code for Virtual Alloc and set a breakpoint right before the function returns. There are more of those but number 2 is the one you want to look at (just to save you some time).
If you start single stepping through the code from there entering all functions that are not API functions you will eventually end up at a place where you see two calls to GetAdaptersAddresses. The first of the two compares the eax register to 0x6f which is 111 in decimal. This return code would indicate a bufffer overflow. We believe that this fires, if the number of interfaces the machine maps is too high to fit the provided buffer.
The second call is followed by test eax, eax which is true when eaxis 0x0. This is the desired return coda as it indicates that we now got our interface structures successfully loaded into the buffer.
After that we are in a loop that creates the md5 sum of every interfaces mac address and stores it to the memory using memcpy. In my case when I dump the source for the memcpy operation the first 16 bytes should the md5 sum of one of my adapters.
The bytes I get are:
93 16 DF 71 02 90 78 CB 6E 33 9C BE 12 0B 1F 49
The mac address for my only adapter is:
Checking that using Cyberchef proves that we got the right data there.
So now that we see that the malware stores the md5 of our mac addresses, the question is, what does it compare it to?
To figure that we need to keep on stepping. I put a breakpoint shortly before my current function returns. and single-step from there. Eventually you will find a set of memcmp instructions in several loops. they compare the memory space filled with your adapter’s macs to the macs the attacker is looking for. It will compare 0x10 or 16 dec bytes in two memory locations. That’s the size of an md5 sum.
So argument one and two are eax and esi. They are on top of the stack so we can easily load them into the data dump window. esi contains our values and eax the value hardcoded in the malware.