117 lines
4.2 KiB
PowerShell
117 lines
4.2 KiB
PowerShell
function Get-FunctionHash
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Outputs a module and function hash that can be passed to the
|
|
GetProcAddressWithHash function.
|
|
PowerSploit Function: Get-FunctionHash
|
|
Author: Matthew Graeber (@mattifestation)
|
|
License: BSD 3-Clause
|
|
Required Dependencies: None
|
|
Optional Dependencies: None
|
|
.DESCRIPTION
|
|
Get-FunctionHash calculates a hash that can be passed to
|
|
GetProcAddressWithHash - a C function that is used to resolve Win32
|
|
library functions. Passing a hash to a function address resolver
|
|
prevents plaintext strings from being sent in the clear in shellcode.
|
|
A python implementation of this algorithm is present in Meatsploit
|
|
will perform hash collision detection.
|
|
.PARAMETER Module
|
|
Specifies the module to be hashed. Be sure to include the file extension.
|
|
The module name will be normalized to upper case.
|
|
.PARAMETER Function
|
|
Specifies the function to be hashed. The function name is case-sensitive.
|
|
.PARAMETER RorValue
|
|
Specifies the value by which the hashing algorithm rotates right. The
|
|
range of possibles values is 1-31.
|
|
.EXAMPLE
|
|
Get-FunctionHash kernel32.dll LoadLibraryA
|
|
.OUTPUTS
|
|
System.String
|
|
Outputs a hexadecimal representation of the function hash.
|
|
.LINK
|
|
http://www.exploit-monday.com/
|
|
https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/hash.py
|
|
#>
|
|
|
|
[CmdletBinding()] Param (
|
|
[Parameter(Position = 0, Mandatory = $True)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[String]
|
|
$Module,
|
|
|
|
[Parameter(Position = 1, Mandatory = $True)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[String]
|
|
$Function,
|
|
|
|
[Parameter(Position = 2)]
|
|
[ValidateRange(1, 31)]
|
|
[String]
|
|
$RorValue = 13
|
|
)
|
|
|
|
$MethodInfo = New-Object Reflection.Emit.DynamicMethod('Ror', [UInt32], @([UInt32], [UInt32]))
|
|
$ILGen = $MethodInfo.GetILGenerator(8)
|
|
|
|
# C# equivalent of: return x >> n | x << 32 - n;
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 31)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::And)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Shr_Un)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 32)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldarg_1)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Sub)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ldc_I4_S, 31)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::And)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Shl)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Or)
|
|
$ILGen.Emit([Reflection.Emit.OpCodes]::Ret)
|
|
|
|
$Delegate = [Func``3[UInt32, UInt32, UInt32]]
|
|
|
|
$Ror = $MethodInfo.CreateDelegate($Delegate)
|
|
|
|
$MethodInfo = New-Object Reflection.Emit.DynamicMethod('Add', [UInt32], @([UInt32], [UInt32]))
|
|
$ILGen = $MethodInfo.GetILGenerator(2)
|
|
|
|
# C# equivalent of: return x + y;
|
|
$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)
|
|
|
|
$Add = $MethodInfo.CreateDelegate($Delegate)
|
|
|
|
$UnicodeEncoder = [Text.Encoding]::Unicode
|
|
|
|
$Module = $Module.ToUpper()
|
|
[Byte[]] $ModuleBytes = $UnicodeEncoder.GetBytes($Module) + [Byte[]] @(0, 0)
|
|
$ModuleHash = [UInt32] 0
|
|
|
|
# Iterate over each byte of the unicode module string including nulls
|
|
for ($i = 0; $i -lt $ModuleBytes.Length; $i++)
|
|
{
|
|
$ModuleHash = $Ror.Invoke($ModuleHash, 13)
|
|
$ModuleHash = $Add.Invoke($ModuleHash, $ModuleBytes[$i])
|
|
}
|
|
|
|
$AsciiEncoder = [Text.Encoding]::ASCII
|
|
[Byte[]] $FunctionBytes = $AsciiEncoder.GetBytes($Function) + @([Byte] 0)
|
|
$FunctionHash = [UInt32] 0
|
|
|
|
# Iterate over each byte of the function string including the null terminator
|
|
for ($i = 0; $i -lt $FunctionBytes.Length; $i++)
|
|
{
|
|
$FunctionHash = $Ror.Invoke($FunctionHash, $RorValue)
|
|
$FunctionHash = $Add.Invoke($FunctionHash, $FunctionBytes[$i])
|
|
}
|
|
|
|
# Add the function hash to the module hash
|
|
$FinalHash = $Add.Invoke($ModuleHash, $FunctionHash)
|
|
|
|
# Write out the hexadecimal representation of the hash
|
|
Write-Output "0x$($FinalHash.ToString('X8'))"
|
|
} |