Я исправляю инструмент, который работает по сетевому протоколу NTLM, у меня есть объект структуры, где я индексирую строку и передаю функции, внутри области действия переменной переменная изменяется от <type 'str'>
до <type 'instance'>
.
вызов функции:
# type(self.challengeMessage['challenge']) == <type 'str'>
self.ParseHTTPHash(self.challengeMessage['challenge'])
внутри функции:
def ParseHTTPHash(challenge):
# type(challenge) == <type 'instance'>
challenge.encode("hex") # causes exception due to being instance type and not string
объект challengeMessage:
class NTLMAuthChallenge(Structure):
structure = (
('','"NTLMSSP\x00'),
('message_type','<L=2'),
('domain_len','<H-domain_name'),
('domain_max_len','<H-domain_name'),
('domain_offset','<L=40'),
('flags','<L=0'),
('challenge','8s'),
('reserved','8s=""'),
('TargetInfoFields_len','<H-TargetInfoFields'),
('TargetInfoFields_max_len','<H-TargetInfoFields'),
('TargetInfoFields_offset','<L'),
('VersionLen','_-Version','self.checkVersion(self["flags"])'),
('Version',':'),
('domain_name',':'),
('TargetInfoFields',':'))
@staticmethod
def checkVersion(flags):
if flags is not None:
if flags & NTLMSSP_NEGOTIATE_VERSION == 0:
return 0
return 8
def getData(self):
if self['TargetInfoFields'] is not None and type(self['TargetInfoFields']) is not bytes:
raw_av_fields = self['TargetInfoFields'].getData()
self['TargetInfoFields'] = raw_av_fields
return Structure.getData(self)
def fromString(self,data):
Structure.fromString(self,data)
self['domain_name'] = data[self['domain_offset']:][:self['domain_len']]
self['TargetInfoFields'] = data[self['TargetInfoFields_offset']:][:self['TargetInfoFields_len']]
return self
странная вещь, если я передаю self
в ParseHTTPHasH(self)
и ссылку на него внутри функции self.challengeMessage['challenge']
, она не меняет тип на экземпляр. Что здесь происходит?
(Edit:)
Приносит извинения за неопределенность исходного сообщения, его трудно показать контекст с этим большим файлом
Общий контекст макета:
class HTTPRelayServer(Thread):
...
# Parse NTLMv1/v2 hash with challengeMessage & token * custom *
# check out responder ParseSMBHash to implement for smbrelayserver.py
# replace impacket/impacket/examples/ntlmrelayx/servers/httprelayserver.py
def ParseHTTPHash(self,client,data):
LMhashLen = struct.unpack('<H',data[12:14])[0]
LMhashOffset = struct.unpack('<H',data[16:18])[0]
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[20:22])[0]
NthashOffset = struct.unpack('<H',data[24:26])[0]
NTHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
UserLen = struct.unpack('<H',data[36:38])[0]
UserOffset = struct.unpack('<H',data[40:42])[0]
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
# parameter reference
*---------> NumChal = self.challengeMessage['challenge'].encode("hex")
if NthashLen == 24:
HostNameLen = struct.unpack('<H',data[46:48])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHash, NTHash, NumChal)
if NthashLen > 24:
NthashLen = 64
DomainLen = struct.unpack('<H',data[28:30])[0]
DomainOffset = struct.unpack('<H',data[32:34])[0]
Domain = data[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
HostNameLen = struct.unpack('<H',data[44:46])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, NumChal, NTHash[:32], NTHash[32:])
return WriteHash
def do_PROPFIND(self):
proxy = False
if (".jpg" in self.path) or (".JPG" in self.path):
content = """<?xml version="1.0"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>http://webdavrelay/file/image.JPG/</D:href><D:propstat><D:prop><D:creationdate>2016-11-12T22:00:22Z</D:creationdate><D:displayname>image.JPG</D:displayname><D:getcontentlength>4456</D:getcontentlength><D:getcontenttype>image/jpeg</D:getcontenttype><D:getetag>4ebabfcee4364434dacb043986abfffe</D:getetag><D:getlastmodified>Mon, 20 Mar 2017 00:00:22 GMT</D:getlastmodified><D:resourcetype></D:resourcetype><D:supportedlock></D:supportedlock><D:ishidden>0</D:ishidden></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>"""
else:
content = """<?xml version="1.0"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>http://webdavrelay/file/</D:href><D:propstat><D:prop><D:creationdate>2016-11-12T22:00:22Z</D:creationdate><D:displayname>a</D:displayname><D:getcontentlength></D:getcontentlength><D:getcontenttype></D:getcontenttype><D:getetag></D:getetag><D:getlastmodified>Mon, 20 Mar 2017 00:00:22 GMT</D:getlastmodified><D:resourcetype><D:collection></D:collection></D:resourcetype><D:supportedlock></D:supportedlock><D:ishidden>0</D:ishidden></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>"""
messageType = 0
if self.headers.getheader('Authorization') is None:
self.do_AUTHHEAD(message='NTLM')
pass
else:
typeX = self.headers.getheader('Authorization')
try:
_, blob = typeX.split('NTLM')
token = base64.b64decode(blob.strip())
except:
self.do_AUTHHEAD()
messageType = struct.unpack('<L', token[len('NTLMSSP\x00'):len('NTLMSSP\x00') + 4])[0]
if messageType == 1:
if not self.do_ntlm_negotiate(token, proxy=proxy):
LOG.info("do negotiate failed, sending redirect")
self.do_REDIRECT()
elif messageType == 3:
authenticateMessage = ntlm.NTLMAuthChallengeResponse()
authenticateMessage.fromString(token)
if authenticateMessage['flags'] & ntlm.NTLMSSP_NEGOTIATE_UNICODE:
LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('utf-16le'),
authenticateMessage['user_name'].decode('utf-16le')))
else:
LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('ascii'),
authenticateMessage['user_name'].decode('ascii')))
self.do_ntlm_auth(token, authenticateMessage)
self.do_attack()
# Function call
*------------> print(self.ParseHTTPHash(self,str(token)))
self.send_response(207, "Multi-Status")
self.send_header('Content-Type', 'application/xml')
self.send_header('Content-Length', str(len(content)))
self.end_headers()
self.wfile.write(content)
return
...