Showing posts with label reflection. Show all posts
Showing posts with label reflection. Show all posts

Monday, March 25, 2013

Parsing Binary File Formats with PowerShell

I'm giving a presentation on "Parsing Binary File Formats with PowerShell" for MiSec on Tuesday, March 26. For those who will not be attending, the slides and code are available for download.



In the presentation, I cover the following:

1) Why you would want to parse binary data
2) Why PowerShell is a powerful tool to accomplish this task
3) A brief overview of data types and how they differ across languages: C/C++, C#, PowerShell
4) Conversion from C data types to PowerShell/.NET data types
5) All concepts taught are applied by parsing the DOS header of a PE file.
6) DOS header overview
7) The three strategies for parsing binary data in PowerShell:
   a) Pure PowerShell-based approach using only PowerShell cmdlets (no .NET)
   b) C# compilation using the Add-Type cmdlet
   c) Reflection
8) Reading in binary data in PowerShell
9) I cover building a DOS header parser using the three strategies
10) Brief overview of reflection and .NET application layout
11) Applications of a DOS header parser
12) Bonus: Intro to the Rich signature
13) Bonus: I extend the DOS header parser to decode and parse the Rich signature

I also provide the following code:

1) Get-DosHeader_Pure_PowerShell.ps1 - A pure PowerShell-based implementation of the DOS header parser
2) Get-DosHeader_CSharp.ps1 - A DOS header parser using Add-Type to compile C# code
3) Get-DosHeader_Reflection.ps1 - A DOS header parser implemented using reflection
4) Get-DosHeader_Reflection_Bonus.ps1 - Same as #3 but extended to include a Rich signature decoder/parser
5) Get-DosHeader.format.ps1xml - A formatting file used to display a proper hexadecimal representation of the parsed DOS header

While the example I use throughout the presentation is a simple one, you would be surprised what information can be gleaned by performing analysis on known good DOS headers in PE files. For example, after scanning 6695 DOS headers, I found that the following fields were always 0: e_crlc, e_cparhdr, e_minalloc, e_ss, e_csum, e_ip, e_cs, e_ovno, e_oemid, e_oeminfo, e_res2. This simple heuristic alone could be used as a signature to detect a malformed DOS header/PE file. TinyPE is the perfect example. Also, a simple DOS header parser can be used to scan for all PE files on disk. What you'll discover is that there are some non-standard PE file extensions that you may not have been familiar with: .lrc, .ax, .rs, .tlb, .acm, .tsp, .efi, .rll, .ime, .old, .dat, .iec, etc.

The techniques that I describe can easily be used to parse any binary format - from a stupid DOS header parser to a PowerShell implementation of binwalk. The sky is the limit.

Enjoy!

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.

Saturday, December 1, 2012

In-Memory Managed Dll Loading With PowerShell

Download: Out-CompressedDll

The .NET framework has a very handy method which loads a managed executable as a byte array – [System.Reflection.Assembly]::Load(byte[] rawAssembly). From the perspective of a malicious script, this is very convenient because it allows for a dll to be self-contained within the script body. What’s not as convenient is the size required to store the raw dll as a byte array in the script. To alleviate the size dilemma, I’ve written a PowerShell script that reads in a managed dll, compresses it, base64-encodes it, and outputs generated code that you can simply paste into any script that requires the dll.
As an example, I’ll compile the following code and run it through the script:
PS C:\> csc /target:library test.cs
Microsoft (R) Visual C# Compiler version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\> Out-CompressedDll .\test.dll | Out-File LoadDll.ps1

I then add the following to the generated script to run the DoStuff method: [Test]::DoStuff()

This results in the following script:
And that's all there is to it!

Note that this technique will only load MSIL-based dlls. It will not load native or  IJW ('it just works' - mixed-mode) dlls.

Saturday, August 11, 2012

Surgical .NET Dissection - Using PowerShell Proxy Functions to Extend Get-Member


Download: 'Get-Member' proxy function

tl:dr version

Using proxy functions in PowerShell, a '-Private' parameter can be added to the Get-Member cmdlet which will expose all non-public .NET members. This feature is ideal for those interested in hacking, researching or tearing apart the .NET framework.



In previous posts, I've mentioned methods to expose private types and members in .NET with PowerShell. Leveraging these techniques creatively require at least a basic knowledge of reflection and .NET internals. These techniques also consume a lot of keystrokes. After reading an excellent introduction to proxy functions, I learned that any existing cmdlet can be added to or subtracted from. This inspired me to extend the Get-Member cmdlet.

