运用AFL对Linux内核Fuzzing的总结 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

运用AFL对Linux内核Fuzzing的总结

申博_新闻事件 申博 49次浏览 已收录 0个评论

云端数据提取的发展历程

在iOS取证中,当无法进行物理采集时,云端数据提取确实是一种可行的替代方案。在即将发布的iOS 13版本中,苹果攻击附加了额外的安全措施,无疑将使物理访问变得更加困难。虽然下载iCloud备份的能力已经被很多人掌握了,但对于如何获取用户登录名和密码以及双因素身份验证,很多人是无法逾越这个门槛的。 早在2014年,就有研究人员介绍了如何使用身份验证令牌来访问没

隐约测试是现在最经常运用的破绽发掘手艺,Fuzzer将半随机输入喂到到测试顺序,目的是找到触发毛病的输入。隐约测试在查找C或C ++顺序中的内存破坏破绽时迥殊有用。

一般情况下,发起挑选一个尽人皆知但很少探究的库,这个库在剖析时很重要。汗青上,像libjpeg,libpng和libyaml如许的东西都是圆满的目的。现在找到一个好目的更难 – 统统好像都已被隐约化了。这是功德!我猜软件愈来愈好了!我没有挑选用户空间目的,而是挑选了Linux内核netlink机械。

Netlink是一个Linux内核东西,它用于设置收集接口,IP地点,路由表等。这是一个很好的fuzzing 目的:它是内核的一个小模块,而且天生畸形有用音讯相对比较轻易。最重要的是,我们可以在此过程当中学到许多关于Linux内核的学问。

在这篇文章中,我将运用AFL隐约器,将netlink shim顺序与自定义Linux内核相对应,一切这些都在KVM虚拟机中运转。

汗青上的内核Fuzzing手艺

我们将要运用的手艺被称为“掩盖指导隐约测试”。有许多之前的文献:

· Dan Guido 的智能隐约反动,以及LWN关于它的文章

· Mateusz“j00ru”Jurczyk的有用文件花样隐约测试

· honggfuzz是一个现代化的,功用雄厚的掩盖面指导的fuzzer

· ClusterFuzz

· Fuzzer测试套件

许多人过去都在Fuzzing Linux内核:

· 由Dmitry Vyukov 建立的syzkaller(别名syzbot)是一个异常壮大的CI作风的延续运转的内核隐约器,它已发现了数百个破绽。

· 三位一体的隐约器

我们将运用AFL,多是人人最喜欢的隐约器。AFL由MichałZalewski撰写。它以其易用性,速率和异常好的变异逻辑而著名,这是最先隐约测试之旅的圆满挑选!

假如您想相识有关AFL的更多信息,请参阅几个文件:

· 汗青笔记

· 手艺白皮书

· 自述

掩盖指导的隐约测试

掩盖指导的隐约测试基于反应回路的道理:

· 隐约测试挑选最有愿望的测试用例

· 隐约测试将测试变成大批新的测试用例

· 目的代码运转变异的测试用例,并报告代码掩盖率

· 隐约器依据报告的掩盖局限盘算得分,并运用它来肯定有用的变异测试的优先级并删除冗余的测试

比方,假定输入测试是“hello”。Fuzzer可能会将其变成多种测试,比方:“hEllo”(位翻转),“hXello”(字节插进去),“hllo”(字节删除)。假如这些测试中的任何一个将发生风趣的代码掩盖,那末它将被优先化并用作下一次测试的基础。

有关怎样完成突变以及怎样有用地比较数千个顺序运转的代码掩盖率报告的细节是隐约测试的窍门,浏览AFL的手艺白皮书,可以相识更多细节。

一般,在运用AFL时,我们须要检测目的代码,以便以AFL兼容的体式格局报告掩盖局限。但我们想要Fuzzing 内核!我们不能只用“afl-gcc”从新编译它!。我们将预备一个二进制文件,让AFL以为它是用它的东西编译的。这个二进制文件将报告从内核中提取的代码掩盖率。

内核代码掩盖率

内核至少有两个内置的掩盖机制–GCOV和KCOV:

· 将gcov与Linux内核一同运用

· KCOV:隐约测试的代码掩盖率

KCOV的设想斟酌了隐约测试,因而我们将运用它。

运用KCOV异常简朴。我们必需运用准确的设置编译Linux内核。起首,启用KCOV内核设置选项:

 cd linux
 ./scripts/config \
     -e KCOV \
     -d KCOV_INSTRUMENT_ALL

