在youtube和国外论坛上看到了一种比较有趣的使用fuzzing实现反调试的思路。
方法的原理很简单,通过循环修改源文件的一个byte使得该文件正常共能能够实现,但是能够对gdb和radare2这类调试软件进行一定程度上的干扰。通过实验之后发现,该方法不一定适合实战,但是可能会在对于反调试这一部分开拓新思路上面会有所帮助。
首先使用C语言写一个类似于Crackme的简单小程序:
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
if(argc==2)
{
if (strcmp("CORRECT_SERIAL", argv[1])==0)
{
printf("Accessed!\n");
}
else
{
printf("Denied!\n");
}
}
else
{
printf("Usage %s [serial_number]\n", argv[0]);
}
}
然后写一个python脚本自动实现上述的通过fuzzing进行反调试的实验
源代码:
#/bin/python3!
import os
import random
def alter_byte(bytes_in):
i = random.randint(0, len(bytes_in))
c = chr(random.randint(0,255))
return bytes_in[:i] + c.encode()+ bytes_in[i+1:]
def alter_file():
with open("secret", 'rb') as f_obj, open("secret_tmp", 'wb') as new_f:
f_content = f_obj.read()
new_content = alter_byte(f_content)
new_f.write(new_content)
def cmp_out_file(f_1, f_2):
with open(f_1, 'rb') as f_1_obj, open(f_2, 'rb') as f_2_obj:
return f_1_obj.read() == f_2_obj.read()
def check_normal():
cmd = "(./secret_tmp; ./secret_tmp CORRECT_SERIAL; ./secret_tmp WRONG_SERIAL) > normal_tmp.txt"
os.system(cmd)
return cmp_out_file("std_output.txt", "normal_tmp.txt")
def check_gdb():
os.system("echo disassemble main | gdb secret_tmp > gdb_tmp.txt")
return cmp_out_file("gdb.txt", "gdb_tmp.txt")
def check_r2():
os.system("echo 'aaa\rs main\rpdf' | radare2 secret_tmp > r2_tmp.txt")
return cmp_out_file("r2_tmp.txt", "r2.txt")
if __name__ == '__main__':
os.system("cp secret secret_tmp")
os.system("echo disassemble main | gdb secret_tmp > gdb.txt")
os.system("(./secret_tmp; ./secret_tmp CORRECT_SERIAL; ./secret_tmp WRONG_SERIAL) > std_output.txt")
os.system("echo 'aaa\rs main\rpdf' | radare2 secret_tmp > r2.txt")
while True:
alter_file()
if check_normal() and not check_gdb() and not check_r2():
print("************* Found possible solution ************")
os.system("rm gdb.txt r2_tmp.txt r2.txt gdb_tmp.txt normal_tmp.txt std_output.txt")
exit()
这段代码主要实现了在程序功能正常的情况下对 radare2 和 gdb的实现反调试的功能。
因为Crackme程序中只有一个main函数,所以check_r2()函数主要是要能对main函数进行一定的干扰。
运行程序之后会生成一个secret_tmp的二进制文件。
下面是几组在fuzzing之前和之后的对比。
1. fuzzing前后直接运行对比:
修改后的文件都能够正常实现应有的功能。
2. fuzzing前后gdb调试对比:
源文件gdb调试:
修改后gdb调试:
3. fuzzing前后radare2 调试对比:
源文件:
源文件disassemble函数表
源文件main函数disassembling
修改后:
修改后文件disassemble函数表
修改后main函数disassembling
对比前后可发现,修改后的文件不太能被反汇编,并且会显示不可识别文件。radare2还能够进行反汇编,但是函数列表基本除了main不可读。内部函数也看不出调用了printf和strcmp等libc函数。通过ltrace也不太能发现libc函数调用记录:
总结:
总的来说这是个很有意思的过程,单纯的整个过程可能对于实际来说并没有很大的帮助,但是是个很有趣的思路,或许经过多次实验通过一些统计可能会发现一些有趣的现象,比如可以对一个指定区域的二进制内容范围进行fuzzing,或许能够发现一些有趣的内容。
原文作者:逆向实习生
原文链接:https://bbs.pediy.com/thread-248834.htm
转载请注明:转自看雪学院
更多阅读:
网友评论