An update on MD5 poisoning

Last year we published a proof-of-concept tool to demonstrate bypasses against security products that still rely on the obsolete MD5 cryptographic hash function.

Summary: The method allows bypassing malicious executable detection and whitelists by creating two executables with colliding MD5 hashes. One of the executables (“sheep”) is harmless and can even perform some useful task and is expected to be categorized as goodware by the victim. After the sheep is accepted by the victim, the colliding malicious version (“wolf”) is sent. Because affected products rely solely on the MD5 fingerprints to identify known good executables, wolf is already whitelisted and can run.

Although the reception of the research was generally positive, some were skeptical about the extent and even the validity of the issue. Although in the meantime we received information about more affected products, NDA’s prevented us from further demonstrating that the problem indeed exists and affects multiple vendors. 

Today we are able to share a demonstration of the problem affecting Panda Adaptive Defense 360. The issue is demonstrated against the stricter “Lock mode” of the product meaning that the Panda agent only allows known good executables to run (application whitelisting). For the sake of this video we manually unblock the harmless executable version (sheep4.exe) to speed up the process, as otherwise the analysis could take several hours to complete (it was confirmed that the “sheep” executables aren’t detected as malicious by the cloud scanner in case they are not manually unblocked):


(You can skip 01:00-01:55 if you are not interested in the policy update)

We notified Panda Security about this issue through their Hungarian partner (see the timeline at the end of this post). Panda responded that this is a known issue that is expected to be fixed in the next major version, but no ETA was provided. Panda stated that MD5 was used because of performance reasons. We informed Panda that the BLAKE2 hash function can provide higher level of security at better performance than MD5 (thanks to Tony Arcieri for this update!).

We’d like to stress that this research is not about individual vendors but about bad practices prevalent in the security industry. We now know of at least four vendors affected by the above problem and several others still provide MD5 fingerprints only in their tools and public reports. It is shameful that while hard work is put into phasing out SHA-1, in the security industry it is still generally accepted to use MD5, even after it was exploited in a real-world incident. We understand that there are more straightforward ways for evasion, but think that this issue is a good indicator of how security product development is often approached.

We should do better than this!

Timeline

2016.08.30: Sending technical information to vendor.
2016.09.05: Vendor requests more information, including PCOPInfo logs collected during retest.
2016.09.06: Sending demo video and identification information about product instance. Requesting more information about PCOPInfo usage.
2016.09.06: Vendor responds with instructions about PCOPInfo.
2016.09.08: Sending PCOPInfo logs to vendor.
2016.09.19: Vendor responds that this is a known issue, replacement algorithm is expected to be implemented in the next version.
2016.09.27: Requesting negotiation about issue publication date.
2016.10.12: Requesting negotiation about issue publication date. Including notification about 90-day disclosure deadline in case no agreement would be achieved.
2016.10.19: Vendor responds, internal discussion is still in progress.
2016.11.16: Requesting information about acceptance of publication date.
2016.11.28: Public release.

CqjSneqWEAEeeHH

Bake your own EXTRABACON

In the last couple of days we took a closer look at the supposed NSA exploit EXTRABACON,  leaked by Shadow Brokers. As an initial analysis of XORcat concluded, the code is capable of bypassing authentication of Cisco ASA devices after exploiting a memory corruption vulnerability in the SNMP service. We managed analyze and test the code in our lab and even add support for version 9.2(4) (that created quite bit of a hype :). While we don’t plan to release the upgraded code until an official patch is available for all affected versions, in this post we try to give a detailed description of the porting process: what the prerequisites are and how much effort is required to extend its capabilities.  We also hope that this summary will serve as a good resource for those who want to get started with researching Cisco ASA.

Continue reading Bake your own EXTRABACON

umbrella

Accessing local variables in ProGuarded Android apps

Debugging applications without access to the source code always has its problems, especially with debuggers that were built with developers in mind, who obviously don’t have this restriction. In one of our Android app security projects, we had to attach a debugger to the app to step through heavily obfuscated code.

Continue reading Accessing local variables in ProGuarded Android apps

Street_painting_in_guanajuato_01

Detecting ImageTragick with Burp Suite Pro

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:

issue screenshot

Header image © Tomas Castelazo, www.tomascastelazo.com / Wikimedia Commons / CC-BY-SA-3.0

Apfelteiler_fcm

