Talking about Windows drivers at 44CON 2015’s Community Evening

I’ll be speaking at 44CON this year, at the community evening on Wednesday 9th September. The community evening is free to attend – you just need to register to attend if you don’t have a conference ticket. My talk is currently scheduled at 19:45, and I’m speaking about writing Windows drivers, with the goal of leaving you a bit more informed about how they work, and how to get started.

In addition to my talk, Saumil Shah will be speaking about Stegosploit, and Michael Boman will be running a workshop on anti-analysis techniques used in malware. After the talks, there will be a showing of the 20th anniversary edition of Hackers, which is guaranteed to be fun.

As usual, there will be drinks and good conversation. Hope to see you all there! 🙂

Advertisements

Another year, another Securi-Tay, another talk… and this time we’re sponsoring the bar!

Another year has rolled by (damn, I really don’t update this blog much, do I?) and Securi-Tay IV is coming up. I’ll be speaking about security issues related to serialisation and deserialisation of data in modern programming languages, including PHP and C#.

My colleague FreakyClown will be talking about robbing banks for a living, which promises to be amusing at the very least (which reminds me – ask me about coathangers and server rooms when you see me).

Most importantly though: we (and by that I mean Portcullis) are sponsoring the bar this year! I hope to see you all there for plenty of drunken security rambling.

Pentesting Java EE web applications with LAPSE+

Just a quick tip for anyone doing a code review of a Java EE web application: LAPSE+ is a very useful tool to have in the arsenal, whether you’ve got the original source or just the JAR/WAR file.

In my case, the client provided me with a single .WAR file which contained the application. As it was a large application, I didn’t really fancy digging through everything manually with JD-GUI, although it is an excellent Java decompiler. I decided to take the opportunity to give LAPSE+ a try.

Here’s what  you’ll need:

You can also grab a PDF instruction manual for LAPSE from the same site. However, be aware that I found some of the information in there to be a bit misleading, e.g. needing a specific version of Eclipse. Also, don’t worry if your client provided you a project for a different IDE, such as IntelliJ IDEA – it doesn’t really matter.

First step is to get Eclipse set up. Drop the .jar file from the LAPSE+ archive into the plugins directory of Eclipse. (Re)start Eclipse, then go to Window -> View -> Other… and select the items relating to LAPSE+. A little toolbar should appear on the right with blue spherical buttons. These are your LAPSE+ windows.

Next step is to load your code into a project. This is split up into two parts, but if you’ve already got an Eclipse project for the site’s source code, you can skip the first part. Otherwise, you’ll need to extract the code from your archive and make a project for it. Start by loading the JAR (rename the .WAR to .JAR if needs be) into JD-GUI. It should decompile the archive and let you browse the code. Go to File -> Export all Sources, and save the resulting ZIP file somewhere. This archive now contains all your decompiled source code, split into directories based on the namespace hierarchy.

Now, go back to Eclipse and create an empty Java project, filling the wizard out with whatever values suit you. Once that’s created, go into the project explorer tree and find the src directory, then right click it and select Import. Select your newly exported ZIP file, and Eclipse will populate your project with your reverse-engineered source. Now right-click the project and select Build. In all likelihood, it’ll throw a whole load of errors due to imperfect decompilation – don’t worry, we don’t really care, because LAPSE+ can still function with a broken build.

Once you’ve got your project set up, go to the individual LAPSE+ windows and browse through what they found. You might need to manually refresh them to run through the checking process. In my case, I found about a 10:1 ratio of false positives, which isn’t actually too bad for code scanning. Within an hour or so of digging through the results I’d found a couple of concrete XSS bugs that I’d not spotted yet, plus a whole bunch of potential XSS bugs that I couldn’t immediately find vectors for, and a whole variety of other interesting stuff to dig through. It’s a really nice way to cut down a 400kLoC project into manageable target points.

Steam Code Execution – Privilege Escalation to SYSTEM (Part 2)

In my previous post I talked about a vulnerability in Steam which allows you to bypass UAC. I’m going to be totally transparent here: I fucked up. I wrote the draft post a few days back, then did some more work on the vulnerability. I discovered something much more serious in the process. I posted last night’s blog post at 1am, tired as hell, and in my sleep-deprived state I completely neglected to update it properly, and there are several mistakes and bits of missing information. The draft went out and confused a lot of people. So, for that, I apologise. I’m going to leave it there so people can see it, because it’ll remind me not to do that next time.

Now, onto the real impact of the vulnerability: I can leverage it to gain code execution as SYSTEM. How? Well, it turns out that Steam.exe gives itself one unusual privilege – the privilege to debug other processes. This is called SeDebugPrivilege and one of its features is that it allows the process to bypass access control lists (ACLs) on processes when you call OpenProcess, i.e. the process can open a handle to any process it likes, with any privilege it likes.