KCOV可以纪录全部内核的代码掩盖率。可以运用KCOV_INSTRUMENT_ALL选项举行设置。有个瑕玷是,它会减慢我们不想剖析的内核部份,而且会在Fuzzing 中引入噪声(下降“稳定性”)。关于初学者,让我们禁用KCOV_INSTRUMENT_ALL并有挑选地在现实想要剖析的代码上启用KCOV。

我们专注于Fuzzing netlink,所以在全部“net”目次树上启用KCOV:

 find net -name Makefile | xargs -L1 -I {} bash -c 'echo "KCOV_INSTRUMENT := y" >> {}'

在一个抱负环境中,我们只能为真正感兴趣的几个文件启用KCOV。然则netlink处置惩罚普及全部收集客栈代码,现在没有时候举行微调。

有了KCOV,将增添报告内存破坏毛病的可能性。最重要的是KASAN,运用该鸠合,可以编译我们的KCOV和KASAN启用的内核。

我们将以kvm运转内核,所以须要切换一下:

 ./scripts/config \
     -e VIRTIO -e VIRTIO_PCI -e NET_9P -e NET_9P_VIRTIO -e 9P_FS \
     -e VIRTIO_NET -e VIRTIO_CONSOLE  -e DEVTMPFS ...

怎样运用KCOV

新WhiteShadow下载器用Microsoft SQL提取歹意软件

攻击活动分析 2019年8月,Proofpoint研究人员发现了一系列的传播含有WhiteShadow下载器VB宏的word和Excel附件的恶意邮件活动。 图1: AWhiteShadow攻击活动中的恶意邮件 WhiteShadow是一种恶意软件交付服务,其中包含Microsoft SQL Server实例来保存下载器提取的主机payload。 下面是攻击活动的概览: 表 1: WhiteShadow攻击活动2019年8月和9月的顺序表 下载器分析 WhiteShadow用SQLOLEDB连接器来连接远程Microsoft SQL Server服务器实例,执行查询,并将

KCOV异常轻易上手。代码掩盖率会纪录在每一个历程的数据结构中,就是说必需在用户空间历程中启用和禁用KCOV,而且没法纪录非使命事项的掩盖局限,比方最常见的中缀处置惩罚。

KCOV将数据发送到缓冲区,然后就可以运用一个简朴的ioctl启用&禁用它:

 ioctl(kcov_fd, KCOV_ENABLE, KCOV_TRACE_PC);
 /* profiled code */
 ioctl(kcov_fd, KCOV_DISABLE, 0);

缓冲区会包括启用KCOV内核代码的一切基础块的%rip值列表。

要读取缓冲区,运转以下代码:

 n = __atomic_load_n(&kcov_ring[0], __ATOMIC_RELAXED);
 for (i = 0; i < n; i++) {
     printf("0x%lx\n", kcov_ring[i + 1]);
 }

运用addr2line东西可以将%rip剖析为特定的代码行。

将KCOV喂到AFL中

AFL须要一个特制的可执行文件,但我们想要晓得内核代码掩盖率。我们先相识一下AFL的事情道理。

AFL设置一个64K 8位数字的数组。该存储器地区称为“shared_mem”或“trace_bits”,并与trace的顺序同享这块存储地区。数组中的每一个字节都可以被以为是检测代码中特定对(branch_src,branch_dst)的掷中计数器。

AFL更更多的是运用随机分支,而不是重用%rip值来辨认基础块,重要是为了增添熵,我们愿望数组中的掷中计数器均匀分布。

AFL运用的算法以下:

 cur_location = <COMPILE_TIME_RANDOM>;
 shared_mem[cur_location ^ prev_location]++; 
 prev_location = cur_location >> 1;

在运用KCOV的情况下,没有每一个分支的编译时随机值。然则,我们可以运用哈希函数从KCOV纪录的%rip天生一致的16位数。

下面代码显现了怎样将KCOV报告提供给AFL“shared_mem”数组:

 n = __atomic_load_n(&kcov_ring[0], __ATOMIC_RELAXED);
 uint16_t prev_location = 0;
 for (i = 0; i < n; i++) {
         uint16_t cur_location = hash_function(kcov_ring[i + 1]);
         shared_mem[cur_location ^ prev_location]++;
         prev_location = cur_location >> 1;
 }