iOS HTTP cache analysis for abusing APIs and forensics

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 Library/Caches/[id]/Cache.db where [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.

screenshot of the plugin

The source code is available on GitHub under MIT license, with pre-built JAR binaries downloadable from the releases page.

Featured image is Apfelteiler by Frank C. Müller licensed under CC BY-SA

Telescope_76d60a_53882

You’re not looking at the big picture

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.

Burp finding

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!

GWAPT_Gold

Testing stateful web application workflows

SANS Institute accepted my GWAPT Gold Paper about testing stateful web application workflows, the paper is now published in the Reading Room.

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:

Testing stateful web application workflows

The accompanying code is available on GitHub.

SSL Added and Removed Here

Proxying nonstandard HTTPS traffic

Depending on the time spent in IT, most professionals have seen an instance of two where developers based their implementations on specific quirks and other non-standard behaviors, a well-known example is greylisting, another oft-used but less-known one is Wi-Fi band steering. In all these cases, the solution works within a range of implementations, which usually covers most client needs. However, just one step outside that range can result in lengthy investigations regarding how such a simple thing like sending an e-mail or joining a Wi-Fi network can go wrong.

During one of our application security assessments, we found an implementation which abused the way HTTP worked. The functionality required server push, but they probably decided to use HTTP anyway to get through corporate firewalls, and the application came from the age before WebSockets and HTTP2. So they came up with the idea of sending headers like the one below, then keeping the connection open, without sending any data.

HTTP/1.0 200 OK
Server: IDealRelay
Date: Wed, 16 Sep 2015 18:03:24 GMT
Content-length: 10000000
Connection: close
Content-type: text/plain

Googling the value of the Server header revealed mostly false positives, however as it turned out, there’s even a patent US 7734791 B2 with the title Asynchronous hypertext messaging that describes this behavior. Sending data to the server happened over separate HTTP channels, which themselves returned worthless responses, and the real response arrived in the first HTTP channel promising to deliver 10 megabytes in its Content-length header.

Some corporate proxies might have handled this well, however the Proxy module of Burp Suite just waited for the full 10 MB to arrive and just hung there, waiting for all eternity – and even if it managed to receive some data, its Scanner module couldn’t have handled the correlation between sending a payload in one request and getting response in another. In order to solve the problem, I decided to throw together a simple HTTPS proxy that doesn’t assume that much about the contents, just accepts CONNECT requests, performs a Man-in-the-Middle (MITM) attack and dumps the plaintext traffic into a file.

Multiple streams needed to be handled asynchronously, so I chose Erlang for its unique properties, and used built-in modules for everything except generating fake certificates for MITM. Since such certificates are cached, I chose to sign them using the command line version of OpenSSL for the sake of simplicity, so a whitelist is applied to the hostname to avoid command injection attacks – even though it’s supposed to be a tool used to debug “well behaving” applications, it never hurts to protect and setting good example. As an output format, PCAP was chosen as it’s simple (the PCAP writer itself is 32 lines of Erlang code) and widely supported by tools such as Wireshark.

The proxy logic fits into 124 lines of code, and waits for new TCP connections. By setting the socket into HTTP mode, the standard library does all the parsing for the CONNECT request. A standard response is sent, and from this point, the mode gets changed back to raw, and both the server and the client gets an SSL handshake from the proxy. Server certificates used for MITM are cached in an ETS (built-in high-performance in-memory database) table, shared between the lightweight thread-like Erlang processes, so certificates are signed only once per hostname, and the private key is the same for the CA and all the certificates.

After the handshake traffic is simply forwarded between the peers, and simultaneously written into the PCAP file. TCP/IP headers are added with the same port/address tuple as the original stream, while sequence/acknowledgement values are adjusted to reflect the plaintext content. This way, Wireshark doesn’t have any problems with reassembling the stream and can even detect and dissect known application protocols. Source code of the SSL proxy is available in our GitHub repository under MIT license, pull requests are welcome.

With the plaintext traffic in our hands, we managed to develop another tool to experiment with the service and as a result, we found several vulnerabilities, including critical ones. So the lesson to learn is that just because tools cannot intercept traffic out of the box, it doesn’t mean that the application is secure – existing tools are great for lots of purposes but one big difference between hackers and script kiddies is the ability of former to develop their own tools.

salt

Finding the salt with SQL inception

Introduction

Web application penetration testing is a well researched area with proven tools and methodologies. Still, new techniques and interesting scenarios come up all the time that create new challenges even after a hundred projects.

In this case study we start with a relatively simple blind SQL injection situation and show how this issue could be exploited in a way that made remote code execution possible. The post will also serve as a reference for using Duncan, our simple framework created to facilitate blind exploitation.

Continue reading Finding the salt with SQL inception

bank

Virtual Bank Robbery – In Real Life

Introduction

This week a Polish bank was breached through its online banking interface. According to the reports the attacker stole 250.000 USD and now uses the personal information of 80.000 customers to blackmail the bank. Allegedly the attacker exploited a remote code execution vulnerability in the online banking application to achieve all this.

We at Silent Signal performed penetration tests on numerous online banking applications, and can say that while these systems are far from flawless, RCE vulnerabilities are fairly rare. Accordingly, the majority of the in-the-wild incidents can be traced back to the client side, to compromised browsers or naive users.

But from time to time we find problems that could easily lead to incidents similar to the aforementioned Polish banks. In this case-study we’re describing a remote code execution vulnerability we discovered in an online banking application. The vulnerability is now fixed, the affected institution was not based in Poland (or our home country, Hungary).

The bug

The online bank testing account had access to an interface where users could upload various files (pictures, HTML files, Office documents, PDFs etc.). The upload interface checked the MIME type of the uploaded documents only (from the Content-Type header), but not the extension. The Content-Type header is user controlled, so uploading a public ASPX shell was an obvious way to go; but after the upload completed I got an error message that the uploaded file was not found and the message revealed the full path of the missing file on the servers filesystem. I was a bit confused because I could not reproduce this error with any other files I tried to upload. I thought it was possible that an antivirus was in place that removes the malicious document before the application could’ve handled it.
I uploaded a simple text file with the EICAR antivirus test string with .docx extension(so I could make sure that the extension wasn’t the problem) that verified this theory. The antivirus deleted the file before the application could parse it that resulted in an error message revealing the full path:
EICAR

This directory was reachable from the web and the prefix of the file name was based on the current “tick count” of the system. The biggest problem was that the application removed the uploaded files after a short period of time because this was only a temporary directory. I could also only leak the names of deleted files but not the ones that remained on the system for a longer time. So exploitation required a bit more effort.

The Exploit

Before going into the details of the exploit, let’s see what “primitives” I had to work with:

  • I can upload a web shell (antivirus evasion is way too easy…)
  • I can leak the tick count by uploading an EICAR signature
  • I can access my web shell if I’m fast enough and know the tick count of the server at the moment the shell was uploaded

Unfortunately I can’t do these three things at the same time, so this is a kind of a race condition situation. According to the documentation “a single tick represents one hundred nanoseconds or one ten-millionth of a second” so guessing the tick count on a remote system through the Internet seems like a really though job. Luckily, I don’t always trust the documentation ;)

