前言

模糊测试是一种自动向程序传递输入数据并监控其输出的自动化测试技术。通过这种技术,安全人员可以测试程序的可靠性以及识别潜在的安全漏洞。

我们(360成都安全响应中心)将对Stagefright Media Framework进行模糊测试。它是Android系统上用于解析多媒体文件的逻辑算法库,其中包含了大量的安全漏洞,攻击者通过构造特殊的多媒体文件导致拒绝服务或特权升级甚至远程执行代码。

我们将要使用的模糊测试工具为Michał Zalewski开发的一款最为流行的基于代码覆盖率的开源测试工具:AFL(American Fuzzy Lop)。 借助于其高效的策略,AFL已经在真实产品中发现了大量的漏洞。

在本文中,我们将指导你如何在Linux上使用AFL对stagefright进行模糊测试,从而更高效的复现已知漏洞或发掘新漏洞。 另外,本文不仅适用于stagefright,其中的一些经验同样适用于其它由C/C++编写的Android本地程序。

要求

在本节中,我们将首先向你介绍本文接下来使用的环境要求以及软件版本。为了避免出现其他未遇见的错误,我们建议你和我们保持完全一致。

  • 操作系统:Ubuntu 16.10 64bit, 不建议使用32位系统;
  • AFL版本:2.39b,最新的总是更好的;
  • AOSP版本:7.1.1_r25,如果你使用的是其他版本,你可能无法直接使用补丁文件;
  • llvm和clang版本:3.8。

我们假设你已经完成了下载并且编译AOSP的工作。另外,如果你想要使用ASAN,我们建议你编译AOSP为x86版本。

概述

官方AFL只支持在Linux上进行模糊测试,而stagefright是在Android多媒体框架下工作的,因此我们无法直接使用AFL对stagefright进行模糊测试。为了解决这个问题,我们提出了下面两种方案。

  • 方案A:将AFL移植到Android上,从而在Android模拟器或者真实的Android设备上进行模糊测试;
  • 方案B:将stagefright移植到Linux上,从而直接使用官方AFL对其进行模糊测试。

其中,我们已经实现了方案A–android-afl,并且公布了源代码,你可以从仓库得到更多信息。

方案A的主要流程图如下图所示。

方案B的主要流程图如下图所示。

显而易见,相比于方案A,方案B更加简洁,其效率也更好(通常来说,PC的性能远高于任何Android手机或者Android模拟器);另一方面,由于stagefright本身的复杂性,其实现也更加困难。

在后续的文章中,我们将一步一步向你介绍如何实现方案B。通过它,我们已经发现了两个漏洞。

  • CVE-2016-6764:mediaserver的拒绝服务漏洞;
  • CVE-2016-6766:mediaserver的拒绝服务漏洞。

细节

移植stagefright到Linux

显而易见,我们首先要让stagefright在Linux上正常工作。

移植binder和ashmem

stagefright需要通过ashmem驱动来共享内存,然而默认情况下Linux内核并不包含ashmem驱动。幸运的是,我们可以通过修改Linux内核配置,并重新编译安装新内核,从而激活ashmem驱动。

我们也许还有更好的解决方案,例如:使用shm代替ashmem或者完全去掉ashmem相关的代码;
注意,本文并未使用binder驱动,这里移植binder只是顺便而已。

使用以下命令下载内核源码。

1
sudo apt install linux-source

转到你要保存内核源码的目录并提取压缩文件。

1
2
cd kernel$ tar jxvf /usr/src/linux/linux-source-4.8.0.tar.bz2
cd linux-source-4.8.0

拷贝旧的.config文件到源码根目录并开始配置。

1
2
cp -vi /boot/config-`uname -r` .config
make oldconfig

接着使用下面的命令来激活ashmem驱动。

1
make menuconfig

转到Device Drivers->Android,选中Andoid Drivers和Android Binder IPC Driver。

转到Device Drivers->Staging drivers->Android,选中Enable the Anonymous Shared Memory Subsystem。

现在你可以开始编译安装内核了,执行下面的命令。

