When faced with the problem of identifying entities, most people reach for incremental IDs. Since this requires a central actor to avoid duplicates and can be easily guessed, many solutions depend on UUIDs or GUIDs (universally / globally unique identifiers). However, although being unique solves the first problem, it doesn’t necessarily cover the second. We’ll present our new solution for detecting such issues in web projects in the form of an extension for Burp Suite Pro below.
It’s been a steady trend that most of our pentest projects revolve around web applications and/or involve database backends. The former part is usually made much easier by Burp Suite, which has a built-in scanner capable of identifying (among others) injections regarding latter. However, detection is only half of the work needed to be done; a good pentester will use a SQL injection or similar database-related security hole to widen the coverage of the test (obviously within the project scope). Burp continually improves its scanning engine but provides no means to this further exploitation of these vulnerabilities, so in addition to manual testing, most pentesters use standalone tools. With the new features available since Burp Suite 1.7.09, we’ve found a way to combine the unique talents of Burp with our database exploitation framework, resulting in pretty interesting functionality.
After ImageTragick (CVE-2016–3714) was published, we immediately started thinking about detecting it with Burp, which we usually use for web application testing. Although collaborator would be a perfect fit, as image processing can happen out-of-band, there’s no official way to tap into that functionality from an extension.
The next best thing is timing, where we try to detect remote code execution by injecting the
sleep command which delays execution for a specified amount of seconds. By measuring the time it takes to serve a response without and the with the injected content, the difference tells us whether the code actually got executed by the server.
We used rce1.jpg from the ImageTragick PoC collection and modified it to fit our needs. By calling
System.nanoTime() before and after the requests and subtracting the values, the time it took for the server to respond could be measured precisely.
Since we already had a Burp extension for image-related issues, this was modified to include an active scan option that detects ImageTragick. The JPEG/PNG/GIF detection part was reused so that it could detect if any parameters contain images, and if so, it replaces each (one at a time) with the modified rce1.jpg payload. The code was released as v0.3 and can be downloaded either in source format (under MIT license) or a compiled JAR for easier usage. Below is an example of a successful detection:
Header image © Tomas Castelazo, www.tomascastelazo.com / Wikimedia Commons / CC-BY-SA-3.0
We’ve tested a number of iOS apps in the last few years, and got to the conclusion that most developers follow the recommendation to use APIs already in the system – instead of reinventing the wheel or unnecessarily depending on third party libraries. This affects HTTP backend APIs as well, and quite a few apps use the built-in
NSURLRequest class to handle HTTP requests.
However, this results in a disk cache being created, with a similar structure to the one Safari uses. And if the server doesn’t set the appropriate
Cache-Control headers this can result in sensitive information being stored in a plaintext database.
Like others in the field of smartphone app security testing, we’ve also discovered such databases within the sandbox and included it in the report as an issue. However, it can also be helpful for further analysis involving the API and for forensic purposes. Still, there were no ready to use tools, which is problematic in such a convoluted format.
The cache can usually be found in
[id] is application-specific, and is a standard SQLite 3 database, as it can be seen below.
$ sqlite3 Cache.db SQLite version 3.12.1 2016-04-08 15:09:49 Enter ".help" for usage hints. sqlite> .tables cfurl_cache_blob_data cfurl_cache_response cfurl_cache_receiver_data cfurl_cache_schema_version
Within these tables, all the information can be found that can be used to reconstruct the requests issued by the app along with the responses. (Well, almost; in practice, the lack of HTTP version and status text is not a big problem.)
Since we use Burp Suite for HTTP-related projects (web applications and SOAP/REST APIs), an obvious solution was to develop a Burp plugin that could read such a database and present the requests and responses within Burp for analysis and using it in other modules such as Repeater, Intruder or Scanner.
As the database is an SQLite one, the quest began with choosing a JDBC driver that supports it; SQLiteJDBC seemed to be a good choice, however it uses precompiled binaries for some platforms, which limits its compatibility. After the first few tests it also became apparent that quite a few parts of JDBC is not implemented, including the handling of BLOBs (raw byte arrays, optimal choice for storing complex structures not designed for direct human consumption). The quick workaround was to use
HEX(foo) which results in a hexadecimal string of the blob
foo, and then parsing it in the client.
BLOBs were used for almost all purposes; request and response bodies were stored verbatim (although without HTTP Content Encoding applied, see later), while request and response metadata like headers and the HTTP verb used were serialized into binary property lists, a format common on Apple systems. For the latter, we needed to find a parser, which was made harder by the fact that most solutions (be it code or forum responses) expected the XML-based representation (which is trivial to handle in any language) while in this case the more compact binary form was used. Although there are utilities to convert between these two (plutil, plistutil and others), I didn’t want to add an external command line dependencies and spawn several processes for every request.
Fortunately, I found a project called Quaqua that had a class for parsing the binary format. Although it also tried converting the object tree to the XML format, a bit of modification fixed this as well.
With these in place, I could easily convert the metadata to HTTP headers, and append the appropriate bodies (if present). For UI, I got inspiration from Logger++ but used a much simpler list for enumerating the requests, since I wanted a working prototype first. (Pull requests regarding this are welcome!)
Most of the work was solving small quirks, for example as I mentioned, HTTP Content Encoding (such as gzip) was stripped before saving the body, however the headers referred to the encoded payload, so both the
Content-Length and the
Content-Encoding headers needed to be removed, and former had to be filled based on the decoded (“unencoded”) body.
Below is a screenshot of the plugin in action, some values had been masked to protect the innocent.
When serving image assets, many web developers find it useful to have a feature that scales the image to a size specified in a URL parameter. After all, bandwidth is expensive, latency is killing the mobile web, and letting the frontend guys link to
avatar.php?width=64&height=64 pretty straightforward and convenient. However, solutions with those latter two qualities usually have a hard time with security.
As most readers already know and/or figured it out by now, such functionality can not only be used for scaling images down but also making them huge. This usually results in hogging lots of resources on the server, including RAM (pixel buffers), CPU (image transformation algorithms) and sometimes even disk (caching, temporary files). So in most cases, this leads to Denial of Service (DoS), which affects availability but not confidentiality; however, with most issues like this, it can be combined with other techniques to escalate it further.
During our assessments, we’ve found these DoS issues in many applications, including those used in banks and other financial institutions. Even security-minded developers need to think really hard to consider such an innocent feature as something that should be handled with care. On the other hand, detecting the issue manually is not hard, however it’s something that’s easy to miss, especially if the HTTP History submodule of the Burp Suite Proxy is configured to hide image responses as visual clutter.
To solve this, we’ve developed a Burp plugin that can be loaded into Extender, and passively detects if the size of an image reply is included in the request parameters. The source code is available on GitHub under MIT license, with pre-built JAR binaries downloadable from the releases page. It currently recognizes JPEG, PNG and GIF content, and parameters are parsed using Burp’s built-in helpers.
Since dynamically generated web content often has ill-defined
Content-Type values, this plugin checks if there’s at least 12 bytes of payload in the response, and if so, the first four bytes are used to decide which parser should be started for one of the three image formats above. As the plugin is only interested in the size of the image, instead of using a full-fledged parser, a simpler (and hopefully faster and more robust) built-in solution is used that tries to be liberal while parsing the image. If the dimensions of the payload could be extracted, the request is analyzed as well to get the parameters. The current version checks if both the width and the height is included in the request, and if so, the following issue is generated.
The plugin in its current form is quite usable, it’s passive behavior means that just by going through a site, all such image rescaling script instances will appear in the list of issues (if the default setting is used, where every request made through the proxy is fed to passive scanning). Future development might include adding an active verification component, but it’s not trivial as this class of vulnerability by design means that a well-built request might grind the whole application to a halt.
We encourage everyone to try the plugin, pull requests are welcome on GitHub!
The paper introduces the problem we’ve been facing more and more while testing complex web applications, and shows two working solutions. Burp Suite is known by most and used by many professionals in this field, so its GUI-based features are presented first. But as Burp is far from a one-size-fits-all perfect solution, an alternative is shown combining mitmproxy and commix – a dynamic duo that can not only detect but also exploit the issues. To make things easier to demonstrate (and possibly replicate and improve by readers), an intentionally vulnerable web application was developed that (unlike the aforementioned complex apps) requires minimal effort to deploy, lowering the bar for developing tools that can be used later in enterprise environment.
The full Gold Paper can be downloaded from the website of SANS Institute:
The accompanying code is available on GitHub.