StateAFL demo复现
1.概述
论文地址:https://arxiv.org/abs/2110.06253
源码地址:https://github.com/stateafl/stateafl
配置:VMware Pro 16.0 Ubuntu Linux 18.04
StateAFL在AFLNET的基础上,采用更细粒度的状态表示:通过插桩的方式转储网络应用程序的长生命周期的变量,并计算其散列值作为状态ID。
stateafl在服务器编译时,向内存分配和I/O操作插入探针。
在服务器运行时,它通过拍摄长生命周期内存区域的快照,并通过应用模糊哈希算法(局部敏感哈希)将内存内容映射到唯一的状态标识符,来推断目标服务器的当前协议状态。
文章在2020年发表,在2022年进行了修订
2.复现
2.1环境搭建
#安装clang sudo apt-get install clang #安装graphviz——图可视化工具 sudo apt-get install graphviz-dev #安装wireshark,tshark sudo apt-get install wireshark sudo apt-get install tshark
虚拟机默认安装tshark为2.6.7版本,2.x足够运行测试。
2.2安装StateAFL
git clone https://github.com/stateafl/stateafl
cd stateafl
make clean all
cd llvm_mode
make
在官方解释中,这里执行make后可能会出错(比如我),出错如下图:
问题描述是:如果无法找到llvm-config,下面的make命令可能无法工作
官方给出的解决方法是:在Ubuntu 18.04上,如果你使用apt-get安装clang,它可能是llvm-config-6.0,因此只需设置LLVM_CONFIG env。变量设置为机器上特定的llvm-config版本
export $LLVM_CONFIG=/usr/bin/llvm-config-6.0
之后再次执行make即可成功
2.3安装LightFTP
安装依赖
sudo apt install build-essential sudo apt install gnutls-dev sudo apt install libgnutls28-dev sudo apt install libgnutls-dev
安装LightFTP
git clone https://github.com/hfiref0x/LightFTP
在aflnet源码中,lightftp使用了5980ea1版本
#进入克隆下来的LightFTP文件里
cd LightFTP
#转向特定版本
git checkout 5980ea1
#安装补丁 patch -p1 < $AFLNET/tutorials/lightftp/5980ea1.patch
#编译源文件 cd Source/Release CC=afl-clang-fast make clean all
release下面多出来了fttp,这个是之后要用到的
#修改fftp.conf文件,因为默认主文件夹是/home/ubuntu,要修改为自己的默认主文件夹,笔者的是/home/linfg cd /Source/Release gedit fftp.conf #新建ftpshare文件夹 mkdir ~/ftpshare
3.测试
3.1前置工作
默认所处的为主文件夹/home/ubuntu,笔者的是/home/linfg。现在已经有了刚刚clone下来的stateafl和LightFTP文件夹
#创建文件夹 mkdir experiments #进入文件夹 cd experiments mkdir pcaps #复制字典 cd /home/linfg/stateafl/tutorials/lightftp chmod 777 ftp.dict cp ftp.dict /home/linfg/experiments
设置环境变量,StateaAFL官方和复现AFLNET的其他笔者都是设置了临时变量,即在终端直接export $xxxxxx=xxxxxx
由于这个新开的虚拟机只进行这一个实验,我在这里直接写入了/etc/profile,每次使用时source一下就可以了
vim /etc/profile
source /etc/profile
####还有一个我落下了,后来直接补充的临时变量####
export $WORKDIR=/home/linfg/experiments
3.2获取种子
默认所处的为主文件夹/home/ubuntu,笔者的是/home/linfg。
抓包
#使用tcpdump抓包 cd experimentssudo tcpdump -i lo -w pcaps/ftp.pcap port 2200
运行LightFTP服务器
cd .. cd LightFTP/Source/Release ./fftp fftp.conf 2200
连接FTP
cd /home/linfg/experiments ftp localhost 2200 #使用用户名为ubuntu,密码为ubuntu登陆 #输入如下命令测试 pwd mkdir TEST cd TEST pwd quit
由于我没有修改ftp的配置文件,所以登陆后没有权限mkdir,所以随便输入了一些命令如下
至此数据收集工作完毕,客户端、服务端、启动的tcpdump都可以停掉,此时/experiments/pcaps下会有抓包的数据
生成种子文件
#进入默认主文件 cd /home/linfg cd /experiments mkdir in-ftp-replay python3 $STATEAFL/convert-pcap-replay-format.py --input $WORKDIR/pcaps/ftp.pcap --server-port 2200 --output $WORKDIR/in-ftp-replay/ftp.replay
StateAFL以“replayable”格式接收输入种子文件。它是一种简单的格式,在AFLNet中也用于重放输入(即,保存在replayable-queue和输出文件夹中的replayable-crashes),使用命令AFLNet -replay。
这种格式交替使用消息的大小(4字节,unsigned int)和消息的内容。官方配图如下:
hexdump -C in-ftp-replay/ftp.replay
3.3模糊测试
cd LightFTP cd/Source/Release make clean
编译
CC=${STATEAFL}/afl-clang-fast make clean all -j3
模糊测试
${STATEAFL}/afl-fuzz -d -i ${WORKDIR}/in-ftp-replay -x ${WORKDIR}/ftp.dict -o ${WORKDIR}/output -N tcp://127.0.0.1/2200 -D 10000 -q 3 -s 3 -E -K -m none -t 5000 -c ${WORKDIR}/ftpclean -u ${WORKDIR}/LightFTP/Source/Release/fftp -- ./fftp fftp.conf 2200
3.4绘制状态机
watch -n 1 'cat $WORKDIR/output/ipsm.dot | graph-easy --from=dot --as_ascii 2>/dev/null'
4.报错总结
4.1......
在3.2中使用python3生成种子时,出现如下错误:
没有pychark包,这种情况下直接用pip3补上就行,但别用pip,否则就是给python2装的了
#下载pip3 apt-get install python3-pip #默认pip3为9.x版本,更新后变为21.x版本 pip3 install --upgrade pip #安装pyshark pip3 install pyshark
4.2......
ASLR没有关闭
ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的的一种技术
运行如下命令关闭
echo 0 > /proc/sys/kernel/randomize_va_space
4.3.....
重启之后,执行afl-fuzz会出现-N无效,且使用afl-fuzz --help查看没有aflnet的选项,且又使用make重新安装了一下AFLNET/StateAFL之后,再使用afl-fuzz --help依旧没有输出aflnet的选项。
可能是因为没有将AFLNET/StateAFL加入环境变量path