1
2
3
make -j16
sudo make modules_install
sudo make install

你还需要配置udev规则,从而使得任何用户均可访问binder和ashmem。

1
echo -e "KERNEL==\"binder\", MODE=\"0666\"\nKERNEL==\"ashmem\", MODE=\"0666\"" sudo tee /etc/udev/rules.d/android.rules

最后,重启你的电脑以启用新内核。

修改Stagefright源码

注意,变量ANDROID_BUILD_TOP为AOSP的根目录,ANDROID_PRODUCT_OUT为AOSP的输出目录。

在这一节,你需要对stagefright源码(包括libstagefright和 stagefright命令行工具)进行改动,原因主要为以下两点。

  • 平台性:stagefright使用了binder驱动进行进程间通信,然而默认情况下Linux内核并不包含binder驱动(实际上,我们可以通过修改Linux内核配置,并重新编译安装新内核,从而激活binder驱动);

  • 依赖性:stagefright命令行工具无法独立的对多媒体文件进行解析,它依赖于其他服务进程(如:servicemanager,mediaserver等)。

我们将不会阐述解决上诉两个问题的具体细节,你可以直接使用我们提供的适用于7.1.1_r25版本的补丁文件。如果你使用的版本和我们不同,你可能需要参照补丁文件,手动修改代码。

点击这里下载补丁文件stagefright.diff,转到$ANDROID_BUILD_TOP/aosp/master/frameworks/av目录并应用补丁。

$ cd $ANDROID_BUILD_TOP/frameworks/av
$ git apply stagefright.diff

编译

编译好x86版本的AOSP后,转到stagefright源码目录,并编译。

$ cd $ANDROID_BUILD_TOP/frameworks/av/cmds/stagefright
$ mm -j16

编译结束后,你可以在$ANDROID_PRODUCT_OUT/system/bin目录找到stagefright可执行程序。

配置运行环境

为了让系统能正确找到加载器以及依赖库的位置,你需要做以下软连接。

$ sudo ln -s $ANDROID_PRODUCT_OUT/system /system

拷贝解码器配置文件到/etc目录。

$ sudo cp $ANDROID_PRODUCT_OUT/system/etc/media_codecs_google_audio.xml /etc
$ sudo cp $ANDROID_PRODUCT_OUT/system/etc/media_codecs_google_telephony.xml /etc
$ sudo cp $ANDROID_PRODUCT_OUT/system/etc/media_codecs_google_video.xml /etc
$ sudo cp $ANDROID_PRODUCT_OUT/system/etc/media_codecs.xml /etc

另外,如果需要在后续使用ASAN,你还需要做以下软连接。

$ ln -s $ANDROID_PRODUCT_OUT/system/bin/linker $ANDROID_PRODUCT_OUT/system/bin/linker_asan
$ ln -s $ANDROID_PRODUCT_OUT/obj/lib/libclang_rt.asan-i686-android.so $ANDROID_PRODUCT_OUT/system/lib/libclang_rt.asan-i686-android.so

测试运行

现在,你可以尝试在Linux上运行stagefright了。例如,解析一个MP4文件,运行结果如下。

$ /system/bin/stagefright Disco.240p.mp4
thumbnailTime: 0 us (0.00 secs)
AVC video profile 66 and level 13
format changed.
...................$
avg. 180.73 fps
avg. time to decode one buffer 5485.86 usecs
decoded a total of 304 frame(s).

很好,你已经完成了最为困难也最为重要的工作!

移植AFL

首先,你需要从官网下载最新的AFL源码并解压。

$ wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
$ tar zxf afl-latest.tgz

接着,对AFL源码进行修改以修复下面几个错误。

error: undefined reference to '__fprintf_chk'
error: undefined reference to 'shmat'
error: undefined reference 'afl-area_prev'

同样,我们直接给出适用于2.39b版本(此时的最新版本)的AFL的补丁文件。如果你使用的版本和我们不同,你可能需要参照补丁文件,手动修改代码。

从这里下载补丁文件afl-2.39b.diff到你的电脑,转到AFL源码根目录并安装补丁。

