Download presentation
Presentation is loading. Please wait.
Published byRudolf Webster Modified over 7 years ago
1
A Whole New Efficient Fuzzing Strategy for Stagefright
Thank everyone. Thank you all for coming. This is my first time to attend an international conference as a speaker and my spoken English is not very good, so please bear with me and I will try to speak clear. So let’s just start. I am Zinuo Han, or you can just call me eleven. My presentation is <A Whole New Efficient Fuzzing Strategy for Stagefright: Porting and Optimizations>. Porting and Optimizations by Zinuo Han at Ruxcon 2017
2
About Me Security Researcher at Chengdu Security Response Center, Qihoo 360 Focused on Android vulnerability research and exploit development Right now, I work for Chengdu Security Response Center of Qihoo 360 as their security researcher. I focus on Android vulnerability research and exploit development. And you can contact me by the or my github.
3
Agenda Introduction Design Implementation Disclosure Conclusion
This is agenda for today's talk. It includes five parts: introduction, design, implementation, disclosure, conclusion.
4
Basic information about this talk
Introduction Firstly In this section, I will give you some basic information about this talk. Basic information about this talk
5
What is Stagefright A logical algorithm framework library for parsing multimedia on Android Written in C++ Support a wide range of audio and video formats Including MP3, MP4, MKV, MPEG2, MPEG4, and many more Lots of vulnerabilities have already been found in Stagefright So fist of all, what is Stagefright? If you have focused on Android security before, you may already know it. For those who don't know, it is a logical algorithm framework C++ library for parsing multimedia on Android. And it support a wide range of audio and video formats including MP3, MP4, MKV, MPEG2, MPEG4 and any other formats which supported on Android. And Lots of vulnerabilities have already been found in Stagefright.
6
Why Stagefright again Stagefright vulnerabilities keep attractive
Continuously patched in every Android security update since August 2015 Most Stagefright vulnerabilities assessed as Critical This means higher bounty Found vulnerabilities in multiple Stagefright components Libstagefright library, especially MPEG4Extractor.cpp OMX SW codecs(Most in 2017) So the next question is that since it has already been patched so many times from 2015 to 2016 why do I want to fuzz Stagefright again? The reason is that the first Stagefright bug was publicly announced on July 27, However until now, Google was still fixing the Stagefright bug in every Android security update. And because of remoteable gene, like play a video on the web page, most Stagefright bugs assessed as Critical that means Google will pays more bug rewards to researcher. And according to Android security bulletins, vulnerabilities are concentrated in libstagefright library, especially Mpeg4Extractor in Then, some vulnerabilities found in OMX components. Unti 2017, A large number of vulnerabilities in soft codecs have been discovered.
7
Why Stagefright again Stagefright vulnerabilities keep attractive
Continuously patched in every Android security update since August 2015 Most Stagefright vulnerabilities assessed as Critical This means higher bounty Found vulnerabilities in multiple Stagefright components Libstagefright, especially MPEGExtractor.cpp OMX SW codecs(Most in 2017) Still 0days All in all, Stagefright has turned in to a red sea with so many vulnerabilities and I believe that it still has 0days. So why not fuzz it?
8
Fuzzing the Media Framework in Android(MFFA)
Related Work Research Foucsed on Coverage-Guide ASAN Fast Crash Tolerant Fuzzing the Media Framework in Android(MFFA) by Alexandru Blanda at ELC 2015 libstagefright ✗ - ✓ Before introducing my fuzzing strategy, I will first go through the related works. <Fuzzing the Media Framework in Android> developed by Alexandru Blanda and talked at Embedded Linux Conference This research focused on libstagefright and obtained some interesting results, unfortunately it didn't use any coverage-guide and AddressSanitizer technologies.
9
Related Work Research Foucsed on Coverage-Guide ASAN Fast
Crash Tolerant Fuzzing the Media Framework in Android(MFFA) by Alexandru Blanda at ELC 2015 libstagefright ✗ - ✓ Stagefright: Scary Code in the Heart of Android by Joshua Drake at Blackhat USA 2015 MPEG4Extractor + The next one is <Stagefright: Scary Code in the Heart of Android> developed by Joshua Drake and talked at Blackhat USA This research only focused on MPEG4Extractor, and due to it's meaningful fuzzing approach which used coverage-guide and ASAN-enable technologies, it found lots of vulnerabilities. So it is a great research however not cover all components of stagefright.
10
Related Work Research Foucsed on Coverage-Guide ASAN Fast
Crash Tolerant Fuzzing the Media Framework in Android(MFFA) by Alexandru Blanda at ELC 2015 libstagefright ✗ - ✓ Stagefright: Scary Code in the Heart of Android by Joshua Drake at Blackhat USA 2015 + Fuzzing Android OMX by MingjianZhou and ChiachihWu at HITCON 2016 OMX ? The last one is <Fuzzing Android OMX> developed by MingjianZhou and ChiachihWu and talked at HITCON Their presentation has not enough details about their fuzzing strategy, I only know that this one focused on OMX components and discovered 21 vulnerabilities. This is a great results! But, this one not cover all components too.
11
About this talk What will be talked about next
How to design and implement a efficient fuzzing strategy for Stagefright What vulnerabilities did I find by the above method Conclusion of this talk What will not be talked about next The root cause of the vulnerabilities Vulnerabilites exploitation So, in the rest of this talk, I will introduce my fuzzing strategy in datail and show you some vulnerabilities found by this method that proved it is efficent. Finally, I will make a simple conclusion. And notice that the real root cause of vulnerabilites and analysis of vulnerabilites exploitation will not be talked today.
12
Design Goal & Architecture overview
In this section, I will talk about the design goal and architecture. Goal & Architecture overview
13
Goal More targeted Mainly focus on SW codecs
Because of these disadvantages of previous research, I decide to design a new fuzzing strategy which is more targeted. Android provides lots of software codecs for common media formats, and all of these software codecs are open source and written by C++. In general, the complex native codes are often vulnerable, so these should be a good target.
14
Goal More targeted More faster Mainly focus on SW codecs
Run Stagefright on desktop Linux Optimize Stagefright workflow And more faster. As we all know, desktop processors offer more performance than mobile processors. It means that if I can run Stagefright on desktop Linux, it will be more faster. And I also want to optimize Stagefright workflow to make it more faster too.
15
Goal More targeted More faster More technical
Mainly focus on SW codecs More faster Run Stagefright on desktop Linux Optimize Stagefright workflow More technical Coverage-Guided fuzzer(American Fuzzy Lop) AddressSanitizer And more technical. Coverage-Guided fuzzer and AddressSanitizer are the most popular technologies in recent years, and one of the most powerful and simple fuzzing tool is American Fuzzy Lop or AFL for short. So, I will use the both technologies in my fuzzing strategy.
16
Goal More targeted More faster More technical Find 0days more easily
Mainly focus on SW codecs More faster Run Stagefright on desktop Linux Optimize Stagefright workflow More technical Coverage-Guided fuzzer(American Fuzzy Lop) AddressSanitizer Find 0days more easily And the final goal is to find 0days more easily.
17
Architecture overview
Binder and ashmem driver on desktop Linux Test harness (Instrumented ) Attacked components Attack surface AFL MediaExtractor MediaCodec Libstagefright_soft_avcdec.so … MP4Extractor.cpp Desktop Linux Monitor (ASAN ) Test cases Real Android device Yes Crash ? Log monitor Unique crashes ? Save test cases Libstagefright_soft_aacdec.so Here is an overall architecture of my fuzzing strategy. Basically it has two parts, the left is fuzzing Stagefright with AFL on Linux and the right is recognizing the unique crashes on a real Android device. The overall architecture may seem simple, but there are some challenges need to be overcome.
18
Implementation Details of the fuzzing strategy
This is the most important section, in this section I will implement this fuzzing strategy step by step. Details of the fuzzing strategy
19
Steps in the fuzzing strategy
Find attack surface Porting Optimizations Get more powerful test cases Fuzzing mp4 container Recognize unique crashes Here are 6 main steps, including find attack surface, porting, optimizations, get more powerful test cases fuzzing mp4 container and recognize unique crashes. Let's find attack surface first.
20
Find attack surface - How is audio and video played
Start Examine the container type of the media file Create the appropriate extractor Extract the encoded frames Create the appropriate Codec Read encoded frames Decode data End MediaExtractor MediaCodec User APP So, how is audio and video played on Android Nougat? To simplify the process, I choose Stagefright command line tool as entry point. Firstly this tool loads the input media file into memory and passes a file descriptor to mediaextractor. Next mediaextractor examines the file to determine container type and codec type of the file by using sniffing mechanism and creates the appropriate extractor. Then mediacodec creates codecs of the required codec type and finally decodes all encoded frames. Note that playing audio and video requires at least three processes(user application, mediaextractor and mediacodec) to work together.
21
Find attack surface - How is audio and video played
Unprivileged Process MediaExtractor Service MediaCodec Service APP Privileged Process Binder IPC Let's look at this, These three processes communicate through the binder mechanism. The top half is unprivileged process, example a media player. The bottom half is privileged process. An attacker can easily attack mediaextractor and mediacodec services by passing a craft media file via binder ipc.
22
Find Attack Surface - Attacked components
Container Type Module Codec Type ASAN MP4 MPEG4Extractor.cpp AAC libstagefright_soft_aacdec.so MP3 MP3EXtractor.cpp AMRNB AMRWB libstagefright_soft_amrdec.so AMRExtractor.cpp H264 libstagefright_soft_avcdec.so FLAC FLACExtractor.cpp HEVC libstagefright_soft_hevcdec.so WAV WAVExtractor.cpp G711 libstagefright_soft_g711dec.so OGG OGGExtractor.cpp MPEG2 libstagefright_soft_mpeg2dec.so MKV MatroskaExtractor.cpp H263 MPEG4 libstagefright_soft_mpeg4dec.so MPEG2TS MPEG2TSExtractor.cpp libstagefright_soft_mp3dec.so WVM WVMExtractor.cpp VORIBS libstagefright_soft_vorbisdec.so AACExtractor.cpp OPUS libstagefright_soft_opusdec.so MPEG2PS MPEG2PSExtractor.cpp VP8 VP9 libstagefright_soft_vpxdec.so MIDI MIDIExtractor.cpp GSM libstagefright_soft_gsmdec.so Because Android supports a large number of media formats, so there are lots of potential attacked components including multiple container and codec type such as MPEG4Extractor, libstagefright_soft_avcdec and others shown in this table.
23
Find Attack Surface - Summary
Two potential attacked processes with privilege: mediaextracor and mediacodec Mediaextractor is used to extract audio and video frames Mediacodec is used to encode and decode audio and video frames Full controllable input data Complex input formats It means the possibility of more vulnerabilities Easy to trigger No special permissions required So here is a summary. I have found two potential attacked processes with privilege: mediaextracor and mediacodec. I can fully control the input data and the input formats are very complex, it means the possibility of more vulnerabilities. I can trigger it without any special permissions.
24
Porting - What and why Port Stagefright to x86
Android device most likely uses the ARM architecture, but the x86 family of processors is used in most desktop Port binder and ashmem driver to linux Stagefright works with binder and ashmem driver, which are not enabled in desktop Linux as default Port AFL to Android toolchains The shmat() function is used in the afl-llvm-rt.o.c, however Android toolchains can’t recognize it Setup running environment So next I will introduce some details of the porting work. If you need full details you can contact me by . Here are three core components need to port. I need to port Stagefright framework to x86 because of the different processor architectures of Android and desktop. And I also need to port binder and ashmem driver to linux which are not enabled in desktop Linux as default. Official AFL was already working on Linux desktop, so why need to port yet? The reason is that Android toolchains can't recognize shmat() function, causing a failure when try to cross-compile afl-llvm-rt which is used to instrument the target Android binary. And last I need to setup running environment to make it work
25
Porting - What and why Port Stagefright to x86
Android device most likely uses the ARM architecture, but the x86 family of processors is used in most desktop Port binder and ashmem driver to linux Stagefright works with binder and ashmem driver, which are not enabled in desktop Linux as default Port AFL to Android toolchains The shmat() function is used in the afl-llvm-rt.o.c, however Android toolchains can’t recognize it Setup running environment Make it efficient And the real reason is to make the fuzzer efficient.
26
Porting - Port Stagefright to x86
Download AOSP code from: Build Android for x86 Build Stagefright to x86 $ cd aosp $ source build/envsetup.sh $ lunch aosp_x86-eng $ make –j64 Porting Stagefright to x86 is easy to implement. Just download AOSP code from the official website and build AOSP and Stagefright to x86. You can just refer to the commands on this page. $ cd framework/av/cmds/stagefright $ make –j64
27
Porting - Port binder and ashmem driver to Linux
Download the latest version of the Linux kernel from: Enable the binder and ashmem driver e.g. (Linux kernel version ) Add new udev rules to set correct permissions CONFIG_ANDROID=y && CONFIG_ANDROID_BINDER_IPC=y && CONFIG_ASHMEM=y $ echo -e "KERNEL==\"binder\", MODE=\"0666\"\nKERNEL==\"ashmem\", MODE=\"0666\"" | sudo tee /etc/udev/rules.d/android.rules Fortunately, the binder and ashmem driver have already merged into Linux kernel tree. So, I just only need turn some configuration options on. example, set CONFIG_ANDROID, CONFIG_ANDROID_BINDER_IPC and CONFIG_ASHMEM to y in Linux kernel version And compile and install the new kernel. And new devices are only fully accessible by the root user by default. However, I don't want to run Stagefright and afl-fuzz as root, so I create new udev rules to set correct permissions and here is the command code.
28
Porting - Port AFL to Android toolchains
Use syscall() function instead of shmat() function in afl-llvm-rt.o.c Force the compile wrapper(afl-clang-fast) to instrument the shared libraries Cross-compile afl-llvm-rt.o which should be linked into the target Android binary shmat(shm_id, NULL, 0); + syscall(SYS_ipc, IPCOP_shmat, id, flag, &addr, addr); if (!strcmp(cur, "-shared")) maybe_linking = 0; Next to make AFL work more friendly with Android toolchains I use syscall() function instead of shmat() function to fix compile errors. AFL official suggests compiling a static binary, however Stagefright contains multiple dynamic libraries and it uses dlopen() function to load the codecs libraries which are need to be instrumented for fuzzing. So It is so difficult to compile Stagefright as a static binary. The solution is to change the AFL source code to force afl to instrument the shared libraries. As you see, just need comment one line. And of course, I need cross-compile the object which should be linked into the target Android binary.
29
Porting - Setup running environment
Create a soft link Copy configuration files Startup dependency services: e.g. mediaextractor, mediacodec... $ ln –s out/system /system $ cp out/system/etc/media_codecs_google_audio.xml /etc $ cp out/system/etc/media_codecs_google_telephony.xml /etc $ cp out/system/etc/media_codecs_google_video.xml /etc $ cp out/system/etc/media_codecs.xml /etc Notice that I'm not porting the whole Android to Linux desktop due it's very difficult and unnecessary. Actually I just want to run Android x86 native binary on Linux desktop. But there are some problems. Android and Linux have different dynamic linkers, Android uses /system/bin/linker, if you try to directly run a Android x86 binary on Linux, you will get the same error: no such file or directory. Also a dynamically-linked android executable needs some shared libraries. To solve this problem in a simple way, I create a soft link at /system which references original file out/system. And special for Stagefright, I also need copy some configuration files which used to initialize mediacodec list. Finally startup dependency services: e.g. mediaextractor, mediacodec and other related services.
30
Porting - It works Running 5x times faster
Let's look into the two screenshots. I used Stagefright command line tool to decode the same mp4 file on Android and Linux. The top screenshot is running on a Google pixel phone and the bottom screenshot is running on a Ubuntu desktop with Intel Core i7 processor. As you can see, it is running 5 times faster.
31
Porting - what else Make it more efficient Make it more AFL-friendly
Make extractor and codec work independently Bypass the media type sniffing mechanism Decode only one encoded frame Make it more AFL-friendly Running as a single process Let's start optimizing Although I have gained 5 times performance, but it still took about 1.7 seconds to decode a test case, maybe it is ok for testing but still slow for fuzzing. So, I need to make it more efficient and more AFL-friendly. Let's start optimizing.
32
Optimizations - Take a step back to Stagefright workflow
Start Examine the container type of the media file Create the appropriate extractor Extract the encoded frames Create the appropriate Codec Read encoded frames Decode data End MediaExtractor MediaCodec User APP Firstly, Let's take a step back to Stagefright workflow. In this talk, I only focus on decoding process, especially the data parsing logic, however there are some unnecessary time-consuming steps in Stagefright workflow. So in this section I will show you why and how to optimize it to improve performance.
33
Optimizations - Make extractor and codec work independently
Why When fuzzing target is codec(extractor), extractor(codec) will waste CPU time When fuzzing target is codec, unnecessary check logic in extractor could stop the decoding process ahead of time How Fuzz only one target at a time MediaExtractor MediaCodec User APP Start Examine container and codec type Create the appropriate extractor Extract the encoded samples Create the appropriate Codec Read encoded frames Decode data End In standard work flow, extractor and codec always work together. However this mechanism is not suitable for fuzzing. There are two reasons, one is that when fuzzing target is codec, extractor will waste CPU time and vice versa. The another one is that when fuzzing target is codec, some unnecessary check logic in extractor could stop the decoding process ahead of time, e.g. header validity check. So I'd prefer to fuzz only one target at a time. The solution is as shown in the right flowchart, I changed the workflow to make them independently.
34
Optimizations - Bypass the sniffing mechanism
Why Fuzz one specify meida type at a time is more efficient, the sniffing is not necessary for this job Cause meaningless mutations: there is chance that one media type could be turned into other media type by AFL How Specify the container and codec type MediaExtractor MediaCodec User APP Start Examine container and codec type Create the appropriate extractor Extract the encoded samples Create the appropriate Codec Read encoded frames Decode data End Android uses the sniffing mechanism to automatically examine media file types. This mechanism will take some time to repeatedly parse a part of the file data. More importantly, it will causes meaningless mutations. When fuzzing with a coverage-guide fuzzer, like AFL, the code coverage information of sniffing mechanism will guide the mutation turn one media type to other media type. And this is unacceptable, I want to fuzz one specify media type at a time. The solution is to specify the container and codec type by manually enter parameters.
35
Optimizations - Decode only one frame
Why Typically, a standard media file contains multiple frames However, most vulnerabilities have been triggered when decoding the first frames – Just in my experience How Break the decoding loop MediaExtractor MediaCodec User APP Start Examine container and codec type Create the appropriate extractor Extract the encoded samples Create the appropriate Codec Read encoded frames Decode data End The next optimizations step is to decode only one frame of each test case. A standard media file usually contains multiple frames data. Example, a tens of seconds video may contains hundreds frames data. The original Stagefright will repeatedly decode all of the encoded frames. However, most vulnerabilities have been triggered when decoding the first frames. It means that I don't really need decode the rest of frames when fuzzing. And this conclusion is just my experience, I have not really prove it yet. The solution is so simple, just break the decoding loop when first frame has been decoded. if (numFrames == 1) break;
36
Optimizations - Running as a single process
Why Multi-process communication brings extra overhead AFL-unfriendliness How Create services in local MediaExtractor MediaCodec User APP Start Examine container and codec type Create the appropriate extractor Extract the encoded samples Create the appropriate Codec Read encoded frames Decode data End So the last step of optimization is running as a single process. What's the meaning of this? Like I talked at first, playing or decoding media file requires multiple processes to work together. And the core parsing logics are all hold by mediaextractor and mediacodec. The Stagefright command line tool is just a interface. Multiple processes bring two disadvantages. One is that multi-process communication brings extra overhead and the other is not afl-friendly. So what's the meaning of AFL-unfriendliness? afl-fuzz uses shared memory to collect code coverage information of target process, But it can not talk with multiple processes that means afl-fuzz can only talk with the Stagefright command line tool, but loses contact with mediaextractor process and mediacodec process. On the other hand, afl-fuzz uses waitpid() function to check if the target process crashes. So afl-fuzz has no ideal about whether the mediaextractor process and mediacodec process crash. So based on these two reasons, the solution is to modify the Stagefright source code to create all remote services in local.
37
Optimizations - Running as a single process
// Create MediaCodecList object instance in local sp<IMediaCodecList> MediaCodecList::getLocalInstance() { sCodecList = new MediaCodecList; return sCodecList; } sp<IMediaCodecList> MediaCodecList::getInstance() { // Get the remote interface of the mediaserver via binder IPC sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player")); sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); if (service.get() != NULL) { sRemoteList = service->getCodecList(); if (sRemoteList == NULL) { // if failed to get remote list, create local list sRemoteList = getLocalInstance(); return sRemoteList; MediaExtractor MediaCodec User APP Start Examine container and codec type Create the appropriate extractor Extract the encoded samples Create the appropriate Codec Read encoded frames Decode data End Ok, here is an example for media play service. Let's look at the getInstance() function. Firstly, target process get remote interface of the mediaserver process via binder IPC; Then, mediaserver process create MediaCodecList object instance and return remote binder interface to target process; Finally, target process has got a remote interface for MediaCodecList. Now, Let's look at the getLocalInstance() function. It is so simple that target process directly create MediaCodecList object instance in local.
38
Optimizations - The new Stagefright work flow
Start Examine the container type of the media file Create the appropriate extractor Extract the encoded frames Create the appropriate Codec Read encoded frames Decode data End MediaExtractor MediaCodec User APP Finally, a new Stagefright work flow as shown in this figure.
39
Optimizations - It works faster
Two test harness for extractor and codec 20x+ performance gains So, Let's test it's performance. In the top screenshot, I used Stagefright command line tool to decode a mp4 file, it took about 1.7 seconds. After the above optimization works, as shown as the bottom screenshot, it works so fast and gains 20 times performance.
40
Get more powerful test cases - Where to get test cases
The AOSP repository contains a large number of test cases Search in Google File format conversion tools ffmpeg Open source project e.g. -inurl:htm -inurl:html intitle:"index of" .mp4 So up to now, I have got a very fast target program, but I still need powerful test cases. The first question is that where to get test cases. Fortunately, The AOSP repository contains lots of valid media files and some POC for known vulnerabilities located in cts folder. And search in google is a good solution for some common media formats. And for some indeed unpopularity of the media formats, you can use file format converters, like ffmpeg. And also you can download test cases from open source project.
41
Get more powerful test cases - How to get encoded frames
Dump the data when decoding a media file Refer to the following code // framework/av/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp void SoftAVC::onQueueFilled(OMX_U32 portIndex) { … // If input dump is enabled, then write to file // pv_stream_buffer points to encoded frames // u4_num_Bytes is encoded frames length DUMP_TO_FILE(mInFile, s_dec_ip.pv_stream_buffer, s_dec_ip.u4_num_Bytes); } The second question is that how to get encoded frames which is the input data for fuzzing codecs. Let's look into the following code, the SoftAVC::onQueueFilled() function is entry point to avc codec decoder. The pv_steam_buffer points to encoded frames data and the u4_num_Bytes is length of the encoded frames. If input dump is enabled, the DUMP_TO_FILE macro will write encoded frames to file. For more details, just refer to this cpp file.
42
Get more powerful test cases – Keep it small (< 1kb)
Keep only the video or audio data that actually want to fuzz Keep only one frame data Use afl-tmin tool $ ffmpeg –i input_file –vcodec copy –an output_file_video $ ffmpeg –i input_file –acodec copy –vn output_file_audio $ ffmpeg –i input_file –codec copy –frames 1 output_file The last and most important is to keep test cases small and less than 1 kilobyte is preferable. Video files usually contain both video and audio data, however I only want to keep only one that actually want to fuzz. And keep one frame data by using ffmpeg tool, I have already talked about this before. And afl-tmin is also a good tool.
43
Get more pwerful test cases – Keep it small (< 1kb)
Keep only the video or audio data that you actually want to fuzz Keep only one frame data Use afl-tmin tool Remove useless data, save CPU time $ ffmpeg –i input_file –vcodec copy –an output_file_video $ ffmpeg –i input_file –acodec copy –vn output_file_audio $ ffmpeg –i input_file –codec copy –frames 1 output_file So all of these solutions are designed to remove as much useless data as possible and save CPU time, so that the fuzzing will be more faster and efficient.
44
Fuzzing mp4 container - Test harness
// extractorfuzz.cpp int main(int argc, char **argv) { if (argc != 3) return -1; ProcessState::self()->startThreadPool(); // Running in persistent mode while (__AFL_LOOP(1000)) { // argv[2] is the input file path sp<FileSource> fileSource = new FileSource(argv[2]); // argv[1]is the container type of the input file sp<IMediaExtractor> extractor = MediaExtractor::Create(fileSource, argv[1]); } return 0; Ok, Let's start a real fuzzing. Sorry I don't have time to give you all details for all types of containers and codecs fuzzing. So I just go a little bit about fuzzing mp4 container as a case study. So let's first look into the source code of test harness. This test harness is simple. Here are two arguments, the first is the input file path, the second arguments is the container type of the input file so that fuzzer can bypass the sniffing mechanism. And I also used persistent mode which offer performance gains up to 5 to 10 times.
45
Fuzzing mp4 container - Instrument
Add the following to Android.mk in test harness and libstagefright Build LOCAL_CLANG := true LOCAL_CFLAGS += -fno-omit-frame-pointer -O2 export AFL_PATH := /usr/local/lib/afl/arm export AFL_CC := /usr/local/bin/clang LOCAL_CC := afl-clang-fast export AFL_CXX := /usr/local/bin/clang++ LOCAL_CXX := afl-clang-fast++ And next add the following code to Android makefile in test harness and libstagefright. I have set LOCAL_CLANG to true so I can use llvm mode. And export some AFL variable so afl-clang-fast can instrument the target. Then just rebuild target. $ mm -j16
46
Fuzzing mp4 container - Get test cases
Get original test cases from here cts/tests/tests/media/res/raw/a_4_aac.mp4 cts/tests/tests/media/res/raw/swirl_128x128_h264.mp4 Keep only one frame ffmpeg –i a_4_aac.mp4 –codec copy –frames 1 a_4_aac_1frame.mp4 ffmpeg –i swirl_128x128_h264.mp4 –codec copy –frames 1 swirl_128x128_h264_1frame.mp4 I get two test case from AOSP repository located at cts folder. And also you can get your test case from anywhere. And keep only one frame by using ffmpeg tool.
47
Fuzzing mp4 container - Lunch afl-fuzz loop
Fuzzing in distributed mode Make full use of CPU performance Increase the -m and -t limits The decoding process requires more memory and time $ afl-fuzz -M fuzz0 -m t i in -o out -- extractorfuzz video/mp4 $ afl-fuzz -S fuzz1 -m t i in -o out -- extractorfuzz video/mp4 … So let's just lunch afl-fuzz loop. Here are two suggestions for all of you: One is fuzzing in distributed mode so that you can make full use of CPU performance. Other is to increase the parameter m and parameter t limits, because of the decoding process requires more memory and time.
48
Fuzzing mp4 container - Running screen
Faster Exec speed > 10k/sec Efficient Find paths in 9 seconds Here is a running screen of mp4 container fuzzer. You can see, it decodes 10 thousand test cases per second and find more than 1500 paths in just nine seconds. So it is so faster and efficient.
49
Recognize unique crashes - Why
The AFL recorded crashes may be non-reproducible Different code for different processor architectures Some crashes not interesting Assertion The unique crashes recorded by AFL are not always unique AFL's uniqueness was determined based on tuple instrumentation that is too strict Not crash ≠ Not vulnerability Some vulnerabilities(e.g. use-after-free) don't cause crashes After fuzzing all types of containers and codecs about a week, I have got thousands of crashes. So does that mean I have found thousands of new vulnerabilities? The answer is impossible. Because of I'm running fuzzer on x86 architectures, so if a vulnerability found in x86 special code, it maybe non-reproducible on real Android device, like pixel phone which uses arm64 processor. And some crashes due to assertion failures are not interested. Android Security Team rate this issue as not a security vulnerability. And the unique crashes recorded by AFL are not always actually unique. AFL's uniqueness was determined based on tuple instrumentation that is too strict. And some vulnerabilities don't cause crashes. (e.g. use-after-free) So because of the above reasons, I recognized unique crashes one by one again.
50
Recognize unique crashes - How
Push the unique crashes and the generated corpus to a real Android device with the latest security updates Examine all corpus with ASAN-enabled again Build AOSP with ASAN: Monitor crash logs Record the unique crashes The uniqueness is determined based on ASAN backtrace information $ make -j42 S SANITIZE_TARGET=address make -j42 $ fastboot flash userdata && fastboot flashall Firstly push the unique crashes and the generated corpus by AFL to a real Android device with the latest security updates. Next test all corpus with ASAN-enabled again and monitor crash log by using adb logcat command. When crashes are found, check the ASAN backtrace information for each crash, If the call stack is unique then record the crash as unique. $ adb logcat
51
Disclosure Discovered vulnerabilities
In this section, I will show you all vulnerabilities found by this fuzzing strategy. And I'm sorry that I'm not taking about any exploit. Discovered vulnerabilities
52
Discovered vulnerabilities - Summary
As of October 1, 2017, total 30 vulnerabilities have been discovered 13 vulnerabilities are duplicate 17 vulnerabilities(11 critical, 5 high and 1 moderate) have been disclosed on Android Security Bulletins Some issues are still in process Covered multiple memory corruption vulnerability types Heap overflow Heap use after free Stack buffer overflow Global buffer overflow - Not fix yet Alloc dealloc mismatch FPE As of October 1, 2017, I have found total 35 vulnerabilities, Most of them are found in one week. And 17 vulnerabilities have been disclosed on Android Security Bulletins. (including 11 critical, 5 high and 1 moderate) Unfortunately, 13 vulnerabilities are duplicate and some issues are still in process. These vulnerabilities have covered multiple memory corruption vulnerability types, such as heap-overflow, heap-use-after-free, stack-buffer-overflow, global-buffer-overflow and more.
53
Discovered vulnerabilities - Details
CVE Type Severity components CVE heap-user-after-free Critical mp4/container CVE heap-buffer-overflow h263/codec CVE mpeg2/codec CVE CVE CVE hevc/codec CVE mpeg4/codec CVE CVE This table shows some details about discovered vulnerabilities. The most type is heap-buffer-overflow, and here are so many components are vulnerable, I have found new vulnerabilities in mp4 container, h263, mpeg2, hevc and more.
54
Discovered vulnerabilities - Details
CVE Type Severity components CVE heap-buffer-overflow Critical avc/codec CVE stack-overflow vorbis/codec CVE High CVE sonivox/container CVE mp4/container CVE fpe CVE alloc-dealloc-mismatch Moderate CVE And this table too. And except for one assessed as moderate, the others are all assessed as critical or high. And you can get the root cause of this vulnerabilities from the Android Security Bulletins.
55
Discovered vulnerabilities - POCs
Also you can get all POCs from my github.
56
Conclusion Presentation conclusion
Finally, I will take a brief conclusion to this presentation. Presentation conclusion
57
Conclusion A new efficient fuzzing strategy for Stagefright has been implemented, and 17 new vulnerabilities have been found This fuzzing strategy is besed on Android Nougat and AFL-2.51b, it also compatible with other version in theory, but the details may need to be changed Is there still have 0days in Stagefright ? - Yes, but need more powerful technologies or tricks Not only fuzzing Stagefright on Linux, Fuzzing all Android native binaries on Linux too I have implemented a new efficient fuzzing strategy for Stagefright and found 17 new vulnerabilities by this method. Notice that this fuzzing strategy is based on Android Nougat and version 2.51 of AFL, so if you want test it with other version, some details about this fuzzing strategy may need to be changed. And an interesting question is that is there still have 0days in Stagefright framework? Of course, my answer is yes, but need more powerful technologies or tricks to find them. And the last idea is to give everybody that you can fuzz all Android native binaries on Linux with these technologies talked today.
58
Reference https://source.android.com/security/bulletin/
Stagefright-Scary-Code-In-The-Heart-Of-Android.pdf pdf Effective-File-Format-Fuzzing-Thoughts-Techniques-And-Results.pdf And thanks for all of this paper. Thank for AFL. Thank for other researches.
59
Zinuo Han ele7enxxh@gmail.com
Thank you very much And the end, thank you very much for spending so much time listening my talk. And if you have any questions, contact me by is more better. Thank you! Zinuo Han
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.