AFL-forkserver

AFL-forkserver

forkserver

  • __afl_maybe_log 插装代码

  • __afl_setup

    如果没有设置共享内存:如果__afl_setup_failure的值不为0(0为正常,非零异常),通过getenv($SHM_ENV_VAR)环境变量来获得共享内存的ID,如果不为空就调用atoi以及shmat,最终将这个地址存储在__afl_area_ptr中方便之后使用(不必再初始化),下面启动fork_server

    • __afl_forkserver

      • 首先,通过写入状态管道,fork server会通知fuzzer,其已经准备完毕,可以开始fork了

      • 接下来,fork server进入等待状态__afl_fork_wait_loop,读取命令管道,直到fuzzer通知其开始fork

      • 一旦fork server接收到fuzzer的信息,便调用fork(),得到父进程和子进程:

          " call fork\n"
          "\n"
          " cmpl $0, %eax\n"
          " jl __afl_die\n"
          " je __afl_fork_resume\n"
        
        • 子进程是实际执行target的进程,其跳转到__afl_fork_resume。在这里会关闭不再需要的管道,并继续执行
        • 父进程则仍然作为fork server运行,其会将子进程的pid通过状态管道发送给fuzzer,并等待子进程执行完毕;一旦子进程执行完毕,则再通过状态管道,将其结束状态发送给fuzzer;之后再次进入等待状态__afl_fork_wait_loop
  • __afl_store

    ​ 这里首先把__afl_prev_loc(之前的位置)同当前位置的key异或,保存在edi寄存器,之后当前的key右移一位,作为下一个的__afl_prev_loc,这个右移是一个很巧妙的设计,如果代码块的跳转为A->BB->A,直接对两个Key异或结果是一样的,因此右移可以区分出一些特殊情况。下面那个incb代码中edx为map,edi为索引,即map表中对应的索引加一,表明一次hit。

Fuzz执行流程总结

​ 第一次的fuzz,核心函数为perform_dry_run,其功能是将给的所有测试用例跑一遍,确保软件如期工作,故只会跑一遍。需要说明的是这里的文件在初始的时候被抽象到一个自定义的结构体中,且组成了队列。在这个函数中核心的调用为res = calibrate_case(argv, q, use_mem, 0, 1);,之后对res判断确定程序的运行情况(crash or sth),拿翻译看下,这函数的意思是校准用例,看注释的话意思应该是在输入的时候进行测试,前期发现一些有问题的测试用例。应该一共跑个3次或者8次(取决于是否是快速模式),如果没启动forkserver那么在这用init_forkserver启动。

​ 然后直接就fork出子进程,为其设置一些资源,拷贝文件描述符,设置环境变量等,最终调用execv(target_path, argv);替换进程去执行Binary,由于execv正常是不会返回的,所以出错后后面会在共享内存那里设置一个EXEC_FAIL_SIG,通过对于管道文件的读取可以判断forkserver是否正常启动,这块就和之前插桩的代码联系了起来,判断方式是说如果正常操作会有一个4字节的Hello信息,确保启动正常就进入waitpid(forksrv_pid, &status, 0)的等待,后面对接收到的status进行判断确定子进程的运行状况。

​ 等启动forkserver完毕之后,又一个核心函数出现了,就是这里的run_target,这个函数在之后每次调用新的二进制程序的时候都会使用,其先检查有无启动forkserver,没有的话就先启动一个,否则我们只注重与forkserver的交互即可(使用ctl_fd写,st_fd读),因为 binary那边会一直返回子进程的进程号,所以一直等到结果为-1即可中止,最后拿classify_counts((u32*)trace_bits);将结果进行分类。 has_new_bits判断之前的测试有没有增加新的路径(二元的tuple),逻辑应该就是拿virgin_map这个map同trace_bits进行比较. update_bitmap_score这个函数很有意思,注释里说每当我们发现一个新的路径,都会调用这个函数来判断其是不是更加 favorable,这个favorable的意思是说是否包含最小的路径集合来遍历到所有bitmap中的位,我们专注于这些集合而忽略其他的。核心的比较方式是fav_factor = q->exec_us * q->len;即测试用例执行的时间以及输入长度的乘积,注释说希望找到更快或者规模更小的用例,一旦当前的fav_factor比top_rated[i]要小就会更新这个表,将原来的winner的tc_ref--,当前的插入表中。

  • perform_dry_run

    • calibrate_case(三个caller:fuzz_one、perform_dry_run、save_if_interesting)
      • init_forkserver
        • 调用fork,子进程执行 execv(target_path, argv);
  • cull_queue

​ 下面会调用cull_queue函数,函数前的注释说我们已经进入了第二个阶段,即用routine来遍历top_rated entry,不断寻找之前没见到过的bytes并且将它们标为favored。函数首先判断sore_changed是不是为真,之后拿贪心算法找能够遍历到所有节点的最小测试集合,比如有三个节点n0,n1,n2,n3和3个测试用例s1,s2,s3。top_rated[0]=s0,top_rated[s2]=s2s0覆盖n0,n1;s1覆盖n2其中初始化temp_v=[1,1,1,1],1就表示对应节点没有访问到,初始化为都没访问到。开始先判断temp_v[0]=1,说明没访问到,之后就去看top_rated[0],发现为1,说明存在一个用例能访问到这个n0,因此进一步查看这个用例,得到其覆盖范围trace_mini=[1,1,0]故据此更新temp_v=[0,0,1],往下看n1,访问过了,再看n2仍未访问到,再去看top_rated得到s2,再看s2的覆盖范围更新temp_v,就这样标注s0和s1为favored,如果他俩还没有被fuzz,还要pending_favored++。完成上述操作之后将无用的用例标为冗余。

​ 再往后就是一个大的循环,也是AFL最最核心的部分,循环开始依然是用cull_queue对队列进行筛选,如果一个cycle都没有新发现尝试更换策略,最终调用skipped_fuzz = fuzz_one(use_argv);这个函数里对测试用例做了变异,

详细参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268