Waiting for the C2 to Show Up
Last Updated: 2021-08-20 06:42:46 UTC
by Xavier Mertens (Version: 1)
Keep this in mind: "Patience is key". Sometimes when you are working on a malware sample, you depend on online resources. I'm working on a classic case: a Powershell script decodes then injects a shellcode into a process. There are plenty of tools that help you to have a good idea of a shellcode behavior (like scdbg):
But scdbg is an emulator and does not execute the shellcode. Anyway, by checking the first instructions of the shellcode, we can be pretty confident that we are facing a downloader. It will grab some content from a malicious host. But what will happen after? Of course, you can try to access manually the host using tools like wget, netcat, curl, ...but what if the payload (and probably it will) is encoded or encrypted?
Using jmp2it, I executed the shellcode into a debugger and found a loop used to connect several times to the host. After unsuccessful attempts, the shellcode will simply give up and exit. From a defense point of view, this is already a good finding: You know that, if the shellcode can't connect, it won't infect the computer. But, in my case, I needed to access this payload to investigate further.
The bad news: the host was unavailable. Maybe the campaign was already over? Or I found the sample too soon and the host will show up in a near future? Or... we can imagine a lot of scenarios.
In a normal context, you can simulate the "Internet" in your malware analysis lab and let the shellcode download the expected content. In this case, you don't know what to offer to the shellcode: a PE file? a DLL? some obfuscated data?
Because patience is key, I decided to take another approach and I patched the shellcode to not exit the loop where it tries to connect to the host. In pseudo-code, we have something like:
counter = 5 while counter > 0: if connect_to_c2() == True: do_more_stuff() exit counter-- exit
If you don't decrement
counter, you will have an infinite loop until the host replies successfully.
That's what I did in the shellcode. The instruction at 0x003F0105 was "
JNE 3F00F3" by an unconditional jump: "
JMP 3F00F3". By doing this, I won't exit the loop after the unsuccessful attempts and wait forever for the C2. Then I set up a breakpoint to stop in case of a successful connection.
Of course, I won't stay forever in front of my screen waiting for the magic to happen. In parallel to this, I set up my network monitoring tool to alert me when the host becomes available and a full packet capture is in place.
I'm now waiting for more than 24 hours and still nothing. Unfortunately, I think that the host will never show up but if it works, I'll keep you updated!
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant