“Those who rule data will rule the entire world.” - 孫正義
TLDR; Crafting Dataset Publishing Language bundles to get stored XSS in the context of www.google.com, and using the DSPL remote sources functionality to access local services (SSRF).
The Google Public Data Explorer is a tool to make large datasets easy to explore and visualize. eg., Visualizing Health expenditure, World Bank data (% of government expenditure).
Dataset Publishing Language (DSPL) uses XML to describe the dataset metadata and uses CSV data files: eg., sample.zip
The issue here was that Google Public Data Explorer would use some supplied metadata in the dataset archive without context aware encoding or validation.
eg., using a sample dataset:
- curl https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/dspl/tutorial1.0.zip -o sample.zip
- unzip sample.zip; rm sample.zip
- zip -r poc.dspl *
- Upload the dataset to Google Public Data Explorer, and share it publically.
Short video showing how this worked before it was fixed. Allows stored XSS in the context of www.google.com using DSPL:
Dataset Publishing Language also has functionality to allow data to be retrieved from remote HTTP or FTP sources. This functionality allowed SSRF (server-side request forgery) to access localhost service resources (potentially also allows access to internal, non internet accessible systems/devices).
eg., contents of poc.dspl/dataset.xml
Uploading this dataset would return the response of the HTTP/FTP request in the resulting error condition responses. eg.,
In this example it shows the local SSH banner response which is a service that is not publically accessible.
This was fun to look into when I took some time off in January. Thanks to @sirdarckcat and the Google Security team for the great VRP! If anyone reads this and finds stuff that I missed, you should let me know. 😅 @signalchaos
Thanks for reading, 👋
Disclosure timeline stuff:
- Jan 2018: Reported to Google
- Feb 2018: Verified that the reported issues were fixed
- Feb 2018: Rewarded $5,000 for Stored XSS
- Mar 2018: Rewarded $13,337 for SSRF
“Yes, books are dangerous. They should be dangerous - they contain ideas.” - Pete Hautman
On a previous post about ePub parsers (This book reads you - exploiting services and readers that support the ePub book format), I mentioned using scripting capabilities in ePub to perform local attacks against users.
Apple just released a fix for one issue I reported last year in iBooks that allowed access to files on a users system when a book was opened. iBooks on El Capitan would open an ePub using the file:// origin, which would allow an attacker to access the users file system when they opened a book. (CVE-2017-2426)
To help demonstrate how this could be used to perform attacks against users, I added a WebSocket client to a book, so that all users who open the book will connect back to a WebSocket controller server that will feed them arbitrary instructions. The WebSocket client in the ePub will allow access as long as the user has the book open (expectation is that it could be open for a long time, if the user is provided with something worth reading).
eg., Sending a book to a user:
iBooks connects to the WebSocket Controller when opening the book:
iBooks connecting back to a WebSockets Controller. Local files can be retrieved if the reader is vulnerable to CVE-2017-2426 (file:// origin):
Video demo of how this works (trying to type with one hand):
This is the POC book if you want to try it yourself. You can open it in a reader like Apple iBooks or Adobe Digital Editions.
Disclaimer: The POC connects to my controller, but I promise not to do anything bad. 😉
To modify it to point to your own controller:
curl https://s1gnalcha0s.github.io/assets/controller/POC.epub -o poc.epub
unzip poc.epub; rm poc.epub
eg., contents of poc.epub/EPUB/js/main.js
- zip -r poc.epub *
Node.js WebSocket Controller:
- curl https://s1gnalcha0s.github.io/assets/controller/server.js -o server.js
- npm install websocket
- node server.js
Disclosure timeline stuff:
- Dec 2016: Reported to Apple.
- Mar 2017: Fix release, and this post.
Thanks for reading. 👋
“We use the ePub format - it is the most popular open book format in the world. We’re very excited about this.” - Steve Jobs, 2010 (original iPad launch)
TLDR; Applying a familiar XXE pattern to exploit services & readers that consume the ePUB format. Exploiting vulnerabilities in EpubCheck <= 4.0.1 (ePub Validation Java Library & tool), Adobe Digital Editions <= 4.5.2 (book reader), Amazon KDP (Kindle Publishing Online Service), Apple Transporter, and Google Play Book uploads, etc.
ePub is a standard format for open books maintained by IDPF (International Digital Publishing Forum). IDPF is a trade and standards association for the digital publishing industry, set up to establish a standard for ebook publishing. Their membership list: http://idpf.org/membership/members
ePub uses XML metadata to define the document structure, support digital signatures, digital rights (DRM) etc.
eg., epub archive:
eg., contents of META-INF/container.xml
eg., contents of book.opf
When I first started looking into this, I learned about a tool/Java library called EpubCheck (provided by IDPF) that is used to validate books in the ePub format. Book publishers tend to perform a validation step using something like this to check the format validity. The validator tool/library was vulnerable to XXE, so any application that relies on a vulnerable version to check the validity of a book would be susceptible to this type of attack.
Modifying an existing ePub file to test for XML parsing vulnerabilities:
curl https://s3-us-west-2.amazonaws.com/pressbooks-samplefiles/MetamorphosisJacksonTheme/Metamorphosis-jackson.epub -o book.epub
unzip book.epub; rm book.epub
Edit any of the files that contain XML metadata.
eg., book.opf (XXE - XML External Entities pattern)
zip -r book.epub *
Point at a HTTP server to serve the following contents, and specifying a FTP server to recieve the specified file
EpubCheck <= 4.0.1
There was a online instance of EpubCheck, that would accept user uploads and perform validation on the format. This provides an example of how this vulnerability could be used to attack online services that support ePub in some way, if they are using a vulnerable version of EpubCheck to validate the uploaded file.
Uploading our created file:
HTTP listener receiving the dtd request when parsed by the remote XML parser, and custom FTP listener receiving the file (I didn’t think it would work, but specified /etc/shadow as the file to retrieve).
This means that we accidentally retrieved the /etc/shadow file. Public facing web apps running as root/system in prod… 😫
A few examples of other services, and applications I came across that were vulnerable:
Amazon KDP which allows publishers to upload books, was susceptible to XXE when converting books to the Kindle format.
External DTD specifying the file to retrive:
eg., Retrieving secret stuff from a users Windows documents folder:
Apple Transporter (underlying tool used to validate metadata and assets and deliver them to the iTunes Store), CVE-2016-7666.
Google Play Book uploads did not allow external entity processing, but was vulnerable to XML exponential entity expansion billion laughs. When uploading a ePub with this pattern, it would spend about 45 minutes trying to process the file before returning an error condition. Google confirmed this on their side.
Disclosure timeline stuff:
- Sep 2016: Reported XXE in EpubCheck <= 4.0.1.
- Sep 2016: Reported XXE in Adobe Digital Editions <= 4.5.2.
- Sep 2016: Reported XXE in Amazon KDP.
- Oct 2016: Reported XXE in Apple Transporter
- Oct 2016: Reported XML exponential entity expansion in play.google.com book uploads.
- Dec 2016: Coordinated disclosure.
- Jan 2017: This blog post (lots of time for users to patch).
Thanks to CERT/CC for their help in coordinating with different vendors & IDPF, and setting a disclosure timeline. I only tested a handful of digital readers and services, so if you find other vulnerable readers/services, tell CERT/CC (they were tracking the ePubCheck issue as VU#779243).
If you got this far, thanks for reading. 👋
I’ve recently become interested in real world examples of vulnerabilities in Node.js applications, which allow
I decided to mock up a simple example of user input passed to an eval() execution sink, to demonstrate an injection of a simple web shell into the server. This web shell will only exist within the current node.js process, and will not be written to disk.
This demo application will only allow a single user input selection to keep things simple:
Vulnerable code (user input passed to an eval execution sink):
In this example res.write(‘SSJS Injection’) is injected, and the server will return that string in the page response:
So we can perform arbitrary SSJS injection on this location. What about injecting a web shell that will start up after 5 seconds, listening on TCP/8000?
One line web shell:
Because we are inserting code which will be eval’d by the application, the web shell will not be written to disk, and execution will be performed from the existing node process.
Injection of the web shell (application continues to respond normally):
cat /etc/passwdusing the web shell:
ls -la /etc:
This is a really simple example of an application with a SSJS injection vulnerability. Another thing to note is that tools to identify web application vulnerabilities may not have support to detect this vulnerability. At the time of this writing, Burp Suite v1.6.10 did not identify a SSJS injection vulnerability in the demo application.
subscribe via RSS