Monday, April 23, 2012

Architecture Independent Windows Shellcode

What's this? A non PowerShell-related blog post??? Unheard of! Today's post is more of a novelty but perhaps someone might benefit from it.

There may be times when you’d like to execute shellcode but don’t know the architecture of the processor that you’ll be running on. I’ve seen at least two techniques to solve this problem [1] [2]. Well, here’s yet another technique that is specific to Windows. The following shellcode will detect whether it’s running in pure 32-bit, pure 64-bit, or Wow64 mode:
On 64-bit processors in Windows, the GS segment register stores the pointer to the PEB (Process Environment Block) in GS:[0x60]. In Wow64 mode this is a DWORD value. In 32-bit mode, the GS segment register is not used and uses FS:[0x30] to point to the PEB.

1. Berend-Jan "SkyLined" Wever, w32-exec-calc-shellcode, http://code.google.com/p/w32-exec-calc-shellcode/

2. “isX64 Gem”, July 31, 2011, http://www.ragestorm.net/blogs/?p=376

Sunday, April 22, 2012

64-bit Process Replacement in Powershell

Download here: Replace-x64-Process.ps1

For those of you who follow me on Twitter, you may have noticed that I posted a few teasers related to replacing processes in Powershell. Without further ado, I am releasing Replace-x64-Process. This tool is intended solely as a proof-of-concept tool. I say that because I make absolutely no guarantees that it will work in all cases. In fact, it won't work in many cases.

The intent of this tool is to circumvent application whitelisting products. Assuming Powershell is whitelisted, you can use this tool to load a blacklisted executable within a whitelisted process. I have not tested this tool on any whitelisting products, however so I cannot attest to its level of effectiveness.

Replace-x64-Process makes use of some common techniques seen in malware to replace a suspended process' executable image. Fortunately, Powershell gives us access to many of the mechanisms required to achieve this goal.

Basic steps required to replace a process in memory:

1) Load the host process in a suspended state.
2) Open a handle to the main thread of the executable
3) Get the context of the suspended thread. In 64-bit the entry point to the process is located in RCX. A pointer to the PEB (Process Environment Block) is located in RDX.
4) Call ZwUnmapViewOfSection to unmap the image of the host process
5) Parse the section headers of the target process
6) Find the image base of the target process
7) Allocate space to contain the image of the target process
8) Map the PE header and each section of the executable to the newly allocated memory.
9) Update the PEB to reflect the new image base address
10) Call SetThreadContext to redirect execution to the target process
11) Resume the process

Here is an example of the script in action:

Replacing Internet Explorer with cmd.exe
Replacing notepad.exe with a 64-bit bind shell
In the last example, it is worth noting that the Microsoft code signature is not invalidated after loading the malicious process. This is due to the fact that code signatures are validated  prior to the main thread loading. This is an unintended but awesome side effect of this process.

Lastly, I have a 32-bit version of this script. It is however even more flaky than the 64-bit version. I suspect it's due to the fact that I don't account for relocations. Because instructions in 64-bit are RIP-relative, relocations are no longer necessary. I may release a more polished script for both 32 and 64-bit in the future once I become more familiar with the loading process.

Replace-x64-Process Help File


Enjoy and try not to get too frustrated when the tool doesn't work for you. Also, if you use the -verbose option, you'll find that much of the code in this script demonstrates the beginnings of a full-fledged PE parser. Perhaps more on that in a future posting... If you have any suggestions on how to increase the reliability of this tool, please leave a comment.