Here’s how you can elevate to SYSTEM when you have SeDebugPrivilege:

  1. Open a handle to a process that is running as SYSTEM, with PROCESS_ALL_ACCESS as the access flag.
  2. Use VirtualAllocEx to allocate a block of memory in the remote process, with the executable flag set.
  3. Use WriteProcessMemory to copy a block of shellcode into that memory buffer.
  4. Use CreateRemoteThread to create a new thread in the remote process, whose start address is the base address of the memory allocation.
  5. Bingo! You just got a privesc to SYSTEM.

In this case, once you’ve got code execution inside Steam, you can utilise this trick to escalate yourself to SYSTEM. There’s your privesc vuln.

Installing Dropbox? Prepare to lose ASLR.

Dropbox has become a daily part of my life. I rely on it to synchronise data between my growing set of devices. But how much of an impact does it have on the security of my system? I decided to find out by digging around in exactly what it does to my machine, or more specifically, the processes running on it.

The first thing I want to check out is what modules are loaded into various processes. Tools like Dropbox like to extend the functionality of other programs using shell extensions, which are nothing more than specially designed DLLs loaded into process memory. Let’s see what we’ve got…

Dropbox Files

Interesting! Looks like we’ve got two extension DLLs, one 32-bit and one 64-bit. These are likely used to add extra context menu options when right-clicking on files. Now let’s find out where they get injected. For this, we’ll use good ol’ trusty Process Explorer. By going to Find » Find Handle or DLL, we can search for the DLLs in running processes.

Dropbox DLL Injection

It looks like it’s being loaded into processes that have windows created, which implies it’s probably an AppInit DLL, but it turns out not to be the case – the registry key doesn’t contain that DLL. This implies that there’s something more active going on, and that Dropbox actively selects which processes to inject into. I may be mistaken here, I’m not sure. Either way, though, it’s a little odd that it chose to inject into Notepad++ and other innocuous processes.

(Update: thanks to zeha and 312c on Reddit for pointing out that it’s likely injected via the standard file browser shell, due to the Dropbox icon in the favourites list)

The biggest problem becomes clear when you take a look at the module in a running process. In this case, it’s Firefox:

Dropbox in Firefox

Notice that the Dropbox extension DLL doesn’t have the ASLR flag set. This means that any vulnerability in Firefox becomes a lot easier to exploit, since the Dropbox module provides an unrandomised anchor for a ROP chain. Ignore PowerHookMenu.dll here – I’m aware of that issue and have notified the developer, but it’s infrequently seen on people’s machines so it’s not so bad.

Let’s just quickly verify that the DLL isn’t ASLR enabled at all, by checking the DLL characteristics flags in the file…

ASLR disabled for DLL

Definitely not enabled.

Anyway, the take-away issue here is that Dropbox arbitrarily injects an ASLR-disabled DLL into various 32-bit and 64-bit processes, causing significant degradation in the efficacy of ASLR across the entire system. With no ASLR, an attacker could craft an exploit payload that utilises executable code within the injected DLL to product a ROP chain, leading to code execution. This is significantly problematic in high-risk programs like web browsers and torrent clients.

I notified Dropbox of this back when version 1.0.0.17 was the latest version, but got not response. I’ve since tried again, but had no luck. I’m hoping that going public will give them the kick they need to get it fixed. In the meantime, a good mitigation is to install EMET and set a policy to enforce Mandatory ASLR. All of this was re-tested against Dropbox 2.0.22, with versions 1.0.0.19 of both the 32-bit and 64-bit DLLs. The operating system used was Windows 7 x64 SP1.

Update: Brad “spender” Spengler (of grsec fame) has noted that the latest version of Dropbox has ASLR enabled for the 64-bit DLL, but still doesn’t on 32-bit.

Update 2: Dropbox responds: “Our engineers are aware of this issue and actively working on fixing it. Unfortunately, I can’t give you an exact timeline that a fix will become available. If you have any additional questions or concerns please let me know.”

Update 3: @_sinn3r has done some awesome work on the exploitability of these issues, over at Metasploit. Definitely worth a read.

A quick crypto lesson – why “MAC then encrypt” is a bad choice

In light of the numerous recent attacks against SSL, I thought I’d offer up a quick and simple crypto lesson about why MAC-then-encrypt schemes are bad. This post will require only a minimum of knowledge about cryptography, so hopefully it’ll be useful to a wide range of people.

This is not designed to be a full and detailed description of how SSL works, or how various attacks against it works, but rather a short primer on the subject for those who know a bit about crypto but don’t really understand how something as seemingly strong as SSL might be broken. Some parts have been generalised or simplified for brevity and ease of understanding, so please don’t take anything I say here as a literal description of how it all works.

Anyway, let’s get started…

A secure network protocol has two main jobs:

  1. Keep the information in the conversation completely confidential.
  2. Prevent an attacker from tampering with the conversation.

The first part, as you probably already know, is performed by encryption. This usually involves exchanging one or more secret session keys between two endpoints, then using them with a cipher of some kind in order to provide safety against eavesdroppers.