$ cd afl-2.39b
$ patch -p2 < afl-2.39b.diff

使用以下命令编译安装AFL。

$ make clean all
$ cd llvm_mode
$ EXTRA_CFLAGS="-target i686--linux-android -U_FORTIFY_SOURCE" make clean all
$ cd ../
$ sudo make install

使用AFL和ASAN进行重编译

首先,进入你想要进行模糊测试的模块目录。

$ cd MODULE_PATH

其次,在其Android.mk文件中添加以下代码。

LOCAL_CLANG := true
export AFL_CC := /usr/bin/clang
LOCAL_CC := afl-clang-fast
export AFL_CXX := /usr/bin/clang++
LOCAL_CXX := afl-clang-fast++

注意,由于unsupported reloc这个错误,我们不推荐使用afl-gcc/afl-g++。另一方面,根据AFL官方的资料,afl-clang-fast/afl-clang-fast++也是更高效的。

接着,如果你想使用ASAN,你需要添加下面一行代码

LOCAL_SANITIZE := address

或者

LOCAL_SANITIZE := integer

最后,重新编译stagefright。

$ mm -j16

对于复杂的模块来说,你需要重复上面步骤数次,以对多个感兴趣的模块进行插桩。例如,你也许想要对以下模块进行插桩。

  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/omx
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/yuv
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/colorconversion
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/codecs/aacenc
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/matroska
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/filters
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/webm
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/mpeg2ts
  • $ANDROID_BUILD_TOP/frameworks/av/media/libstagefright/id3
  • …more…

恭喜你,所有准备工作都已经完成了,让我们开始模糊测试吧!

模糊测试

首先,你需要为AFL创建两个目录,一个为in,用于存放预先准备的输入样本;另一个为out,用于存放AFL模糊测试过程中生产的一些有用信息以及自动生成的会让程序挂起或者崩溃的样本。

$ mkdir in
$ mkdir out
$ cp -r testcase/* in

其次,你需要以root用户修改/proc/sys/kernel/core_pattern,以修复Pipe at the beginning of ‘core_pattern’这个错误。

$ sudo -s
$ echo core >/proc/sys/kernel/core_pattern

接着,你还需要设置CPU的工作模式为performance,以此来提高AFL的效率。

$ sudo -s
$ cd /sys/devices/system/cpu$ echo performance | tee cpu*/cpufreq/scaling_governor

如果使用了ASAN,你可能需要执行以下命令。

$ export ASAN_OPTIONS=abort_on_error=1:detect_leaks=0:symbolize=0:allocator_may_return_null=1

最后,执行以下命令开始模糊测试。

$ afl-fuzz -m 4096 -t 10000 -i in -o out -- /system/bin/stagefright @@

如果一切顺利,你将看到类似的AFL的工作屏幕。

建议

在这一节,我们将给你一些额外的建议,以帮助你更快的发现程序中的漏洞。

  • 使用尽可能小但覆盖全面的测试样本集;
  • 对于你想要进行模糊测试的模块,尽可能的编译为静态模块而不是动态模块;
  • 不要对你不敢兴趣的模块进行插桩;
  • 使用并行模糊测试(-M选项和-S选项),更多介绍请参考AFL源码目录中的 docs/parallel_fuzzing.txt;
  • ASAN需要大量的内存,因此你应该提高-m选项的值。

待办事项

本文还有许多可以改进的地方,但是我们不会在stagefright花费过多的精力了。

原文地址: http://bbs.pediy.com/thread-216319.htm

