Skip to content

XmlDocumentXxe

gadget

Sets XmlDocument.InnerXml, so the target parses your XML and fetches an external DTD. Variant 1 needs a target app on pre-4.5.2 XML resolver defaults, a machine with the EnableLegacyXmlSettings switch back on, or an app that declares NO target framework moniker at all - an ASP.NET app with no <httpRuntime targetFramework> is legacy even on a fully patched 4.8.1 machine. Variant 2 also sets XmlDocument.XmlResolver, which removes that gate entirely.

Declared metadata, not a runtime result. How to read evidence.

Terminal window
.\ysonet.exe -g XmlDocumentXxe -h

Target declarations

VariantFormattersInputsRequirementsRuntime tokens
1Xaml, JavaScriptSerializer, FastJson, YamlDotNet, SharpSerializerXml, SharpSerializerBinary, MessagePackTypeless, MessagePackTypelessLz4remote-urlbuilt-in, net-frameworknet-fx-4.0, net-fx-4.5, net-fx-4.5.1
2Xaml, JavaScriptSerializer, SharpSerializerXml, SharpSerializerBinary, MessagePackTypeless, MessagePackTypelessLz4remote-urlbuilt-in, net-frameworknet-fx-4.0, net-fx-4.5, net-fx-4.5.1, net-fx-4.5.2, net-fx-4.6, net-fx-4.6.1, net-fx-4.6.2, net-fx-4.7, net-fx-4.7.1, net-fx-4.7.2, net-fx-4.8, net-fx-4.8.1
Variants
  • 1: Rely on the target's legacy XML defaults: set InnerXml only (pre-4.5.2 apps, default) (default)
  • 2: Bring your own resolver: set XmlResolver to an XmlUrlResolver first, so any version fires
Options (2)
OptionHelpDefaultRequired
var|variant=Which payload to build. Choices: 1 (default) - set InnerXml only. The target's own XmlTextReader default decides whether the DTD is fetched, so this fires against an application built below .NET Framework 4.5.2, or on a machine where the EnableLegacyXmlSettings switch was turned back on. Smallest payload, widest formatter list. 2 - set XmlResolver to a real System.Xml.XmlUrlResolver BEFORE InnerXml. The document then uses YOUR resolver instead of the reader's default, so the 4.5.2 hardening does not apply and any target version fetches. Costs FastJson and YamlDotNet, which cannot fill that member. Both variants make the SAME request; they differ only in whether the target had to be on the old defaults. Variant 2 is the technique Netwrix published for MessagePack Typeless (see docs/references.md). One target-side caveat belongs with it: MessagePack-CSharp before 2.3.75 calls EVERY setter on a type it builds, and XmlNode.Value throws whatever you give it, so the read dies before the parse. That is a limit of the target's library version, not of the payload, and it applies to both variants on those two formatters. Default value: "1". Suggested values: 1, 2.1false
rawinputSkip the URL validation and put -c into the DTD external identifier exactly as typed, with no trimming. Normal mode accepts an absolute http or https URL and refuses whitespace, control characters and the characters " < > \, because the value goes inside a QUOTED DTD external identifier and those would corrupt or escape it. Use this only for research on a resolver that accepts something else; the network effect this gadget declares was proven with http(s). It does NOT turn off the outer formatter's escaping, so the payload is still a valid document - but nothing checks that the identifier inside it still is, and a broken one simply fetches nothing. Default value: "false".falsefalse

Credit: [Finders: Oleksandr Mirosh, Alvaro Munoz] [Contributors: Soroush Dalili]

All modules · Full catalog JSON