Tuesday, May 12, 2015

Walking the Stack in PowerShell - Part 1

One of the more sophisticated methods of Dynamic Link Library (DLL) injection employs reflective loading to avoid detection. Basically, a chunk of memory is allocated via VirtualAlloc(Ex), a DLL is written to the allocated memory chunk via WriteProcessMemory, and execution begins via Create(Remote)Thread. Since no files are written to disk and the standard LoadLibrary routine isn't used, it's harder to detect this injection technique.

Stephen Fewer's 2008 paper Reflective DLL Injection states:

At a process level the only indicators that the library exists is that their will be a chunk of allocated memory present, via VirtualAlloc, where the loaded library resides. This memory will be marked as readable, writable and executable. Their will also be a thread of execution which will be, periodically at least, executing code from this memory chunk.

Based on that information, there are at least two places to look for reflectively loaded DLLs: process memory and process threads. There are already tools to search the allocated memory of a process for committed pages that aren't referenced by a currently loaded library/module. You could use Sysinternal's Process Explorer to examine currently executing threads, but I'll explain how that might not give conclusive results and doesn't work well when trying to investigate machines over the network. 

Walking the Stack isn't a new concept, so I'll only give it a brief overview here. The majority of my work was inspired by jkalmbach's StackWalker project. However, since I'm a PowerShell nut and interested in remote investigations, I wrote a .NET implementation, PowerWalker. Some of the Structs and Enums in my code were copied from Microsoft's MDbg Sample 4.0.

The basic steps to walking a thread's stack are as follows:

  1. Set the _NT_SYMBOL_PATH environment variable to a functioning symbol server. 
  2. Initialize the symbol loader via SymInitialize.
  3. Determine the machine's processor type via GetSystemInfo. 
  4. Determine the image type of the process via IsWow64Process.
  5. Enumerate the currently loaded modules via EnumProcessModulesEx.
  6. Get the necessary information for each module to load their symbols via SymLoadModuleEx.
  7. Suspend the thread you're going to walk via (Wow64)SuspendThread.
  8. Get the current CONTEXT structure of the thread via (Wow64)GetThreadContext.
  9. Initialize a STACKFRAME64 structure with the offsets from the thread's context.
  10. Pass the Context and Stackframe structures to StackWalk64.
  11. Loop through StackWalk64 until the Return Address equals zero. 
  12. Cleanup allocated resources and call SymCleanup.
  13. Resume the thread.
At each iteration through the StackWalk64 function the instruction pointer and return addresses are updated and we can use those as inputs to GetMappedFile. Any address where GetMappedFile returns null, we know that code was not loaded from a file on disk and can assume that it was loaded reflectively. While there are legitimate reasons for code to be loaded reflectively, this gives us a quick vector to investigate further.

To demonstrate this concept lets look at the stack of a reflectively loaded Meterpreter payload using Process Hacker, Process Explorer, and then finally the simple Cmdlet that I wrote.

Process Hacker

Process Explorer

My simple Cmdlet

More to come...

Tuesday, April 14, 2015


This blog is a carryover from my first attempt, just in case anyone took notice. Much of the subject matter will pertain to computer security efforts from a disruptive defender's point of view; i.e., using attack methodologies as the muse for my attempts to detect and defend.

This first post is an update to the last post on my old blog about using Windows Management Instrumentation (WMI) to create a pseudo remote-shell. My work on this subject is an extrapolation of sorts that started with Andrei Dumitrescu's presentation on the topic:  http://www.lexsi.com/Windows-Management-Instrumentation-Shell.html.

Create-WmiShell was my first attempt, and is basically a direct port of Dumitrescu's python implementation; it is a PowerShell script that uses WMI to upload a Visual Basic (VB) script to a remote machine and then interacts with that VB script to provide the majority of the remote-shell functionality.

WmiSploit is what I'd like to consider a more refined implementation; it is purely PowerShell, doesn't write any files to disk, and can exfiltrate data using only the WMI service. The crux of all of this was Dumitrescu's discovery that a version of Base64 encoded data can be written to WMI namespaces. Within WmiSploit I've also included a script that leverages the Win32_ShadowCopy class to access and retrieve locked files, thanks to a well-placed suggestion by @mattifestation.

Now all of this seems very attacker focused, and it is. Here is where the disruptive defender comes into play. Writing all of this Base64ish data to WMI namespaces does get tracked by the operating system... unfortunate for the attacker, good news for the defender.

It is important to note that WMI listens for connections on port 135, but actually establishes communication between machines on ports 1024-1027. Network monitoring (e.g. snort) rules could easily be written to flag on these ports, base64ish encoded payloads, and other signatures. If network monitoring isn't available, there is a file that can be checked and parsed to completely reconstruct this sort of WMI activity.

The OBJECTS.DATA file located in the C:\Windows\System32\wbem\Repository directory will contain every line of base64 encoded data that was written to the WMI namespaces. That data could be parsed from the OBJECTS.DATA file and reconstructed to identify what transpired during the session. The OBJECTS.DATA file is a system file that can't be easily modified or deleted. I have plans for a backup/restore tool to circumvent this forensic recovery, but that will also leave its own traces.