Sunday, July 28, 2013

Windows RT ARMv7-based Shellcode Development

Recently, I've taken an interest in gaining code execution on my Surface RT tablet. I have found Windows RT to be rather enticing since Microsoft has made a concerted effort to prevent the execution of unsigned code. A couple weeks ago I discovered a way to gain arbitrary shellcode execution via PowerShell. I will have a separate blog post on that topic once I get a thumbs up from Microsoft. And for the record, I am aware of the awesome public Windows RT jailbreak.

Anyway, seeing as I'm already fairly comfortable writing x86 and x86_64 shellcode, I wanted to take on the challenge of writing ARMv7-based shellcode for Windows since no one else seems to be doing it publicly. Knowing that writing shellcode from scratch would have been rather painful and prone to error, I decided to write my payload in C and then modify the resulting assembly listing slightly in order to achieve a position independent payload. Here is the result (noting that this is merely a working proof-of-concept):


You may have noticed that this shellcode is written in MASM format, therefore, it can only be assembled using armasm.exe (the ARM equivalent of ml.exe). Unfortunately, armasm doesn't provide the option of outputting to a raw bin file. It will only emit an object (.obj) file. I wrote Get-ObjDump with the intent of pulling out raw payload bytes in mind but armasm doesn't apply relocations. This means that any calls to functions present in the payload won't be fixed up and it will crash upon executing.

So rather than writing my own linker, the natural choice was to leverage Microsoft's linker, link.exe. In theory, all I would need to do is call `link bindshell.obj` and pull out the raw bytes from the '.foo' section of the resulting binary. However, I ran into a couple issues in practice:

1. link.exe requires that you specify an entry point.

Solution: Easy. Provide the '/ENTRY:"main"' switch

2. Depending on the subsystem you choose, link.exe requires certain functions in the CRT to be present. For example, the following subsystems require the following entry point functions:

/SUBSYSTEM:CONSOLE - mainCRTStartup
/DLL - _DllMainCRTStartup
/SUBSYSTEM:WINDOWS - WinMainCRTStartup
/SUBSYSTEM:NATIVE - NtProcessStartup

Solution: Obviously, I don't care about the C runtime library in my shellcode. The solution I came up with was to specify EFI_APPLICATION as the subsystem since it doesn't require the CRT. In the end, I don't care about the type of PE file I output. I just need the linker to fix up relocations for me. I can take care of pulling out the bytes from the .foo section of the resulting executable. Fortunately, Get-PEHeader can rip raw bytes from a PE file.
 
Wrapping things up, here is the process of obtaining fully-functioning ARM-based Windows RT shellcode from end to end:

Saturday, June 22, 2013

Undocumented NtQuerySystemInformation Structures (Updated for Windows 8)

Those familiar with Windows internals are likely to have used the NtQuerySystemInformation function in ntdll. This function is extremely valuable for getting system information that would otherwise not be made available via the Win32 API. The MSDN documentation only documents a minimal subset of the structures returned by this powerful function, however. To date, one of the best references for the undocumented features of this function has been the “Windows NT/2000 Native API Reference.” Despite being published in 2000, many of the structures documented in this book are still relevant today. In recent history though, Microsoft has quietly expanded the number of functions returned by NtQuerySystemInformation. Thankfully, the vast majority of them have been made public via symbols present in uxtheme.dll (64-bit structures) and combase.dll (32-bit) structures in Windows 8. At last check, it appears as though Microsoft pulled these symbols from the latest versions of the respective dlls.
 
I did my best to document these structures and fill in as many holes as possible in the SystemInformationClass enum. What resulted is the following image – a mapping of SystemInformationClass constants to their respective 32-bit structure and a header file – NtQuerySystemInformation.h. I validated that the header file is properly parsed by IDA (Ctrl+F9). To view the result of what was parsed in IDA, press Shift+F1 (Local Types Subview). The most notable structures are the ones that return pointers. In many cases, these are pointers to kernel memory. >D