参考 liveoverflow Parser Differential
fuzz思路
链接
目标程序
源码
测试
复制target fuzz
保存输出
normal_execute
gdb_debug
radare_debug
编写fuzz脚本
思路
我们试图根据不同的PE文件parser解析器的差异 产生不同输出, 目的找到一个pe文件可以被linux PE加载器正常执行,但是在gdb 以及 radare里解析失败 从而实现反调试目的 Parser Differential
- 随机更改pe文件的某一处字节
- 检查是否 正常执行及gdb,radare里输出结果存在差异
- 如若可以在正常执行结果一致,而gdb和radare产生错误 fuzz成功
fuzz.py
import random
import os
def flip_byte(buff):
pos = random.randint(0,len(buff))
li = []
li.append(random.randint(0,0xff))
return buff[:pos] + bytes(li) + buff[pos+1:]
def copy_binary():
os.system('cp mylogin mylogin_fuzz')
with open('mylogin','rb') as orig_f, open('mylogin_fuzz','wb') as new_f:
new_f.write(flip_byte(orig_f.read()))
def compare(fn1,fn2):
with open(fn1) as f1, open(fn2) as f2:
return f1.read() == f2.read()
def compare_radare(fn1,fn2):
with open(fn1,'r') as f1, open(fn2,'r') as f2:
return f1.readlines()[1:] == f2.readlines()[1:]
def check_output():
os.system('(./mylogin_fuzz ; ./mylogin_fuzz correct_passwd) > fuzz_output')
return compare('orig_output','fuzz_output')
def check_gdb():
os.system('echo disassemble main | gdb mylogin_fuzz > fuzz_gdb')
return compare('orig_gdb','fuzz_gdb')
def check_radare():
os.system('echo "aaa\ns sym.main\npdf\nq" | radare2 mylogin_fuzz > fuzz_radare')
return compare_radare('orig_radare','fuzz_radare')
while True:
copy_binary()
if check_output() and not check_gdb() and not check_radare():
print('Found Possible sample\n\n\n')
os.system('tail fuzz_gdb')
os.system('tail fuzz_radare')
input()
执行
find possible sample
验证
normal_execute
-
mylogin
-
mylogin_fuzz
可以看到 fuzz后的样本可以正常地被linux执行 结果没有差异 符合预期
gdb
-
mylogin
-
mylogin_fuzz
可以看到 fuzz后的样本成功阻止了gdb调试 符合预期
radare
-
mylogin
-
mylogin_fuzz
可以看到 fuzz后的程序 radare已经无法识别main函数 符合预期
Binary compare
可以清楚看到 仅仅更改一个字节 就做到了anti_gdb ant_radare的作用
总结
fuzz过程踩坑
- python 内 os.system() 执行echo 默认附带 -e 参数,如果添加-e 会出错
- 由于python3 bytes类型和str分离 需要int转bytes 我使用单元素列表作为构造
- radare 新版本会在启动时随机产生一句玩梗的话(歪果仁玩的梗 Get不到hhh) 这样就会影响输出 所以单独compare radare 从第一句之后比较
思考
- 万物皆可fuzz(雾
- 以往特征码免杀 分块逐步定位 手动修改, 是不是可以用fuzz 智能化?
- fuzz结果不唯一 实际上很多可行解 怎样添加约束 使得结果更加安全?
- 不同的逆向工具 parser 存在差异 针对parser 主动攻击效果不错, 联想到OD的PE解析器 加载时没有对错误的一个字段做处理 导致 pe头更改该字段时 会导致OD载入失败(已被strong OD修复)