在Linux上使用AFL对Stagefright进行模糊测试相关推荐

  1. Linux上安装部署Solr-4.10.4并测试

    Solr是一种全文检索技术,在一些门户社区中能提高用户体验.Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口.用户可以通过http请求,向搜索引擎服务器提交 ...

  2. 如何在阿里云linux上部署java项目

    image.png 前2天把git练了下,敲了很多命令,也借助图形界面增强自己的理解,乘着余热把linux在熟悉下.然后想起以前婷主有让我帮忙搭建的阿里云服务器,所以就想自己试着在阿里云的linux上 ...

  3. lisp协议instand_分享|Linux 上 10 个最好的 Markdown 编辑器

    在这篇文章中,我们会点评一些可以在 Linux 上安装使用的最好的 Markdown 编辑器. 你可以在 Linux 平台上找到非常多的 的 Markdown 编辑器,但是在这里我们将尽可能地为您推荐 ...

  4. linux加微软的数据库,在Linux上使用Microsoft SQL – 安装SQL

    Microsoft 分享一下如何在Linux上使用Microsoft SQL 2017. SQL Server 2017旨在处理开源数据和应用程序的异构环境.在本技术白皮书中,您将获得业界领先的关系数 ...

  5. linux 存储映射lun 给_如何在 Linux 上扫描/检测新的 LUN 和 SCSI 磁盘 | Linux 中国

    导读:当 Linux 系统连接到 SAN(存储区域网络)后,你需要重新扫描 iSCSI 服务以发现新的 LUN.本文字数:3394,阅读时长大约:4分钟https://linux.cn/article ...

  6. linux上查看网络限制,如何在Linux上限制网络带宽

    您是否曾经与多个设备共享网络带宽?如果您曾经处于一个应用程序占用了所有流量的位置,那么您是系统管理员还是Linux用户,您将需要发现如何控制应用程序的上载和下载速度,以确保您的带宽并不完全被单个应用程 ...

  7. 在Linux上利用python获取本机ip

    下面介绍在Linux上利用python获取本机ip的方法. 经过网上调查, 发现大致有两种方法, 一种是调用shell脚本,另一种是利用python中的socket等模块来得到,下面是这两种方法的源码 ...

  8. Linux上隐藏进程名(初级版)

    缘起 上一篇博文 模仿nginx修改进程名 中提到了一种修改进程名的方法,就像 nginx 一样,给不同进程命名为 master 以及 worker 等.那么能不能把新进程名设置为空字符串呢?如果能, ...

  9. Windows/Linux上使用fopen相关函数读取大文件

    在介绍读取大文件之前,先了解下<cstdint>文件,标准头文件,存放固定宽度整数类型,如int32_t, uint32_t,不管在32位上还是64位上,长度都为4个字节:int64_t, ...

最新文章

  1. 柔宇冲刺科创板IPO:3年营收5亿净亏31亿,乐视掘墓人刘姝威坐镇董事会
  2. BGP MPLS中MCE技术介绍
  3. installEventFilter、eventFilter函数理解
  4. javap的用途不断发展:您的Java类文件中隐藏了什么?
  5. 求数列1/3到1/n之和
  6. Linux -Docker
  7. Unity UGUI制作HSV颜色选择器,看我表演川剧变脸
  8. Typora配置阿里云图床详细教程(PicGo+阿里云OSS)
  9. DirectX9 SDK Samples(19) AntiAlias
  10. 台式计算机怎么截屏,台式电脑怎么截屏
  11. 如何快速将多个文件合并为一个文件?
  12. css 文本移除及省略号位置
  13. 《网络攻防第二周作业》
  14. 【应用回归分析】CH3 回归参数的估计6——广义最小二乘估计
  15. 17_1.Excel股票分析工具-开盘前涨停数据
  16. 地图导航中的路径规划算法(综述)
  17. TiDB 实战优化之 SQL 常见问题与优化案例
  18. 企业WiFi管理 保卫我们的信息安全
  19. XJTU第十三周大计基编程作业
  20. Android使用Google SMSRetrieverAPI监听短信

热门文章

  1. 关于arm-linux-gcc的安装与配置
  2. Oracle函数大全2
  3. 图像中值处理MATLAB实现
  4. pip升级之后出现no module named pip
  5. Linux服务器安装NodeJs简易方法
  6. 【C++】语法小知识
  7. Matlab 实现对 Excel sheet 重命名 合并单元格
  8. [云炬创业基础笔记]第一章创业环境测试3
  9. 系列笔记 | 深度学习连载(5):优化技巧(下)
  10. 独家干货 | 林轩田机器学习课程精炼笔记!