我有一个程序可以处理一定大小的数据包,但需要大量数据包才能进行任何有意义的输出。
我目前通过从 AFL 接收数据包并在系统中运行它必要的次数来使用 AFL 模糊我的程序。
这并不理想,因为我多次重复使用相同的变形数据包,所以我切换到使用 AFL 的持久模式,它通过管道连续向我发送数据。
问题是,AFAICT,这种模式假设每个输入都是独立运行的,我想创建一个依赖于一系列输入的崩溃。
模糊我的程序的正确方法是什么?
我有一个程序可以处理一定大小的数据包,但需要大量数据包才能进行任何有意义的输出。
我目前通过从 AFL 接收数据包并在系统中运行它必要的次数来使用 AFL 模糊我的程序。
这并不理想,因为我多次重复使用相同的变形数据包,所以我切换到使用 AFL 的持久模式,它通过管道连续向我发送数据。
问题是,AFAICT,这种模式假设每个输入都是独立运行的,我想创建一个依赖于一系列输入的崩溃。
模糊我的程序的正确方法是什么?
您应该将从 AFL 接收到的数据作为数据包序列进行处理。这是 AFL 持久模式示例(已删除注释):
int main(int argc, char** argv) {
char buf[100];
while (__AFL_LOOP(1000)) {
memset(buf, 0, 100);
read(0, buf, 100);
if (buf[0] == 'f') {
printf("one\n");
if (buf[1] == 'o') {
printf("two\n");
if (buf[2] == 'o') {
printf("three\n");
if (buf[3] == '!') {
printf("four\n");
abort();
}
}
}
}
}
return 0;
}
您的案例的修改示例是:
//#define FIXED_PACKET_SIZE set to your packet size, assuming all packets have same size
//#define NUM_PACKETS_TO_RECEIVE set to number of packets you want to receive to get meaningfull output
int main(int argc, char** argv) {
char buf[FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE];
while (__AFL_LOOP(1000)) {
memset(buf, 0, FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE);
read(0, buf, FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE);
unsigned curPacket = 0;
while (curPacket < NUM_PACKETS_TO_RECEIVE) {
if (buf[curPacket*FIXED_PACKET_SIZE] == 'f') {
printf("one\n");
if (buf[curPacket*FIXED_PACKET_SIZE+1] == 'o') {
printf("two\n");
if (buf[curPacket*FIXED_PACKET_SIZE+2] == 'o') {
printf("three\n");
if (buf[curPacket*FIXED_PACKET_SIZE+3] == '!') {
printf("four\n");
abort();
}
}
}
}
curPacket ++;
}
}
return 0;
}
AFL 不适用于大输入大小 - 尝试修改所有位需要大量时间。当FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE
大时,您应该尽量不要将模糊数据用于数据包部分,这不太可能导致错误。
当 AFL 修改您的测试数据大小时,可能会出现另一个问题 - 它可以针对某些输入突变这样做。您的read
电话应处理这些情况。