文章一开始发表在微信公众号

https://mp.weixin.qq.com/s/wNeeuS3XojfZWvtAJ9xGlQ

Fuzz Android Native库

为了能够Fuzz Android Native库,笔者基于QBDI框架为AFLplusplus新增一种Fuzz模式,代码和文档如下

https://github.com/vanhauser-thc/AFLplusplus/tree/master/qbdi_mode

qbdi_mode的工作方式是在template.cpp里面把目标库加载到内存,然后设置好被测函数需要的参数,最后调用目标函数。在这个过程里面会使用QBDI的API获取到目标程序的覆盖率信息并启动forkserver和AFL通信,从而实现Fuzz。

本节以Whatsapp为例,介绍如何Fuzz Android的Native库。在Whatsapp APK中的libwhatsapp.so里面的Java_com_whatsapp_Mp4Ops_mp4check函数是一个JNI函数

__int64 __fastcall Java_com_whatsapp_Mp4Ops_mp4check(JNIEnv_ *a1, __int64 a2, __int64 a3, char a4)
{
// 转换UTF-8字符串到 C 字符串
fpath = (a1->functions->GetStringUTFChars)(a1, v5, 0LL);
clock_gettime(1, &tp); // 目标函数, 处理视频文件
v8 = sub_79C70(fpath, &tp, 2 * (v4 == 0), 0);

根据JNI函数的调用约定和Java层的参数信息可以发现该函数的参数类型大概为

a1: JNIEnv
a2: jobject
a3: 文件路径
a4: 一个bool变量,为0或者1

Java_com_whatsapp_Mp4Ops_mp4check函数最终会把文件路径转换成C字符串并传入sub_79C70函数,后面再也没有用过这个文件路径,那么这个函数应该就是实际处理文件的函数,而且函数的参数比较简单,那么我们就可以直接去Fuzz这个函数,修改template.cpp在main函数里面获取到sub_79C70函数的地址

	void *offset_func = dlsym(handle, "Java_com_whatsapp_Mp4Ops_mp4check");

	if (NULL == offset_func) {
printf("getprocaddress error\n");
return 1;
} p_target_func = (target_func)((unsigned char *)offset_func + 0x45af0);
printf("target function addr: %x\n", p_target_func);

然后修改fuzz_func,构造好sub_79C70函数需要的参数,然后调用它。

QBDI_NOINLINE int fuzz_func() {

  if (afl_setup()) { afl_forkserver(); }

  unsigned long len = 0;
char * data = read_file(FPATH, &len); printf("In fuzz_func\n");
struct timespec tp;
clock_gettime(1, &tp);
p_target_func(FPATH, &tp, 1);
printf("execute p_target_func:%p\n", p_target_func);
exit(0);
return 1;
}

编译完成后要能够执行被测程序需要先把libQBDI.so放到安卓设备上并设置LD_LIBRARY_PATH为libQBDI.so和libwhatsapp.so所在的路径,因为libwhatsapp.so还依赖一些APK里面的库。

# find / -name libwhatsapp.so 2>o
/data/app/com.whatsapp-wMSOMeRwydbzJJmi-G1wEw==/lib/x86_64/libwhatsapp.so
# ls ./libQBDI.so
./libQBDI.so
# pwd
/data/lsl
# export LD_LIBRARY_PATH=/data/lsl:/data/app/com.whatsapp-wMSOMeRwydbzJJmi-G1wEw==/lib/x86_64/
# ./loader /data/app/com.whatsapp-wMSOMeRwydbzJJmi-G1wEw==/lib/x86_64/libwhatsapp.so xxx.mp4
target function addr: 7eaf9c70
In fuzz_func
execute p_target_func:0x702f7eaf9c70

确保程序能够正常执行后下面用AFL去Fuzz即可

./afl-fuzz -i mp4in/ -o mp4out -m 5000 -t 3000 -p exploit  -- ./loader /data/app/com.whatsapp-wMSOMeRwydbzJJmi-G1wEw==/lib/x86_64/libwhatsapp.so @@

总结

本章介绍了各种Fuzz技术并介绍了一些优化Fuzz测试的方法,为了能够熟练使用各种Fuzz技术,读者需要多实践并且要多看看Fuzz工具的源代码。Fuzz测试并不是单纯的启动Fuzz工具让Fuzz工具执行就可以的,在Fuzz的过程中测试人员需要不断地查看Fuzz的状态,一般而言Fuzz的流程如下

  1. 确定并分析Fuzz目标。
  2. 初步运行Fuzz工具保证能够正常开始Fuzz。
  3. 收集大量初始用例并对初始用例去重。
  4. 用去重后的初始用例开始Fuzz。
  5. 在Fuzz过程中当代码覆盖率长时间没有增长时,人工介入分析代码覆盖率,想办法提升代码覆盖率。
  6. 对发现的Crash去重。

最后祝读者能够挖到更多的漏洞。

AFL-QBDI与AFL-Unicorn实战的更多相关文章

  1. fuzz系列之afl

    afl 实战 前言 像 libFuzzer, afl 这类 fuzz 对于 从文件 或者 标准输入 获取输入的程序都能进行很好的 fuzz, 但是对于基于网络的程序来说就不是那么方便了. 这篇文章介绍 ...

  2. 基于qemu和unicorn的Fuzz技术分析

    前言 本文主要介绍如果使用 qemu 和 unicorn 来搜集程序执行的覆盖率信息以及如何把搜集到的覆盖率信息反馈到 fuzzer 中辅助 fuzz 的进行. AFL Fork Server 为了后 ...

  3. SAP ABAP RFC接口通用日志工具:abap fm logger

    很早之前就想写个能记录函数模块日志的通用工具,最早尝试时,没有想清楚插入代码的体积问题.在一些群友的提醒下,了解到可以用宏来处理这一问题.不过当时比较忙,就没有动笔.最近又想起这件事,花了2天完成了一 ...

  4. AFL++初探-手把手Fuzz一个PDF解析器

    CVE-2019-13288 目前漏洞在正式版本已经被修复,本文章仅供学习Fuzz过程,不存在漏洞利用的内容 这是一个pdf查看器的漏洞,可能通过精心制作的文件导致无限递归,由于程序中每个被调用的函数 ...

  5. 【EMV L2】GPO响应以及AIP、AFL

    [GPO命令] 终端通过GPO(Get Processing Options)命令 通知卡片交易开始.命令数据为PDOL指定的终端数据. [GPO响应] 卡片在GPO命令的响应中返回AIP和AFL:A ...

  6. afl入门学习

    一个简单的示例 安装afl wget http://lcamtuf.coredump.cx/afl.tgz tar xfz afl.tgz cd afl-xxx sudo make install 用 ...

  7. ref:Adding AFL Bloom Filter to Domato for Fun

    ref:https://www.sigpwn.io/blog/2018/5/13/adding-afl-bloom-filter-to-domato-for-fun Adding AFL Bloom ...

  8. AFL Fuzz安装及完成一次简单的模糊测试

    关于AFL fuzz AFL fuzz是一个模糊测试工具,它封装了一个GCC/CLang编译器,用于对被测代码重新编译的过程中进行插桩.插桩完毕后,AFL fuzz就可以给其编译过的代码输入不同的参数 ...

  9. AFL++ Fuzz一个libexif例子

    CVE-2009-3895 首先在NVD找到漏洞描述如下: 大致意思是说:libexif 0.6.18 中的 libexif/exif-entry.c 中的 exif_entry_fix 函数中基于堆 ...

  10. fuzz——AFL基础使用方法

    最近打 ctf 的时候感觉有点遇到瓶颈,就来 fuzz 这块看看. AFL 全称为 American huzzy loop,是 Fuzzing 最高级的测试工具之一.这个工具对有源码和无源码的二进制程 ...

随机推荐

  1. socket close和shutdown的区别,TIME_WAIT和CLOSE_WAIT

    TCP主动关闭连接 appl: close(), --> FIN FIN_WAIT_1 //主动关闭socket方,调用close关闭socket,发FIN               < ...

  2. 15. 序列化模块json和pickle、os模块

    1. 序列化模块 1.1 序列化与反序列化 (1)序列化 将原本的python数据类型字典.列表.元组 转换成json格式字符串的过程就叫序列化 (2)反序列化 将json格式字符串转换成python ...

  3. map&unordered_map<key,value>key使用自定义类的要求

    std::unordered_map 的键要求: std::unordered_map 是基于哈希表的数据结构. 它要求键类型必须支持哈希计算,也就是必须有对应的 std::hash 函数. 另外,键 ...

  4. HOG算法的笔记与python实现

    这两篇[1][2]博客写的都非常详细.这里做个笔记记录一下. HOG称为方向梯度直方图(Histogram of Oriented Gradient),主要是为了对图像进行特征提取.所以在传统目标检测 ...

  5. 深度学习卷积、全连接层、深度可分离层参数量和FLOPs计算公式

    来源 卷积: 输入尺寸  ,卷积核的大小为  * ,输出的尺寸大小为  参数量 (1)不考虑bias:(2)考虑bias: FLOPs (1)不考虑bias 解释:先计算输出的中一个元素需要的计算量, ...

  6. 关于CycleGAN损失函数的可视化理解

    看了<Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks>这篇论文,大致了解了C ...

  7. 三维医学图像数据扩充:flip and rotate

    对于小数据量医学图像进行深度学习使,会由于数据量过小而过拟合.因此我们需要采用数据扩充方法,而flip和rotate又是经常用到的,这里做一个简单的实现. 输入为[batchsize,height, ...

  8. 13. 说一下$set,用在Vue2还是Vue3

    $set 是 vue2 中对象用来追加响应式数据的方法 : 使用格式 : $set(对象 , 属性名 , 值 ) vue3中使用 proxy 替代了 Object.defineProperty 实现对 ...

  9. Android复习(五)设备兼容—>支持刘海屏

    支持刘海屏 刘海屏是指某些设备显示屏上的一个区域延伸到显示面,这样既能为用户提供全面屏体验,又能为设备正面的重要传感器留出空间.Android 在搭载 Android 9(API 级别 28)及更高版 ...

  10. manim边做边学--直角平面

    直角平面NumberPlane是Manim库中用于创建二维坐标平面的对象,它可以帮助用户在场景中可视化坐标轴以及网格线. 通过坐标轴.网格线以及刻度,它能够动态地展示函数曲线.几何图形以及它们的变换过 ...