从AFL读取测试数据

现在须要现实编写中心netlink接口的测试代码!起首,我们须要从AFL读取输入数据。默许情况下,AFL将测试用例发送到stdin:

 /* read AFL test data */
 char buf[512*1024];
 int buf_len = read(0, buf, sizeof(buf));

Fuzzing netlink

然后我们须要将此缓冲区发送到netlink套接字,运用前5个字节的输入作为netlink协媾和组ID字段。这将许可AFL找出并猜想这些字段的准确值。

netlink测试代码(简化):

netlink_fd = socket(AF_NETLINK, SOCK_RAW | SOCK_NONBLOCK, buf[0]); struct sockaddr_nl sa = {         .nl_family = AF_NETLINK,         .nl_groups = (buf[1] <<24) | (buf[2]<<16) | (buf[3]<<8) | buf[4], }; bind(netlink_fd, (struct sockaddr *) &sa, sizeof(sa)); struct iovec iov = { &buf[5], buf_len - 5 }; struct sockaddr_nl sax = {       .nl_family = AF_NETLINK, }; struct msghdr msg = { &sax, sizeof(sax), &iov, 1, NULL, 0, 0 }; r = sendmsg(netlink_fd, &msg, 0); if (r != -1) {       /* sendmsg succeeded! great I guess... */ }

为了提拔Fuzzing速率,我们将它包装在一个模拟AFL“fork服务器”逻辑的短循环中。

AFL-to-KCOV的效果代码以下所示:

forksrv_welcome(); while(1) {     forksrv_cycle();     test_data = afl_read_input();     kcov_enable();     /* netlink magic */     kcov_disable();     /* fill in shared_map with tuples recorded by kcov */     if (new_crash_in_dmesg) {          forksrv_status(1);     } else {          forksrv_status(0);     } }

检察完整的源代码

运转自定义内核

怎样现实运转构建的自定义内核。有三种挑选:

“native”:您以在服务器上完整启动构建的内核并在本机Fuzzing它。这类要领速率很快,但也很有题目。假如Fuzzing胜利找到了crash,电脑可能会蓝屏崩溃,可能会丧失测试数据。

“uml”:可以将内核设置为以用户形式运转。运转UML内核不须要任何权限,内核只运转用户空间历程。UML有一个题目是,它不支撑KASAN,因而关于内存破坏破绽的发掘就那末有用了。

“kvm”:可以运用kvm在虚拟机环境中运转自定义内核,这就是我们要做的。

在KVM环境中运转自定义内核的最简朴要领之一是运用“virtme”剧本。有了它们,我们可以防止建立专用的磁盘映像或分区,只需同享主机文件体系。

这就是我们运转代码的体式格局:

virtme-run \     --kimg bzImage \     --rw --pwd --memory 512M \     --script-sh "<what to run inside kvm>"

构建输入语料库

每一个Fuzzer都须要精心设想的测试用例作为输入,以指导使顺序发生突变输出。测试用例应当简短,并尽量掩盖大部份代码。

这是我们的输入语料库:

mkdir inp echo "hello world" > inp/01.txt

怎样编译和运转的申明都在我们的github上的README.md中。

virtme-run \     --kimg bzImage \     --rw --pwd --memory 512M \     --script-sh "./afl-fuzz -i inp -o out -- fuzznetlink"

运转后,AFL就最先Fuzzing了:

运用AFL对Linux内核Fuzzing的总结

总结

在这篇文章中我们没有提到:

· AFL shared_memory设置的详细信息

· 运转AFL耐久形式

· 关于怎样读取dmesg(/ dev / kmsg)以查找内核crash的技能

· 在KVM以外运转AFL,以取得速率和稳定性

然则完成了我们的目的,我们针对内核建立了一个基础但仍然有用的Fuzzer。最重要的是:可以重复运用雷同的机制来Fuzzing Linux子体系的其他部份,比方从文件体系到bpf考证顺序。

我有一些感悟:准确的隐约测试相对不是启动Fuzzer后无所作为地守候崩溃。总有一些东西须要革新,调解和从新完成。Mateusz Jurczyk在之前演讲开首的一句话引起了我的共识:“Fuzzing很轻易学,但很难控制。”

本文翻译自: https://blog.cloudflare.com/a-gentle-introduction-to-linux-kernel-fuzzing/


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明运用AFL对Linux内核Fuzzing的总结
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址