{
	"id": "ccb83c40-d9bb-4c4e-b550-d2d2722ee3c4",
	"created_at": "2026-04-06T00:19:17.083838Z",
	"updated_at": "2026-04-10T13:12:19.567565Z",
	"deleted_at": null,
	"sha1_hash": "19ff049991eede697f8d47e0bc26df027d508062",
	"title": "A Pattern for Remote Code Execution using Arbitrary File Writes and MultiDex Applications",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 308170,
	"plain_text": "A Pattern for Remote Code Execution using Arbitrary File Writes\r\nand MultiDex Applications\r\nPublished: 2017-06-15 · Archived: 2026-04-05 23:21:23 UTC\r\nSummary\r\nThe following blog explains vulnerabilities that allow attackers to execute code remotely on a Android userUs\r\ndevice through applications which contain both a arbitrary file write and use multiple dex files. This remote\r\nexploitation can occur without the userUs knowledge.\r\nIn this post, I will walk you through the issues and the process of developing a remote code execution exploit for\r\nthe Talking Tom application. This is a pattern which can be applied to many other applications. If you have any\r\nquestions, feel free to contact me via Twitter at @fuzion24.\r\nA video of the vulnerability in action can be seen below:\r\nhttps://youtube.com/watch?v=u9XqWuY0WG8\r\nVulnerabilities in External Libraries\r\nExternal, third-party libraries are often used by developers and are included in hundreds of thousands of\r\napplications. These libraries are treated like a black box. Developers choosing to implement external libraries in\r\ntheir applications must recognize that these libraries frequently contain vulnerabilities that weaken the overall\r\nsecurity of applications, with advertisement libraries being a particular target of interest. If and when\r\nvulnerabilities are identified in external libraries, the vulnerabilities must be patched, and the developer must then\r\nrebuild the application and redistribute it with a fixed library, as currently there is no operating system supported\r\nlibrary sharing mechanism. This leads to applications with long-standing or, at times, permanent vulnerabilities,\r\neven if patches to the external library are released.\r\nThe Vungle advertisement library contains an arbitrary write vulnerability which affects thousands of applications.\r\nWhile is not uncommon for games and other types of applications to download additional resources in plaintext\r\nvia a zipfile, this library provides an easy target as it is widely used and the attack vector is identical across all\r\naffected applications. We responsibly disclosed this vulnerability to Vungle prior to notifying all of the affected\r\ndevelopers, and then directly notified developers of the affected applications.\r\nWe determined that applications using the Vungle library and containing both a remote arbitrary file write and\r\nusing multiple dex files are remotely exploitable. Attackers can modify network traffic to gain code execution on a\r\nuserUs phone. This code execution will be restricted to the sandbox of the application. However, since OEMs and\r\nGoogle are relatively inadequate at releasing device patches to known privilege escalation vulnerabilities, it\r\nbecomes trivial for an attacker to escape the application sandbox once code execution has been gained on a vast\r\nmajority of devices. This type of vulnerability is particularly unfortunate because developers typically have very\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 1 of 8\n\nlittle visibility into the internal workings of 3rd party libraries. This is due to the fact that they are usually\r\ndistributed as blackbox binaries. The developers, therefore, can only be at fault for blindly including libraries of\r\nwhich they have no visibility.\r\nVungle Arbitrary Write Vulnerability\r\nThe Vungle advertisement library is distributed as a .jar which developers can include into their application. When\r\na developer utilizes this SDK, their application becomes vulnerable to a remote arbitrary file write vulnerability.\r\nThe following is a brief synopsis of the vulnerability (assigned CVE-2014-9333):\r\nWe can set up a man in the middle attack against the phone to proxy the deviceUs network traffic and see what is\r\nbeing sent by the application. The first request we see from the library is requesting instructions from the server on\r\nwhat to display:\r\n POST http://api.vungle.com/api/v1/requestAd _ 200 application/json 967B 947.36kB/s\r\nIn the JSON response, we can see the server tell the app where to download additional zip resources which contain\r\nthe video advertisements that are displayed throughout the application.\r\n{ ... \"postBundle\": \"http://cds.g8j8b9g6.hwcdn.net/bundles/526956a8584cbfa904000010-4.zip\"\r\nShortly thereafter, we see this zip being downloaded:\r\n GET http://cds.g8j8b9g6.hwcdn.net/bundles/526956a8584cbfa904000010-4.zip _ 200 application/zip\r\nThis ZIP file is downloaded in plaintext. There are no further mitigations to prevent tampering of the file. The\r\nAndroid ZIP APIs do not prevent directory traversals by default, allowing for a file with a directory traversal in\r\nthe name to be injected on-the-fly into the ZIP. This allows us to gain an arbitrary write in the context of the app.\r\nWith this, we can easily write a script for a proxy that will inject our payload on-the-fly into the zip. LetUs test\r\nthis out by downloading the payload using our zip injecting proxy:\r\n$ curl -x http://localhost:9999 http://cds.g8j8b9g6.hwcdn.net/bundles/51508704e2903eb17f000006-2.zip \u003e tmp.zip\r\nNow, letUs look at the files in the zip we downloaded through our proxy:\r\n$ unzip -l tmp.zip Archive: tmp.zip Length Date Time Name -------- ----\r\nNotice here that the zip was injected with a directory traversal that writes inside of the app directory. During the\r\nattack, we can see that our files were written in the applicationUs data directory. This directory is only writable by\r\nthe application that owns it:\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 2 of 8\n\nroot@hammerhead:/data/data/com.outfit7.mytalkingtomfree/code_cache/secondary-dexes # ls -l | grep i_wrote\r\nOur dummy payload was successfully extracted by Vungle. Now, we need to turn this file write into something\r\nmore useful.\r\nTurning our Arbitrary File Write into Code Execution\r\nAlthough the arbitrary file write is interesting, it only allows for us to be somewhat destructive by filling up the\r\ndisk and overwriting files. LetUs now look for a target that the application has write access to, which we can use\r\nto gain code execution.\r\nThe executable code of an Android application is stored inside the .APK (just a zip file) in a single file named\r\nclasses.dex where .dex stands for Dalvik Executable. When Android applications are installed, the classes.dex file\r\nis extracted from the APK and run through the the Dalvik optimizer. The optimized dex file, which has the file\r\nextension .odex , is then stored in /data/dalvik-cache/ . Here is the optimized dex file for Google+:\r\nroot@flo:/data/dalvik-cache # ls -l data@app@com.google.android.apps.plus-1.apk@classes.dex -rw-r--r-- s\r\nNotice here, that even Google+ itself doesnUt have write access to its own .odex file. It canUt tamper or rewrite\r\nthe original classes.dex file as it does not write to the filesystem where it can be modified by the application.\r\nAdditionally, apps cannot modify their own Android package file (.apk) after installation. Taking a look at an\r\n.odex file, we notice that itUs owned by system:all_a65, but only system has write access to this file. In this way,\r\nan application cannot modify its own Dalvik bytecode. In order for an application to dynamically extend itself, it\r\nneeds to utilize the DexClassLoader APIs.\r\nThe virtual machine on which Android applications execute, the Dalvik Virtual Machine, was designed for high\r\nefficiency and low power devices. The executable code for the VM is typically stored in a single file named\r\nclasses.dex. In contrast, Java bytecode is spread across many files with each file containing the bytecode for one\r\nclass.\r\nThe compactness of the DEX format allows for deduplication of strings and other constants. It also allows the file\r\nto be memory mapped rather than lazy loaded from disk. The Dalvik executable format (.dex) has well\r\ndocumented limitations which has some horrible workarounds that are exacerbated by bloated libraries. There are,\r\nhowever, solutions for this problem.\r\nThe Dalvik Exchange tool, which converts Java bytecode in the form of .class files into DEX format, has recently\r\nadded support for automatically splitting applications that exceed the method limit into multiple .dex files. Until\r\nthe latest Android support library revision, rev v21, applications had to manually manage the extra dalvik\r\nexecutables and dexload them when necessary.\r\nTaking a look at the files in the APK (the file format for Android applications; a zip file), we can see there are two\r\ndalvik executable files classes.dex and classes2.dex .\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 3 of 8\n\n_ ~ unzip -l com.outfit7.mytalkingtomfree-1.apk | grep classes 5286068 10-20-14 10:46 classes2.dex\r\nAndroid itself prior to Android 5.0 has no awareness of any Dalvik executable file except for classes.dex. The\r\nmulti-dex support library will need to load any secondary dex files (classesX.dex) dynamically. If we take a look\r\nat the dex loading API in Android we see:\r\npublic DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)\r\nThis means that we can only load a DexFile from disk and, therefore, the secondary dex loader will need to write\r\nour executable code to a disk where the app has write capabilities:\r\nroot@flo:/data/data/com.outfit7.mytalkingtomfree/code_cache/secondary-dexes # ls -l -rw-r--r-- u0_a285\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 4 of 8\n\nPoor kitty is about to get owned and he doesn’t even know it:\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 5 of 8\n\nLet’s validate that this is the exact same dex file as we saw earlier in the APK. We check the SHA1 of the\r\nclasses2.dex in the APK:\r\n_ /tmp unzip com.outfit7.mytalkingtomfree-1.apk classes2.dex Archive: com.outfit7.mytalkingtomfree-1\r\nLet’s pull the classes2.dex from the device and check its SHA1:\r\n_ /tmp adb shell su -c \"cp /data/data/com.outfit7.mytalkingtomfree/code_cache/secondary-dexes/com.outfit7.myt\r\nGreat. They match just as we thought.\r\nThis zip file contains the additional bytecode (the secondary dex) which is writeable by the application. Since the\r\nDalvik bytecode is writable from application context, we have a clear path to turn a write vulnerability into code\r\nexecution. Let’s get to work using our arbitrary file write via the Vungle library to overwrite the secondary dexfile.\r\nWe now have our arbitrary write primitive and we have a way to turn that into code execution. Let’s start crafting\r\nour payload. We will need to create a zip file with a classes.dex in it, which will get loaded by our target app and\r\nexecute our payload. I took a very naive approach to solve this problem: I created a .dex file with a HelloWorld\r\nclass and injected it into the zip.\r\nAfter injecting the .dex file I created into the zip, we see that the VM tried to load my .odex and realized it was\r\nstale because I had TupdatedU the Dalvik bytecode.\r\nI/dalvikvm(25418): DexOpt: source file mod time mismatch (455455dc vs 455c6d35) D/dalvikvm(25418): ODEX\r\nThe DEX file the app is loading has none of the expected classes, so it crashes with a NoClassDefFoundError\r\nexception.\r\nW/System.err(25418): java.lang.NoClassDefFoundError: com.outfit7.talkingfriends.clips.c W/System.err(254\r\nNo problem! Let’s just add com.outfit7.talkingfriends.clips.c class to appease the app and toss our payload in\r\nthere:\r\n package com.outfit7.talkingfriends.clips; import android.util.Log; public class c {\r\nAfter closing the app and reopening, our dex gets optimized and loaded. Since our payload is simply logging a\r\nstatement to logcat to prove code execution, we can check logcat:\r\n_ ~ adb logcat | grep WINN D/WINNER ( 7490): Game Over\r\nThis logging statement can easily be replaced with any malicious payload.\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 6 of 8\n\nThe app crashes after this which would take down our child process. In order to make a production grade exploit,\r\nwe would need to create a zombie process and replace our payload with the original so the app continues to\r\nfunction as normal.\r\nA more sophisticated exploit would be to inject the payload directly into the original dex file, by reverse\r\nengineering and patching the dalvik bytecode or by having the payload replace the original dexfile after execution.\r\nMitigations and Closing Thoughts\r\nPlaintext traffic\r\nAll traffic between clients and servers should encrypted and authenticated. TLS (Transport Layer Security,\r\npreviously SSL) should be used for all communications between the client and the server including for file\r\ndownloads such as ZIP files. Consider the recent example of Verizon injecting unique indentifiers into traffic.\r\nAttacks like this can be mitigated best by employing TLS. Using TLS to secure all communications would require\r\nattackers to obtain control over a Certificate Authority, making it that much harder to exploit these applications.\r\nValidation of Zip files\r\nThe default behavior of Android’s Zip library is dangerous. In order for the zip to write files outside of the target\r\nextraction directory an additional flag should be provided. Let’s consider how GNU unzip handles a zip file with a\r\ndirectory traversal in the filename:\r\nHere is an example of a zip file that includes a relative directory traversal:\r\n_ ~ unzip -l evil.zip Archive: evil.zip Length Date Time Name --------- -\r\nWhen we try to extract this zip file with GNU unzip, it strips off any dangerous components and extracts inside of\r\nthe current working directory:\r\n_ ~ unzip evil.zip Archive: evil.zip warning: skipped \"../\" path component(s) in ../../../../\r\nThere exists a flag to allow GNU unzip to extract files outside of the active extraction folder tree head.\r\n_ ~ unzip -: evil.zip Archive: evil.zip extracting: ../../../../../../../../some/random/path/\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 7 of 8\n\nFrom man unzip we can learn more about this flag:\r\n -: [all but Acorn, VM/CMS, MVS, Tandem] allows to extract archive members into\r\nAndroid therefore, needs to take care to ensure sane defaults. If a developer needs to extract files outside of the\r\ncurrent working directory, this should be an option, but its manual specification should not be required.\r\nDeveloper mistakes are inevitable. The easiest, most effective way to prevent this and similar type of attacks is to\r\nensure that all network traffic is properly secured via TLS. This is important enough that it bears repeating: All\r\nnetwork traffic should be encrypted!\r\nSource: https://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applicatio\r\nns/\r\nhttps://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.nowsecure.com/blog/2015/06/15/a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications/"
	],
	"report_names": [
		"a-pattern-for-remote-code-execution-using-arbitrary-file-writes-and-multidex-applications"
	],
	"threat_actors": [],
	"ts_created_at": 1775434757,
	"ts_updated_at": 1775826739,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/19ff049991eede697f8d47e0bc26df027d508062.pdf",
		"text": "https://archive.orkl.eu/19ff049991eede697f8d47e0bc26df027d508062.txt",
		"img": "https://archive.orkl.eu/19ff049991eede697f8d47e0bc26df027d508062.jpg"
	}
}