The second part is a little more involved. In this case, when I say “tampering with the conversation”, I mean forging packets that look like they came from a legitimate endpoint, in such a way that they have a meaningful effect on the security of the conversation. This part is often implemented via a Message Authentication Code (MAC), which verifies that all data received was in fact sent by an authorised endpoint. Usually, a HMAC hash will be used, which is a keyed version of a cryptographic hash function. By using the session key as the key for the HMAC hash, it is possible to produce a hash of the payload in a way that cannot be forged by anyone that does not know the session key. By computing the same HMAC hash on the receiving end, using the same session key, it is possible to verify the authenticity of the data.

However, there’s a catch. One implementation option, called MAC-then-encrypt, is to compute the MAC on the plaintext data, then encrypt the data. The receiving endpoint then decrypts the data using the session key, and verifies its authenticity. Unfortunately, this means that an unauthenticated attacker can send arbitrary messages, and the receiving endpoint must decrypt them first in order to verify the MAC. Without knowing the session key, the attacker will likely produce garbage data after decryption, and the MAC will not match.

There is, however, an interesting trick that can be done here. Block ciphers require the length of all plaintext messages to be a multiple of the cipher’s block size. Since there is often a length discrepancy, padding is used to ensure that the message length is extended to fit. There are many different algorithms for generating padding data, but the padding is usually reliant on the plaintext in some way. This padding is checked during the decryption phase, and invalid padding results in an error. An attacker can flip certain bits in the ciphertext to modify this padding, and identify changes in behaviour and timing based on these altered bits. This is called a padding oracle attack, and can lead to full discovery of the plaintext.

A better solution, called encrypt-then-MAC, is to encrypt the data first, then compute the MAC of the ciphertext. This leads to a situation where the receiving endpoint checks the MAC first, before performing decryption, and drops the connection if the MAC is incorrect. Since the attacker can’t forge the MAC without knowing the session key, this completely negates the padding oracle attack.

How is all of this relevant to SSL? Well, in TLS 1.0 and earlier, a MAC-then-encrypt scheme was used. This resulted in various attacks, including BEAST and Lucky 13. In TLS 1.1 and later, these types of attacks are prevented.

Hopefully this has given you some insight into one of the ways that SSL can be vulnerable.

The anti-virus age is over.

As far as I’m concerned, anti-virus systems are as good as dead. Or, if they aren’t just yet, they’re certainly headed that way.

Signature-based analysis, both static (e.g. SHA1 hash) and heuristic (e.g. pattern matching) is useless against polymorphic malware, which is becoming a big concern when you consider how easy it is to write code generators these days. By the time an identifying pattern is found in a particular morphing engine, the bad guys have already written a new one. When you consider that even most browser scripting languages are Turing complete, it becomes evident that the same malware behaviour is almost infinitely re-writeable, with little effort on the developer’s part. Behavioural analysis might provide a low-success-rate detection method, but it’s a weak indicator of malintent at best.

We’ve also seen a huge surge in attacks that fit the Advanced Persistent Threat (APT) model in the last few years. These threats have a specific target and goal, rather than randomly attacking targets to grab the low-hanging fruit. Attacks under the APT model can involve social engineering, custom malware, custom exploits / payloads and undisclosed 0-day vulnerabilities – exactly the threats that anti-malware solutions have difficulty handling.

The next problem is memory-resident malware. It’s very difficult (i.e. computationally expensive) for AV software to monitor the contents of program memory, let alone provide accurate detection of in-memory exploits on a live system. If malware never touches the disk, most AV software will never catch it. In his  “HTML5 – A Whole New Attack Vector” talk at BSidesLondon, Robert McArdle talked about botnets and other malware, written in HTML5, that reside within a browser tab. Now, assuming the browser doesn’t cache this on disk (you can usually mandate this with HTTP headers) you’ve got a memory-resident malware threat that doesn’t need browser exploits, is easy to obfuscate, and has full networking capabilities. On the other side of things, arbitrary code execution exploits within browsers might be leveraged to load executable modules into process memory. It would be relatively simple to write malware that remains resident in the browser process, or infects other long-running processes on the system. It’s also usually possible to prevent swapping on memory pages, so you can guarantee that the malware never touches the disk. It’s a nightmare for AV software, and a nightmare for forensic analysts.

Whilst the technical aspects of these attacks are a daunting opponent to anti-virus systems, the economic aspect is the nail in the coffin. According to PayScale, an average software developer in India gets about 320,000 INR per year, which equates to roughly 5700 USD. Compare that to the price of a malware analyst or systems security analyst, which is 60,000 USD before insurance, pension and other benefit costs are tacked on. That means that for every analyst that an AV company hires, the bad guys can hire 10 developers. That’s easily enough to work on 3 or 4 malware projects in parallel. There’s no competition here – the bad guys have more people working for them, for less money, and they don’t need to adhere to employment standards or ethical working practices. They can produce and update malware significantly more quickly (and cost-effectively) than the AV guys can analyse and defend against it.

Now don’t get me wrong, AV still has its place in the security world – without it, sysadmins would have to deal with a deluge of common malware used by script kiddies. However, it’s no longer much more than a filter for the most basic attacks.