We have been taking a close look at Android threats since they first appeared, looking for ways to analyze and classify them, as well as looking at possible attack vectors they may use in the near future. Some of our research has uncovered how Android applications could potentially exploit other installed applications to steal their private information or execute malicious code. In particular, we came across something that resembles Windows DLL Hijacking. Bear in mind that we are not talking about Android vulnerabilities per se, but application-specific issues. We found a few applications in the Google Android Marketplace that were susceptible to this attack and have notified the application developers accordingly.
Android provides APIs that allow an application to dynamically load code to be executed. For example, an application may support plug-ins that are downloaded and then loaded at a later time. Unfortunately, if these plug-ins are stored in an insecure location, this process can be hijacked, allowing access to private data and unexpected arbitrary code execution by malicious applications. Two classes allow the loading of additional code:
The first class, DexClassLoader, allows an application to load and execute additional DEX code (the code runs within Android’s Dalvik virtual machine). The dexPath parameter specifies the file name of the additional DEX code. The most obvious vulnerability would be if a developer uses a world-writable directory (such as the SD card) for the dexPath. A malicious application could simply replace the intended DEX code with malicious code. Fortunately, most developers recognize this issue and we haven’t found any applications that are vulnerable in this manner. However, the DEX code is translated into a performance-optimized version called ODEX (optimized DEX) behind the scenes. These ODEX files are saved to the path specified by the dexOutputDir parameter.
Unfortunately, many developers do not appear to have an understanding of the purpose of this parameter or the purpose of ODEX files. Numerous online code examples and the Android developer documentation itself use the SD card path for dexOutputDir. The SD card is both world-readable and world-writable by applications holding WRITE_EXTERNAL_STORAGE permissions. This means other applications can read and write to any files stored on the SD card. If an application uses the SD card path for the dexOutputDir, a malicious application can simply replace the application’s ODEX file with a malicious ODEX file. This allows the malicious application to run code under the context of the vulnerable application, providing access to private data and potentially performing malicious actions the original application did not have permissions to do. Using this technique, we were able to create proof-of-concept exploit code for the vulnerable applications we found in the Google Android Marketplace, allowing us to piggyback on their allowed permissions and perform actions beyond our application’s granted permission set.
The second class, PathClassLoader, has a similar issue with the libPath parameter, which fortunately turns out to be moot. Android will use this path to search for additional native libraries (also known as .so files or Linux Shared Object files) to load when, for example, the API loadLibrary is used. Typically, these should reside in the secure Android system library path, but the libPath parameter will be searched first (releases before 2.2 reversed which path was searched first).
We discovered additional applications in the Google Android Marketplace that are using this API with the SD card as the libPath parameter. However, since these are Linux binaries and not DEX code, they are subject to additional system permissions. In particular, by default, the external storage is mounted with the noexec flag to prevent the execution of any native binaries on the mounted file system, which renders this attack vector useless. This means the developers who specified the SD card did not have an understanding of the purpose of this parameter, since setting it to the SD card simply will not work.
When loading additional code in Android applications, a developer should ensure that both the loaded code and the generated alternative versions of the code are placed in a secured directory, typically within the application's private directory. Ideally, DexClassLoader would simply do so by default for dexOutputDir. We have contacted Google about these issues, who stated that they will update the developer documentation to remove references to using the insecure SD card location and also advise developers to use a secure directory.
For more information on mobile device security, please see Symantec’s latest whitepaper on the topic, “A Window into Mobile Device Security.” The paper provides a deep dive into the security models employed by Apple’s iOS and Google’s Android platforms. As demonstrated by both this blog post and the whitepaper, these and other popular mobile platforms in use today were largely designed with security in mind, but these provisions do not always sufficiently protect sensitive enterprise assets that regularly find their way onto mobile devices.
By: Mario Ballano
Android provides APIs that allow an application to dynamically load code to be executed. For example, an application may support plug-ins that are downloaded and then loaded at a later time. Unfortunately, if these plug-ins are stored in an insecure location, this process can be hijacked, allowing access to private data and unexpected arbitrary code execution by malicious applications. Two classes allow the loading of additional code:
Public Constructors | |
| DexClassLoader (String dexPath, String dexOutputDir, String libPath, ClassLoader parent) Creates a DexClassLoader that finds interpreted and native code. |
| PathClassLoader (String path, String libPath, ClassLoader parent) Creates a PathClassLoader that operates on two given lists of files and directories. |
The first class, DexClassLoader, allows an application to load and execute additional DEX code (the code runs within Android’s Dalvik virtual machine). The dexPath parameter specifies the file name of the additional DEX code. The most obvious vulnerability would be if a developer uses a world-writable directory (such as the SD card) for the dexPath. A malicious application could simply replace the intended DEX code with malicious code. Fortunately, most developers recognize this issue and we haven’t found any applications that are vulnerable in this manner. However, the DEX code is translated into a performance-optimized version called ODEX (optimized DEX) behind the scenes. These ODEX files are saved to the path specified by the dexOutputDir parameter.
Unfortunately, many developers do not appear to have an understanding of the purpose of this parameter or the purpose of ODEX files. Numerous online code examples and the Android developer documentation itself use the SD card path for dexOutputDir. The SD card is both world-readable and world-writable by applications holding WRITE_EXTERNAL_STORAGE permissions. This means other applications can read and write to any files stored on the SD card. If an application uses the SD card path for the dexOutputDir, a malicious application can simply replace the application’s ODEX file with a malicious ODEX file. This allows the malicious application to run code under the context of the vulnerable application, providing access to private data and potentially performing malicious actions the original application did not have permissions to do. Using this technique, we were able to create proof-of-concept exploit code for the vulnerable applications we found in the Google Android Marketplace, allowing us to piggyback on their allowed permissions and perform actions beyond our application’s granted permission set.
The second class, PathClassLoader, has a similar issue with the libPath parameter, which fortunately turns out to be moot. Android will use this path to search for additional native libraries (also known as .so files or Linux Shared Object files) to load when, for example, the API loadLibrary is used. Typically, these should reside in the secure Android system library path, but the libPath parameter will be searched first (releases before 2.2 reversed which path was searched first).
We discovered additional applications in the Google Android Marketplace that are using this API with the SD card as the libPath parameter. However, since these are Linux binaries and not DEX code, they are subject to additional system permissions. In particular, by default, the external storage is mounted with the noexec flag to prevent the execution of any native binaries on the mounted file system, which renders this attack vector useless. This means the developers who specified the SD card did not have an understanding of the purpose of this parameter, since setting it to the SD card simply will not work.
When loading additional code in Android applications, a developer should ensure that both the loaded code and the generated alternative versions of the code are placed in a secured directory, typically within the application's private directory. Ideally, DexClassLoader would simply do so by default for dexOutputDir. We have contacted Google about these issues, who stated that they will update the developer documentation to remove references to using the insecure SD card location and also advise developers to use a secure directory.
For more information on mobile device security, please see Symantec’s latest whitepaper on the topic, “A Window into Mobile Device Security.” The paper provides a deep dive into the security models employed by Apple’s iOS and Google’s Android platforms. As demonstrated by both this blog post and the whitepaper, these and other popular mobile platforms in use today were largely designed with security in mind, but these provisions do not always sufficiently protect sensitive enterprise assets that regularly find their way onto mobile devices.
By: Mario Ballano