Before proceeding in this article, it is recommended that you become familiar with proxy functions.

For those PowerShell users who have been living under a rock, Get-Member is a required cmdlet to be familiar with. It prints all public members (properties, methods, events, etc.) of both instance and static types. For example, the following command will return all the public and static members of the System.Convert class:


The Get-Member cmdlet returns objects of the type System.Management.Automation.PSMemberTypes consisting of the following parameters and types:

      Name - String
  Typename - String
MemberType - System.Management.Automation.PSMemberTypes
Definition - String

What you're not seeing in the output above are all of the non-public members. There is a valid reason for this - there is no way to directly access them and most people don't care to see that which they cannot touch. I, on the other hand enjoy touching one's private members... of .NET objects. ;D So I modified Get-Member to produce the following:


Adding the '-Private' parameter was no trivial matter. First of all, the MemberType field of the Get-Member output is problematic because non-public members use member types from the System.Reflection.MemberTypes class, not System.Management.Automation.PSMemberTypes. What I did to resolve this was convert the output to custom PSObjects with the same properties of the Get-Member output. This was achieved in the following code snippet:


The PSObject.TypeNames.Insert method was used to trick PowerShell into thinking that my custom object was a MemberDefinition object when it got output to the console. This trick is possible because a custom view for Microsoft.PowerShell.Commands.MemberDefinition is defined in PowerShellCore.format.ps1xml.

To install the proxy function, you can do any of the following:

1) Install in your current session:

PS> . .\Get-Member.ps1

2) Persistant install:

* I placed the script in the same folder as my profile.ps1 script and added this line:

. (Join-Path (Split-Path $PROFILE) Get-Member.ps1)

As usual, let me know if you have any questions or bug reports. For all other PowerShell related questions, Get-Help is your friend. Also, the modified Get-Member is fully documented via `help Get-Member -Full -Category function`.

As a final exercise, I encourage everyone to try out the following commands and observe the interesting results:

PS> [AppDomain]::CurrentDomain.GetAssemblies() | % {$_.GetTypes()} | % {$_ | Get-Member -Private -Force}
PS> [AppDomain]::CurrentDomain.GetAssemblies() | % {$_.GetTypes()} | % {$_ | Get-Member -Private -Static -Force}

Saturday, July 28, 2012

Deep Reflection - Defining Structs and Enums in PowerShell

One of the reasons PowerShell is so powerful is in its ability to access to .NET framework. In theory, this should make the transition for C# developers seamless. Unfortunately, PowerShell is not quite a one-to-one translation of C#. I demonstrated where this is not the case in a previous post by illustrating the hoops you need to jump through to declare a delegate type in PowerShell using reflection. Declaring an enum or struct is no different.

Before I jump into the technical details, it's worth addressing the question you may have already formed. Why don't you just compile C# code using the Add-Type cmdlet? Well, that is a perfectly valid method of declaring a struct, enum, delegate, etc. However, compiling C# code leaves artifacts on the disk. To prove my point, just run Procmon while compiling C# in PowerShell. As someone with an attacker's mindset, I prefer that all operations take place in memory unless absolutely necessary. Fortunately, true memory residence can be achieved using reflection.

As an example, here is a portion of the code from my last PowerSploit release - Get-PEHeader:

$code = @"
    using System;
    using System.Runtime.InteropServices;
 
    public class PE
    {
        public enum IMAGE_DOS_SIGNATURE : ushort
        {
            DOS_SIGNATURE =                 0x5A4D,      // MZ
            OS2_SIGNATURE =                 0x454E,      // NE
            OS2_SIGNATURE_LE =              0x454C,      // LE
        }


        [StructLayout(LayoutKind.Sequential, Pack=1)]
        public struct _IMAGE_DOS_HEADER
        {
            public IMAGE_DOS_SIGNATURE   e_magic;        // Magic number
            public ushort   e_cblp;                      // public bytes on last page of file
            public ushort   e_cp;                        // Pages in file
            public ushort   e_crlc;                      // Relocations
            public ushort   e_cparhdr;                   // Size of header in paragraphs
            public ushort   e_minalloc;                  // Minimum extra paragraphs needed
            public ushort   e_maxalloc;                  // Maximum extra paragraphs needed
            public ushort   e_ss;                        // Initial (relative) SS value
            public ushort   e_sp;                        // Initial SP value
            public ushort   e_csum;                      // Checksum
            public ushort   e_ip;                        // Initial IP value
            public ushort   e_cs;                        // Initial (relative) CS value
            public ushort   e_lfarlc;                    // File address of relocation table
            public ushort   e_ovno;                      // Overlay number
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
            public string   e_res;                       // May contain 'Detours!'
            public ushort   e_oemid;                     // OEM identifier (for e_oeminfo)
            public ushort   e_oeminfo;                   // OEM information; e_oemid specific
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=10)]
            public ushort[] e_res2;                      // Reserved public ushorts
            public int      e_lfanew;                    // File address of new exe header
        }
    }
