ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用AFL对libmodbus进行fuzz测试

2021-07-12 14:02:02  阅读:424  来源: 互联网

标签:AFL afl libmodbus socket 编译 fuzz 测试 测试用例


目录

下载编译libmodbus

首先在github上下载libmodbus库的源码

git clone https://github.com/stephane/libmodbus/

下载好之后进入到文件夹中,在编译过程中选择使用afl-gcc而不是默认的gcc

cd libmodbus/
./autogen.sh
CC=afl-gcc CXX=afl-g++ 
./configure --enable-static
make -j8

这里在我第一次运行./autogen.sh时,报错提示autoreconf not found
在这里插入图片描述
查了一下README里面提示说需要autoconf和libtool,新装的虚拟机上好像没安装,装上之后问题就解决了,正常情况下运行autogen.sh后会有如下提示,最后会告诉你可以运行./configure了
在这里插入图片描述
另外注意在./configure之前一定要更改环境变量的CC和CXX为afl的编译器,以便对libmodbus进行插桩。
如果过程顺利,最终会看到如下图所示的界面,很多afl插桩提示
在这里插入图片描述

安装Preeny库

为什么需要Preeny

Modbus协议依托socket实现进程间的通信,而AFL本身并未提供对socket通信的支持。使用AFL对其进行fuzzing时,需要将其输入输出重定向stdio中。纵然可以修改部分代码使其socket通信转移到stdio,但这一过程可能会对fuzz的结果造成影响,同时工作量可能也较为繁杂。若是直接修改系统的socket.h,可能会对其他的程序造成难以估量的影响。
而Preeny提供了一系列有趣的模块,其中就包括了一个可以将socket通信重定向至console的desock模块。这个模块,原本的socket函数实现
在这里插入图片描述

安装Preeny的前置条件

在Preeny的README中,明确提示了preeny需要使用libini_config来实现相关功能,在安装preeny之前需要先装好,否则在make时会报错。
在这里插入图片描述
此外,在编译过程中还需要用到seccomp/h头文件,需要安装libseccomp

sudo apt-get install libseccomp-dev -y

编译安装

在满足了上述前置条件后,直接到preeny目录下make即可自动完成编译,编译过程中可能会有些warning,不影响正常功能。
安装成功后,可以在preeny目录下的src/中找到desock.so,可以通过一个简单的测试小程序确认desock模块是否正确工作

#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
        int sock;
        char send_buf[] = "hello, world! \n";
        char recv_buf[100] = {'\0'};
        sock = socket(AF_INET, SOCK_STREAM, 0);
        send(sock, send_buf, strlen(send_buf), 0);
        recv(sock, recv_buf, 100, 0);
        printf("The following msg is recvd:\n %s \n", recv_buf);
        return 0;
}

在这里插入图片描述
可以看到,send函数成功将消息发往了stdout,而recv函数也成功从stdin中接收了消息,说明本部分工作已经完成

创建测试程序与样例

编译测试程序

在libmodbus目录下有一个tests文件夹,包含几个官方提供的测试样例,可以通过afl-gcc对其进行插桩编译,作为被测程序。此处值得注意的是,在编译时要注意手动指定modbus库和头文件
如:

afl-gcc bandwidth-server-many-up.c -o server -I libmodbus/src/ libmodbus/src/.libs/libmodbus.a

-I后面两个参数分别指定了modbus.hlibmodbus.a的路径,两者缺一不可

生成测试用例

在AFL的文档中,建议为fuzzing测试提供一些“特别”(interesting)的测试用例作为种子。显然,如果直接用一串随机字母数字组合作为modbus测试程序的输入并不够interesting。好在libmodbus提供的测试用例中,random-test一对就可以为我们提供不错的测试数据,这是tests/README.md中对于他们的描述
在这里插入图片描述
在本地运行这一对程序,然后通过tcp将数据包保存至本地,然后再随机挑选几个数据包出来作为输入样例。

开始测试

使用afl-fuzz命令即可开始fuzzing测试,需要通过-i参数给出存放测试用例的目录 -o参数给出用于输出测试结果的目录,如果目录不为空会报错 最后直接给出被测程序的路径即可。
注意为了将socket输入输出重定向到stdio,我们需要在运行的同时指定LD_PRELOAD=desock.so。完成操作即如下所示:

LD_PRELOAD=./desock.so afl-fuzz -i inputs/ -o outputs/ ./server

关于测试用例

测试用例一次不要给太多,按照afl官方所给的建议(/usr/local/doc/afl/perf-tips.txt),第一条就指出要让测试用例尽量小。第一次没注意到这个问题,把抓到的近一千个包一口气全放到了测试用例目录中,结果如下图所示:
在这里插入图片描述
除了第一个case之外,后面的都提示“may be useless"
在这里插入图片描述

测试过程

正确配置各项参数后,AFL的运行界面如下:
在这里插入图片描述

测试结果

目前还没有对测试输出的结果进行分析,后续会通过一些小工具和辅助手段进行一些分析与改善测试,到时候来更新~

标签:AFL,afl,libmodbus,socket,编译,fuzz,测试,测试用例
来源: https://blog.csdn.net/qq_42768012/article/details/118567601

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有