Since Veil’s 1.0 release, shellcode has been injected into memory the same way (largely across the industry). This is done over the following steps:
- Allocate memory with RWX (read, write, and execute) permissions to write shellcode into, and execute it
- Write the shellcode to the previously allocated memory
- Create a thread to execute the shellcode
- Wait for the shellcode to finish running (i.e. you exit Meterpreter or Beacon) before allowing the stager to exit
However, RWX isn’t entirely “normal” and could potentially be seen as malicious by antivirus/sandbox engines. After talking with Casey (@subtee) about this, I decided to change how Veil injects shellcode into memory. As of Veil’s 3.1 release, almost none of Veil’s “shellcode_inject” stagers will make use of RWX memory.
Veil 3.1 will now allocate memory with RW permissions, to enable the stager to write shellcode into the allocated memory. After writing the shellcode to the allocated memory, the stager will call VirtualProtect to change the memory permissions from RW to RX. At this point, the stager will continue on to call CreateThread and WaitForSingleObject as normal. Sample code of this can be seen below:
Line 3 has changed from Veil 3.0 to 3.1. The final parameter passed into the VirtualAlloc call is 0x04 vs. 0x40 which specifically sets the memory to be ReadWrite. In line 5, the stager calls VirtualProtect, which changes the allocated memory to ReadExecute.
While this tweak is completely under the hood and will likely be transparent to you for nearly all use cases, hopefully small tweaks like this can help either now, or in the future.
Don’t hesitate to reach out to provide feedback!