I built a simple test application that models the primitives described and implemented a simple time synchronization algorithm that I used before to predict time on remote servers with seconds precission. The algorithm works basically by making guesses and adjusting them based on the differentials to the actual reported server times.

While this algorithm wasn’t effective on the 100ns scale, the results were really interesting! I could observe that:

  1. Parallel requests result in identical tick counts with high probability
  2. The lower bits of the tick counts tend to represent the same few values

The reason for this is probably that the server processes are not truly parallel, just the OS scheduler makes you believe they are and that the resolution of the tick counter is imperfect. I also found out, that since the filenames are only dependent on the time my requests arrive to the application, the delays of the responses introduce avoidable uncertainty.

My final solution is based on grequests that is an awesome asynchronous HTTP library for Python. This allows me to issue requests very fast without having to wait for the answers in between. I’m using two parallel threads. The first uploads a number of web shells as fast as it can, while the other issues a number of requests with the EICAR string and then tries to access the web shells at constant offsets from the retrieved tick counts. The following chart shows the average hit rates (%) as the server side delays between the creation and deletion of the uploads changes:

avg_tick_hits

And although a few percent doesn’t seem high, don’t forget that I had to only be lucky once! As you can see there is a limit for exploitability (with this setup) between 300 ms and 400 ms but as we later found out the uploads were transferred to a remote host, so the lifetime of the temporary files was above this limit turning the application exploitable.

The model application and the test exploit is available on GitHub.

Conclusion

In this case-study we demonstrated how a low impact information leak and a (seemingly) low exploitability file upload bug could be chained together to an attack that can result in significant financial and reputation loss.

For application developers we have the following advises:

  • If you’re in doubt, use cryptographicaly secure random number generators.
  • Never assume that your software will be deployed to an environment similar to your test machine. A conflicting component (like the antivirus in this case) can and will cause unexpected behavior.
  • File uploads are always fragile parts of web applications, OWASP has some good guidelines about securely handling them.

And for those who are responsible for online banks or similar systems here are some thought-provoking questions:

  • Do your development teams follow a security focused development methodology? Because a good methodology is the base of a quality product.
  • Do you perform regular, technical security tests on your financial applications? Because people make mistakes.
  • Do you fix the discovered vulnerabilities on your production systems in reasonable time? Because tests worth nothing if it takes forever to fix the findings.
  • Do you have an incident response plan? Because despite all effort, incidents will eventually happen.
  • Would you notice an incident? Because IR doesn’t get started by itself.
  • Could you determine what the exploited vulnerabilities were and which users exploited (or tried to exploit) them? Because an incident is an opportunity to learn.