"@


Add-Type -TypeDefinition $code -WarningAction SilentlyContinue | Out-Null

As you can see, the C# 'code' above defines an enum and a struct that are compiled when Add-Type is called. The need to compile the code above can be obviated with reflection. This however requires some understanding of the attributes that define the fields in the enum and struct above. Interrogating these attributes can be accomplished with ildasm or PowerShell. I'll show you how to do this in PowerShell.

First, let's view the attributes of the IMAGE_DOS_SIGNATURE enum:

PS > [PE+IMAGE_DOS_SIGNATURE] | Format-List BaseType, Attributes
BaseType   : System.Enum
Attributes : AutoLayout, AnsiClass, Class, NestedPublic, Sealed

Now, let's view all the relevant individual attributes of the _IMAGE_DOS_HEADER struct:

PS > [PE+_IMAGE_DOS_HEADER] | Format-List BaseType, Attributes
BaseType   : System.ValueType
Attributes : AutoLayout, AnsiClass, Class, NestedPublic, SequentialLayout, Sealed, BeforeFieldInit
PS > [PE+_IMAGE_DOS_HEADER].GetField('e_res').GetCustomAttributes($True) | Format-List Value, TypeId, SizeConst
Value     : ByValTStr
TypeId    : System.Runtime.InteropServices.MarshalAsAttribute
SizeConst : 8
PS > [PE+_IMAGE_DOS_HEADER].GetField('e_res2').GetCustomAttributes($True) | Format-List Value, TypeId, SizeConst
Value     : ByValArray
TypeId    : System.Runtime.InteropServices.MarshalAsAttribute
SizeConst : 10

Now we have everything we need to dynamically generate the enum and struct. The following code demonstrates how to accomplish this and returns the DOS header for calc.exe:


By now, you can see the additional overhead required to dynamically generate code. However, if your goal is to avoid compiling code and remain truly memory resident, this is the way to go. Expect to see an update to Get-PEHeader that will implement these changes in the near future.

Tuesday, June 26, 2012

Get-ILDisassembly - A Scriptable MSIL Disassembler Added to PowerSploit


PowerSploit Repo

I just added Get-ILDisassembly to the PowerSploit project. This tool takes any MethodInfo object and returns the disassembly for that method, assuming it's not a native method or implemented via P/Invoke.

Get-ILDisassembly relies upon the fact that you can dump a raw byte array of a method's IL using the GetILAsByteArray method of the System.Reflection.MethodBody class.

MSIL is surprising easy to disassemble. It consists of either one or two-byte opcodes followed by an operand in many cases. Operands typically consist of one of three options:

1) An immediate value
2) A 32-bit metadata token which is used to describe a member of an object. The metadata token is then resolved with the ResolveMember or ResolveString methods in the System.Reflection.Module class.
3) A location to branch to in conditional logic

Each MSIL opcode is also described in detail in the System.Reflection.Emit.OpCodes class. Unfortunately, there is no direct way to resolve an opcode from a raw byte. In my function, I simply generate a hashtable that links a byte value to its respective MSIL opcode.

Here are some examples of how you could use Get-ILDisassembly:
In the example above, I'm simply dumping the disassembly of the System.Int32.Parse(String) method.
In this example, I disassemble the System.Array.BinarySearch(Array, Object) method.

Lastly, as I hinted upon on Twitter, you could certainly get creative with Get-ILDisassembly. I used it to calculate the frequency of all opcodes in every exported member of every loaded module in PowerShell using the following commands (caution: this takes a long time to run):
The result of this command will resemble the following:



Lastly, I would be a charlatan without mentioning that the disassembly techniques I used came straight out of the book "C# 4.0 in a Nutshell" and was used with generous permission from O'Reilly Media and the authors, Joseph Albahari and Ben Albahari. Enjoy!

Saturday, May 19, 2012

