Learning to Pop XSS with Docx Files

I was reading a blog post by n00py about how some different attack vectors of file upload bypass vulnerabilities.  In most cases you would want to simply upload a reverse shell or bind shell to the webserver, but if there are mitigations in place there might be some additional attack methods that we can leverage.  In this blog post, n00py talks about using a Microsoft Word document (docx format) to upload a cross-site scripting (XSS) vulnerability to a webserver.  I found this blog post very interesting, and wanted to see if I could replicate it using the Damn Vulnerable Web Application (DVWA).  

For this demonstration I will be using my Kali training setup defined in a previous blog post.  The first step will make sure that DVWA is up and running on the host.  

Once DVWA is running you can login with the credentials admin:password.  Once you have logged in we will navigate to the Security tab, and make sure the difficulty is set to Low.  We can experiment with higher levels of security at a later time, but for this demonstration we will stick with the lowest form of security.  

As well we will be downloading a sample docx file from the web.  I found a website, as shown in the screenshot below, that will let us download sample Microsoft Word Docx files.  This will be perfect for our demonstration.  Alternatively, if you have access to Microsoft Word you can create your own empty sample file.  

Microsoft Word documents are at the core just a zipped folder with XML and compressed data that Word knows how to unzip and handle.  For our demonstration, we need a portion of the file that will not be compressed.  We can examine all of the ASCII characters in the file by running the Linux command strings file-sample.docx to see what strings are available to us. As you can see from the screenshot below, the ASCII strings for the titles of the individual files are uncompressed.  We might be able to modify one of the filenames in order to sneak in some XSS.  

In order to unzip the docx file we can run unzip file-sample_100kB.docx. Once the docx is unzipped we can simply use the Linux move command, shown below, to inject some arbitrary A's into a filename that will reside in the document.  The A characters serve as a reference point once the file is compressed again.  The file name that I chose was the settings.xml file.  Which resides one folder down in the /word directory.  

$ cd /word
$ mv settings.xml settAAAAAAAAAAAAAAAAAAAAAAAAAAAAings.xml

This will result in the filename being display with a large number of A's in the middle.  Now that the filename is configured we can simply re-zip the document to compress and get back into the normal docx format.  You will see in the commands shown below I like to save the docx as a different filename.  

# cd up to get to the parent directory
$ cd ..
$ zip -r test.docx *

Now we can re-run our strings command to determine if our A's are still visible after compression.  

Success!  Linux will not allow filenames to contain certain characters such as forward slash / .  Therefore, we will need to use a hexeditor or text editor to change the A's into our XSS code.  

In the hexeditor we can find the string of A's by the chunk of hex code with the \x41 or just 41 depending on your hexeditor.  

You can either convert the string <script>alert(1)</script> into hex, and inject the code into the \x41 locations, or you can simply open it in a text editor to replace the strings.  For simplicity sake, I used the unpopular text editor nano.  I know someone will be unhappy with my use of nano, but my limited knowledge of Vi and Vim I was unable to open the document in a hex format.  Now that it is open in Nano I used the ^W command to search for the string AAAAAAAAAAAAAAAAAA.  Note there will be multiple locations for this A string.  I am simply editing the first one I come to, but your mileage may vary.  Once the string is located I deleted a portion of the A's leaving some for padding, and then added our script alert tag.  

Back to DVWA.  We will attempt to bypass the simple security by intercepting the upload process and changing the filename from file-sample.docx to file-sample.docx.html.  It should be noted here you might have some issues with the upload to DVWA.  This is due to the size of the document being too large.  You can simply cut some of the compressed data out.  It will not be relevant to this attack method, however make sure not to cut out your <script>alert(1)</script> tag.  Navigate to the File Upload vulnerability location using the left hand column.  Select your test.docx file, and setup your Burp instance to catch the initial POST request.

As you can see from the screenshot below the POST request has the filename as test.docx.  In order to upload this to DVWA we will need to change the file name to test.docx.html.  Not only will this change the file format when being checked by DVWA, but also will instruct the browser to attempt to render this document when viewed in the browser.

Once you get the success method as shown in the screenshot below.  We can navigate to the directory where the files were upload.  Upon entering we should get the alert immediately pop up.  If for some reason you do not immediately get the popup here are some troubleshooting tips.  There are multiple locations where the settings.xml is located in the document.  Make sure you replace any extra spots with the script tag.  

The final step will be to navigate to the folder where the document is stored.  The screenshot above shows that the document is located at ../../hackable/uploads/test.docx.html.  

Once we forward on that final GET request, and return to our browser we can see that the browser attempted to read the file as HTML.  Even though no proper HTML was used it still read the script tag and executed the JavaScript appropriately.  

I really have enjoyed playing around with the Microsoft Document formats and leveraging different attack methods for obtaining XSS.  I hope you enjoyed this blog post, and good luck testing!