I recently worked through Sektor7’s “Red Team Operator - Malware Development”.
The course is excellent because the author will supply you with all the templates you need to get started, and show you how to combine them for various tasks. He also provides a VM with all of the tools installed, and for each template there is a compiler .bat file to show you any compiler specific flags for each job. It’s really good value.
These notes are mainly for me; but it might give you an idea of what you’re in for if you do the course. (Maybe worth noting: you can do the course in an afternoon if you can carve out an uninterrupted block. The course wont make you an immediate expert, that’s impossible in 4 hours, but it gives you the building blocks; it’s not high level stuff - he’ll show you how to get things done and you can choose where to spend more time).
PE Format
The sections we’ll be most interested in are:
.text
.data
.resources
“PEBear” is the tool we used to inspect them, but dumpbin from visual studio can do the job.
Dll’s aren’t designed to create thier own process, instead the loader call’s dllmain to make the exportable functions available to the process. As a red team malware developer you’ll be most interested in making sure you’ve buttoned up a dllmain and have an exportable module in your dll.
That said, you can run dlls with rundll32 mydllname.dll,MyDllFunctionName
and rundll will be the hosting process.
Also worth noting, we can dump the exportable functions from a dll with: dumpbin /exports MyDll.dll
Payloads and Storage
Using .text section
- Create a new memory buffer
- Copy the code to the buffer
- Execute
- We use local variable; will be on the stack
- (use the template but..) keep in mind that if you mark the pages executable right away most AV will pick it up (for being writable and executable). Mark them writable, copy the code, mark them executable.
Using .data section
- Similar to .text approach but global variable; not on the stack
Using .rsrc section
- Slightly more complicated.
- We produce a binary payload (msfvenom is the simple example)
- We name it as a resource for the new binary, like favicon.ico
- We import the payload in the dropper code; the template shows the right approach
Encoding and Encryption
Most of the simple approaches where we just stash a payload in a binary or dropper will be picked up by AV and analysts pretty quickly. We probably should encode at the very least, but really encrypt.
You can set up your encoded payload with built in tools like certutil.exe. You’d do:
certutil -encode calc.bin calc.b64
The templates for the course has decoding functions built in if you do go the lazy encode route.
You should encrypt, even if it is XOR. The course provides a good xorencrypt.py
converter for the payload, and then decrypt functions in the template. There is also AESDecrypt options to step up your game.
Call Obfuscation
getmodulehandle();
getprocaddress();
More information:
The functions used by a process are most often available in the import address table. AV can look and see that the usual suspects for malware are in the table and flag based on that. The idea of the getmodulehandle and getprocaddress approach is that we dont have them mapped at the start, they are not in the import address table. The challenge though, is that the function names are still in the code and would still show up with strings.exe or similar tools - so AV has no trouble picking them out either. For that, we use the XOR approach to obfuscate the names in code. (Use the templates).
Backdooring PE
This was pretty much the same approach as shown in the OSCE but it was great to see it working in a couple of practical examples. Same options: Code Cave, New Section or Extended Section. Then remember:
- JMP -> to cave
- PUSHAD -> to save registers on the stack
- PUSHFD -> to save flags on stack
- {code, possibly decryption first}
- POPFD -> restore flags
- POPAD -> restore registers
- {overwritten instructions from the JMP}
- JMP -> to next instruction back at the start.
Code Injection
Getting our code into a different process. Few reasons, often to find a more stable process, or one the user wont close; sometimes just to get our second connection.
Traditional approach (overview) is:
- Create memory for the code somewhere the target process has access
- Copy the code over
- Start a thread
Common API’s:
VirtualAllocEx();
WriteProcessMemory();
CreateRemoteThread();
References:
The .dll injection approach is a little different:
- Key difference is that the memory buffer in the destination is to hold a path to the .dll, rather than the code. Then we use LoadLibrary() and CreateRemoteThread(). We do it like CreateRemoteThread(LoadLibrary(PATHBUFFER)). It’s in the templates.
Invisible Shellcode
Often folk make the mistake of leaving the shellcode dropper as a console app because it is easy. The challenge is that users will probably see a quick black screen flash when it executes which might spook them, especially if there was some interaction. If you instead use a GUI type (without drawing the GUI) you’ll have a little more stealth. Changes:
- main() becomes winmain()
- remove all printf() from any templates
- compile as GUI using /SUBSYSTEM:Windows
Bypassing Defender
Defender is going to be cross about this combo:
- VirtualAllocEx()
- WriteProcessMemory()
- CreateRemoteThread()
You need to go back and do the function call obfuscation (XOR is fine). The course does a good job of demonstrating putting it all together, and the templates provide the best foundation. It’s not as awful as it sounds; it might be if you didn’t have the leg up that the course provides.