Accessing the Windows API in PowerShell via internal .NET methods and reflection

tl:dr version

It is possible to invoke Windows API function calls via internal .NET native method wrappers in PowerShell without requiring P/Invoke or C# compilation. How is this useful for an attacker? You can call any Windows API function (exported or non-exported) entirely in memory. For those familiar with Metasploit internals, think of this as an analogue to railgun.



This journey started for me upon releasing my PowerShell shellcode execution scripts and noticing that even if I issued C# compiler parameters to compile in memory, csc.exe would still write temporary files to disk. This is unacceptible for any attacker. The venerable Lee Holmes mentioned to me that the only way to achieve true memory-residence in .NET is through the System.Reflection namespace. Reflection is an extremely powerful technique used to generate dynamic code. In .NET, you can achieve fine-tuned control over generated code even to the MSIL bytecode level. Before I get too deep in the weeds, let me tell you a story about rifiling through .NET assemblies.

At one point, I was interested in auditing .NET methods that manipulated data/memory in a possibly unsafe fashion. To find some potential targets in Powershell I enumerated the exported types of every loaded .NET assembly via the following commands:


This search yielded some very interesting methods. The ones that were of the most immediate value to me were those contained within Microsoft.Win32.UnsafeNativeMethods:


Microsoft.Win32.UnsafeNativeMethods is an internal class that cannot be referenced through any direct means. If you try to reference the class, you will get an error stating that its module is not loaded. Microsoft.Win32.UnsafeNativeMethods is implemented within System.dll in the GAC.

Of the methods listed above, GetModuleHandle and GetProcAddress were the most interesting to me since these two methods form the basis for calling any other function in the Windows API. How do you access these methods you ask? I wrote the following PowerShell function to demonstrate:



The function first gets a list of all loaded assemblies in PowerShell. It then gets a reference to System.dll, which contains Microsoft.Win32.UnsafeNativeMethods. I then call the GetMethod method on 'GetModuleHandle' and 'GetProcAddress'. I then invoke GetModuleHandle. Normally, in PowerShell, you would invoke this .NET method like this: 

[Microsoft.Win32.UnsafeNativeMethods]::GetModuleHandle('kernel32.dll')

That syntax would generate an error though because it is not a public class. I then get a reference to the returned handle. This is necessary because the managed version of GetProcAddress requires it. Finally, I call GetProcAddress on the function I'm interested in. As an example, the following command will return the address for VirtualAlloc:

Get-ProcAddress kernel32.dll VirtualAlloc

Now, having the address to VirtualAlloc is great and all, but what can be done with it? Conveniently, the System.Runtime.InteropServices.Marshal class contains a very handy method called GetDelegateForFunctionPointer. For those unfamiliar with delegates, think of them as function pointers. GetDelegateForFunctionPointer takes two parameters: a pointer (what was returned from Get-ProcAddress) and a type (a method signature). In C#, defining a method signature is trivial. You just use the delegate keyword. Therefore if you wanted to create a method signature for VirtualAlloc in C#, you could write something like the following:

IntPtr delegate VirtualAllocSig(IntPtr lpAddress, UInt32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

Unfortunately, PowerShell has no equivalent to the 'delegate' keyword. This is where reflection and a handy article circa 2004 come into play. Using reflection, you can do the equivalent of compiling the C# code snippet above. This process is far from straightforward but can be accomplished via the function below:


So to create the equivalent of the C# code that creates a delegate type, you can issue the following command now:

$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])

Note that if a function passes a parameter by reference, you can still get a proper delegate type by using the MakeByRefType method:

$ByRefDelegate = Get-DelegateType @([String].MakeByRefType()) ([Void])

Coming back full-circle now, we now have everything GetDelegateForFunctionPointer needs to get a 'managed function pointer' to any Windows API function. So lets say you wanted to allocate some RWX memory. This can now be achieved:


Last but not least, it is worth noting that this method will only execute functions that use the StdCall calling convention. Also, if anyone is familiar with Lee Holmes' awesome Invoke-WindowsApi script, you might have noticed that these techniques offer similar functionality to his script. The main difference is that this technique does not use P/Invoke and because you're calling a function from an address, you not just limited to exported functions. You can call non-exported StdCall functions.

Now, you're limited only by your imagination as to what you can achieve in Powershell and all without touching the disk! For example, soon I'll be modifying PowerSyringe to take advantage of these techniques. Also, expect more features to be added to PowerSyringe in the near future...