Sunday, February 17, 2013

Windows File Confusion: Masquerading Unsigned Binaries as Signed Ones


Could it be? A non-PowerShell related blog post?

A while ago, Mark Baggett (@MarkBaggett) tipped me off to a technique that he had seen malware using in the wild. He explained that if you could manage to execute an unsigned binary with the same name as a signed binary (but with trailing white space) that it would take on the code signature of the legitimate binary.

I was obviously intrigued. This posed a bit of a challenge though because Windows automatically strips trailing white space from file names. I eventually figured out how to bypass this slight restriction by echoing the contents of my binary using `type` to a path prefixed with \\?\.

For example, to name the file "evil.exe" to "calc.exe   " (note the three trailing spaces), you would do the following:

type evil.exe > "\\?\C:\Windows\System32\calc.exe   "

Great. We now have an unsigned binary with trailing white space. Now how does one execute it? As is demonstrated by the following screenshot, there is no longer a file association with the binary and Windows doesn't know how to load it.



I asked some friends for ideas on how to execute it and Chris Campbell (@obscuresec) had the genius idea to execute it via its 8.3 file name. Trying to call it directly from cmd.exe with its 8.3 file name unfortunately opened the original, signed calc. However, executing it with the Create method of the Win32_Process WMI class worked like a champ! This was accomplished with the following WMIC command:

wmic process call create C:\Windows\System32\CALC~1.exe

The following screenshot demonstrates the steps necessary to create a binary with trailing white space and consequently execute it:



Upon executing the unsigned file masquerading as the original calc.exe, you notice something amusing - when viewed in Process Explorer, the signed calc.exe is mistaken for the unsigned one and Process Explorer mistakenly reports the unsigned calc as having a valid code signature both in the process and module listings. It doesn't take long to see that something isn't right though. For example: the following differences are evident:

  • The file sizes differ
  • The unsigned binary is a .NET executable. The original calc is not.
  • The unsigned binary is lacking the company name of "Microsoft Corporation". I tried to replicate the company name by modifying the assembly information of my unsigned binary but it caused Process Explorer to no longer say that it was '(Verified) Microsoft Windows'.



Another peculiarity I witnessed was that depending upon how you referenced the file names, the hash of the unsigned binary differed. Its true hash would only be manifested by referring to its 8.3 file name.



All in all, I would consider this technique to be more of a novelty than a serious vulnerability. For example, sigcheck detects the unsigned binary. Also, if code integrity checks are enforced (as Windows RT does), the kernel will prevent the unsigned binary from being executed. The underlying logic flaw is that Microsoft made the assumption that an executable would not have any trailing white space. As a result, the file information of the original executable (with no trailing white space) is processed rather than that of the one with trailing white space.

You can download the binary I used in the screenshots here. All it is is a basic Windows Forms .NET executable with the calc.exe icon and assembly information.

Monday, January 7, 2013

Get-PEB – A Tool to Dump the Process Environment Block (PEB) of Any Process

Download: Get-PEB

Recently, I made the mistake of volunteering to undertake the creation of a process environment block parsing tool in PowerShell. Several painstaking days of work later, Get-PEB was created. Get-PEB is a self-contained script that will retrieve and parse the PEB of an arbitrary process, independent of Windows OS version (well, XP and above) and architecture – i.e. it will retrieve the PEB of 32-bit, 64-bit, and Wow64 processes.

What is the process environment block? It is a structure that is formed during process initialization that contains data pertinent to the execution of a process and is closely associated with the EPROCESS data structure in the kernel. The structure isn’t fully documented by Microsoft but fortunately, the symbols for the PEB and its embedded structures are made available via `dt nt!_PEB` in Windbg. Additionally, there is a wealth of open source documentation.

The process environment block is also heavily used by shellcode to resolve dll function addresses without needing to call GetProcAddress.

Running Get-PEB is pretty simple. You can either give it a process ID via the ‘-Id’ parameter or you can just pipe the output of Get-Process (ps) to it via the pipeline. For example, let’s say I’m interested in retrieving the PEB from a notepad.exe process:
One of the techniques used by shellcode to get the addresses of loaded modules in memory is to walk the InLoadOrderModuleList doubly linked list to obtain the base address of kernel32.dll and ntdll.dll. Ntdll and kernel32 are almost always the second and third entries in this list. I didn’t bother to parse every possible substructure contained within the PEB in Get-PEB but I did make sure to parse the InLoadOrderModuleList, InMemoryOrderModuleList, and InInitializationOrderModuleList linked lists which point to a series of LDR_DATA_TABLE_ENTRY structures.

So, if I wanted to view the InLoadOrderModuleList field in notepad.exe, I simply type the following:
This script was not trivial to produce. I faced a number of challenges during its creation:

Problem: The definition of the PEB structure has evolved over time since Windows XP and I wanted to reflect these changes dynamically based upon the version of Windows running.

Solution: Reflection was suited perfectly for this task since its intended use is the creation of assemblies, modules, and types (structures are a subset of types in .NET) on the fly. I wrote some logic that retrieves the NTDDI representation of the Windows version and built up the structure of the PEB dynamically based upon the well documented difference in ReactOS.

Problem: Parsing memory structure pointed to by memory addresses in the virtual address space of another process proved problematic.

Solution: I developed a helper function - Get-StructFromMemory to address this issue. It is basically calls ReadProcessMemory in kernel32, copies data from the other process into local virtual memory and calls [Runtime.InteropServices.Marshal]::PtrToStructure.

Problem: Making it all look pretty.

Solution: ps1xml files are designed to format the output of objects. The challenge is that since the PEB structure is created dynamically, I have to account for every possible type that it might emit. The included Get-PEB.format.ps1xml accounts for all these possibilities.

I hope you enjoy Get-PEB. As usual, I encourage you to ask questions, report bugs, propose improvements. Hopefully, time permitting, I’ll parse additional substructures in the PEB. The next one on the list for me is the _RTL_USER_PROCESS_PARAMETERS structure pointed to by the ProcessParameters field.