The “hits” keep on coming for Android’s mediaserver component. We have discovered yet another Android mediaserver vulnerability, which can be exploited to perform attacks involving arbitrary code execution. With this new vulnerability, an attacker would be able to run their code with the same permissions that the mediaserver program already has as part of its normal routines.
This vulnerability has been designated as CVE-2015-3842. While it affects Android versions 2.3 to 5.1.1, Google has fixed and published details this vulnerability via the Android Open Source Project (AOSP). Currently, there are no known active attacks against this vulnerability.
This discovery closely follows three other major vulnerabilities in Android’s mediaserver component that surfaced recently. CVE-2015-3823 may allow attackers to trap phones in endless reboots, ANDROID-21296336 may render devices silent, while CVE-2015-3824 (Stagefright), can be used to install malware through a multimedia message.
How it works
The vulnerability involves AudioEffect, a component of the mediaserver program. It uses an unchecked variable which comes from the client, which is usually an app. For an attack to begin, attackers convince the victim to install an app that doesn’t require any required permissions, giving them a false sense of security.
Figure 1. Android UI showing the lack of permissions required by our POC app
The checking of the buffer sizes of pReplyData and pCmdData is not correct. The buffer sizes of both pReplyData and pCmdData and the buffer pCmdData itself all come from client-supplied parameters. As the mediaserver component uses these buffers, it reads a size coming from the buffer pCmdData; the mediaserver component assumes the buffer sizes of pReplyData and pCmdData are bigger than this size. We can make the buffer size of pReplyData, which is client-supplied, smaller than the size read from the buffer pCmdData. This causes a heap overflow.
I used the related source code files from a vulnerable Android version (5.1.1). In the screenshot below, we can see that the vulnerable file name is EffectBundle.cpp.
Figure 2. Heap overflow locations
Another vulnerable file is EffectReverb.cpp.
Figure 3. Heap overflow location
I decided to test it using a Nexus 6 with the Android 5.1.1 LMY47Z image. I wrote an app that crashes the mediaserver component by overflowing the buffer pReplyData in heap. Below is a portion of the PoC’s Java language source code.
Figure 4. Get mNativeAudioEffect from object
Below is the PoC’s C++ language source code, which is invoked by Java:
Figure 5. Send malformed data to mediaserver
In the PoC, when the app is running, the mediaserver component will crash at a random function. If the mediaserver component doesn’t crash, the POC app can be closed and ran again.
Below is one of the crash report logs:
F/libc ( 357): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7777776b in tid 4757 (Binder_5)
I/DEBUG ( 354): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 354): Build fingerprint: 'google/shamu/shamu:5.1.1/LMY47Z/1860966:user/release-keys'
I/DEBUG ( 354): Revision: '33696'
I/DEBUG ( 354): ABI: 'arm' W/NativeCrashListener( 855): Couldn't find ProcessRecord for pid 357
I/DEBUG ( 354): pid: 357, tid: 4757, name: Binder_5 >>> /system/bin/mediaserver <<<
I/DEBUG ( 354): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7777776b
I/DEBUG ( 354): r0 b3123bb4 r1 b3123bb4 r2 77777777 r3 b404e380
I/DEBUG ( 354): r4 b3123bb4 r5 b589a1c0 r6 b3123bb4 r7 00000003
I/DEBUG ( 354): r8 0000030e r9 b3123bdc sl 00000009 fp b5873b20
I/DEBUG ( 354): ip b6e46d7c sp b3123ba8 lr b6fb1db7 pc b6fb1c26 cpsr 80000030
I/DEBUG ( 354):
I/DEBUG ( 354): backtrace:
I/DEBUG ( 354): #00 pc 0001ec26 /system/lib/libaudioflinger.so
I/DEBUG ( 354): #01 pc 0001edb3 /system/lib/libaudioflinger.so
I/DEBUG ( 354): #02 pc 0002341b /system/lib/libaudioflinger.so
I/DEBUG ( 354): #03 pc 0002045f /system/lib/libaudioflinger.so
I/DEBUG ( 354): #04 pc 00009bef /system/lib/libaudiopolicyservice.so
I/DEBUG ( 354): #05 pc 00016d95 /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::getInputForAttr(audio_attributes_t const*, int*, audio_session_t, unsigned int, audio_format_t, unsigned int, audio_input_flags_t, android::AudioPolicyInterface::input_type_t*)+736)
I/DEBUG ( 354): #06 pc 00009701 /system/lib/libaudiopolicyservice.so
I/DEBUG ( 354): #07 pc 00069647 /system/lib/libmedia.so (android::BnAudioPolicyService::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+890)
I/DEBUG ( 354): #08 pc 0001a6cd /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60)
I/DEBUG ( 354): #09 pc 0001f77b /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+582)
I/DEBUG ( 354): #10 pc 0001f89f /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+38)
I/DEBUG ( 354): #11 pc 0001f8e1 /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)
I/DEBUG ( 354): #12 pc 00023a5b /system/lib/libbinder.so
I/DEBUG ( 354): #13 pc 000104d5 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)
I/DEBUG ( 354): #14 pc 00010045 /system/lib/libutils.so
I/DEBUG ( 354): #15 pc 00016baf /system/lib/libc.so (__pthread_start(void*)+30)
I/DEBUG ( 354): #16 pc 00014af3 /system/lib/libc.so (__start_thread+6)
I/BootReceiver( 855): Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
Possible threat scenarios
This attack can be fully controlled, which means a malicious app can decide when to start the attack and also when to stop. An attacker would be able to run their code with the same permissions that mediaserver already has as part of its normal routines. Since the mediaserver component deals with a lot of media-related tasks including taking pictures, reading MP4 files, and recording videos, the privacy of the victim may be at risk. Devices with customized versions of Android but with no modification made to the mediaserver component are also affected.
A dilemma users may face is that it will be difficult for them to locate the cause once an attack occurs. In our demo, we simply triggered the attack by running an app; this is convenient and intuitive for disclosure. While attacks can be triggered by apps alone, real-world attacks won’t involve apps that are easy to detect. The malicious app will try as much as possible to appear legitimate and use dynamic load technology to remain undetected while triggering the attack several days/months later, either persistently or intermittently, similar to other malware.
End users can block this threat from the onset by downloading Trend Micro Mobile Security (TMMS), which can detect threats trying to use this vulnerability and running any of the scenarios presented. Android users can also reboot their device using safe mode to uninstall the malicious app. However, this method might prove difficult, especially for those unaccustomed to tinkering with their devices.
We also recommend that device manufacturers patch their devices regularly to prevent their users from suffering from attacks that use this vulnerability.
This vulnerability was disclosed to Google, with details outlined below:
- June 19: We reported the issue, along with the corresponding POC, to the Android Security Team.
- June 19: The Android Security Team accepted it as a high severity vulnerability and assigned AndroidID-21953516 to it.
- June 24: The Android Security Team assigned CVE-2015-3842 to it.
- August 1: The Android Security Team published the fix in AOSP.