Bypassing AV Solution Using Simple Evasion Techniques
byMITM-
0
Authors: Liel Ben Yehuda and Mr Emperor X.
In our opinion, BitDefender Total AV Security is the closest AV today to an EDR/XDR solution in terms of defending capabilities.
This article will show an example of how to bypass an AV solution such as BitDefender and run Sliver C2 shellcode.
Why Sliver?
From https://www.cybereason.com
Silver C2 is gaining popularity due to these reasons:
· Open-source alternative to Cobalt Strike and Metasploit
· Modularity of the platform with Armory
· Cross-platform : OS X, Linux and Windows
The framework provides all core capabilities for adversary simulation and most notables are:
· Dynamic code generation
· Compile-time obfuscation
· Multiplayer-mode
· Staged and Stageless payloads
· Secure C2 over mTLS, WireGuard, HTTP(S), and DNS
· Windows process migration, process injection, user token manipulation, etc.
· Let’s Encrypt integration
· In-memory .NET assembly execution
· COFF/BOF in-memory loader
· TCP and named pipe pivots
· Armory, alias and extension package manager
The technique we used in this article is called “Early Bird”.
This technique abuses Asynchronous Procedure Calls to execute the payload in memory in a stealthier way other than creating a new thread (QueueUserApc API).
What is APC?
Asynchronous Procedure Call or APC is a function to run code in the context of another thread. every thread has its own queue of APCs. If the thread enters an alertable state it starts to do APC jobs in the form of first in first out (FIFO). A thread can enters an alertable state by using SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, or WaitForSingleObjectEx functions.
It’s important to note that only threads that are in “alertable state” can be executed by QueueUserApc.
Early Bird creates our own process in a “SUSPENDED STATE”, queues an APC to the main thread, and resumes the thread afterward, so it can run the malicious code before the AV/EDR has a chance to place its hook.
We also used PPID Spoofing technique to hide our newly created process.
In addition to the techniques above we used Indirect System calls to avoid BitDefender hooking capabilities and to execute our payload without being detected.
Steps:
1. The first step will be to generate a sliver payload.
Creating the Sliver C2 payload:
Sliver C2 Payload
To avoid the static detection we used an encryption algorithm and decrypted the payload at runtime.
It is possible to use XOR, RC4, or any other encryption algorithms but in this article, we decided to use AES.
Encrypting the shellcode with AES using HellShell.exe tool
The Encrypted shellcode (output from HellShell.exe)
Encrypted ShellCode
AesCipherText[] — The encrypted shellcode.
AesKey[] — The AES encryption key.
AesIv[] — Initialization Vector, to ensure that the same plaintext doesn’t encrypt to the same ciphertext when using the same key.
Decrypting The Payload at Runtime:
The simpeDecryption function will decrypt the shellcode at runtime and save the decrypted payload into the “payload” variable.
2. The second step is to generate Indirect Syscalls, in this article we chose to use Syswhisper3.
The Windows APIs we are using for this type of injection are NtAllocateVirtualMemory, NtProtectVirtualMemory, NtWriteVirtualMemory, and NtQueueApcThread.
Indirect Syscalls — The technique aims to replace the original syscall instruction with a jump instruction pointing to a memory address of NTDLL where it stores the syscall instruction.
SysWhispers3 is a tool designed to generate header/ASM pairs for any system call in the core kernel image (ntoskrnl.exe), which can then be integrated and called directly from C/C++ code, evading user-lands hooks
Generating Indirect Syscalls with syswhisper3 command:
syswhispers.py will automatically create the necessary files to use the Indirect Syscalls APIs.
Indirect Syscalls asm file:
What is an ASM file?
An ASM file is a program written in the low level programming language known as assembly language. It is primarily used for writing hardware related code such as for programming micro-controllers. program is written using simple assembly language syntax that includes operators and operands to carry out different operations. ASM files are written and edited in text editors and are executed using an assembler program such as HLA, MASM, FASM, NASM, or GAS.
3. The third step is creating a process in a “SUSPENDED STATE” and injecting our payload into that process.
So, before the thread starts to execute the main code it calls the NtTestAlert function to empty the APC queue of the current thread and run the queued jobs.
We also used “EXTENDED_STARTUP_INFO_PRESENT” to use PPID Spoofing.
Modern EDR solutions track process parent-child relationships to determine if suspicious activity is taking place. For instance, Microsoft Word launching cmd.exe would likely trigger an alarm.
When calling CreateProcess, it’s possible to set the attribute PROC_THREAD_ATTRIBUTE_PARENT_PROCESS to define the parent process.
Creating process in SUSPENDED STATE with PPID Spoofing.
CREATE_SUSPENDED Flag is required to start the process in a “SUSPENDED STATE”
4. The fourth step is to inject our payload into our newly created process using a simple injection technique but without creating a new thread.
Injecting the payload into our newly created process:
Basic process injection with indirect syscalls
NtAllocateVirtualMemory — Allocate virtual memory within the remote process.
NtWriteVirtualMemory — The shellcode (pShellcode) is then written to the allocated memory in the remote process.
NtProtectVirtualMemory — The memory protection is changed to PAGE_EXECUTE_READWRITE. This change in protection allows the shellcode to be executed in the remote process.
5. The fifth step is executing the payload using Asynchronous Procedure Call.
We will call the NtQueueApcThread and set our payload address in memory as an argument.
Because the process is in “SUSPENDED STATE” once we will resume the process using “ResumeThread” API the Asynchronous Procedure Call will execute our payload.
Abusing Asynchronous Procedure Calls to execute the payload.