首页
社区
课程
招聘
[原创]手写fuzzer实现anti-debugging趣味实验 XD
发表于: 2019-1-6 14:05 8216

[原创]手写fuzzer实现anti-debugging趣味实验 XD

2019-1-6 14:05
8216

#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,或许能够发现一些有趣的内容。



#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()
#/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调试:



[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-1-6 15:25 被逆向实习生编辑 ,原因: 修改显示
收藏
免费 1
支持
分享
最新回复 (16)
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
2
哎。。咋回事儿。。。发了第二遍 还是显示不出来。。
2019-1-6 14:07
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
3
求删掉把。。
2019-1-6 14:07
0
雪    币: 23080
活跃值: (3432)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
4
是不是从word复制的?如果是的话建议纯文本粘贴,然后重新排版
2019-1-6 14:13
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
5
KevinsBobo 是不是从word复制的?如果是的话建议纯文本粘贴,然后重新排版
不是从word复制的,是复制的纯文字,然后插的图片
2019-1-6 14:15
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
6
KevinsBobo 是不是从word复制的?如果是的话建议纯文本粘贴,然后重新排版
我之前发都没问题,不知道这次咋回事,点击编辑还能看到写的内容,但就是显示不出来。我换了哥电脑和浏览器,关掉插件再尝试一次。
2019-1-6 14:16
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
7
KevinsBobo 是不是从word复制的?如果是的话建议纯文本粘贴,然后重新排版
就是显示不出来,点击编辑里面是有内容的:

2019-1-6 14:22
0
雪    币: 23080
活跃值: (3432)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
8
已经反馈给段老大,正在排查问题,稍等
2019-1-6 14:41
0
雪    币: 47147
活跃值: (20445)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
9
论坛为了安全性,对显示内容过滤所至。
现在这帖可以显示了,若你要编辑内容,编辑完留言我一下,我再恢复出来。
最后于 2019-1-6 15:27 被kanxue编辑 ,原因:
2019-1-6 15:07
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
10
kanxue 论坛为了安全必,对显示内容过滤所至。 现在这帖可以显示了,若你要编辑内容,编辑完留言我一下,我再恢复出来。
已经编辑完成
2019-1-6 15:25
0
雪    币: 29
活跃值: (295)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
挺好玩的  感谢分享
2019-1-7 00:04
0
雪    币: 128
活跃值: (694)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
国外论坛网址分享下被
2019-1-9 17:03
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
13
书生怕怕 国外论坛网址分享下被
Youtube: https://www.youtube.com/watch?v=OZvc-c1OLnM&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&index=10&t=0s
LiveOverflow 的视频 无论对新手还是进阶都很友好。总有有意思的东西可以学习。
2019-1-18 03:19
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
此贴必火,火钳刘明, 1024
2019-1-27 12:57
0
雪    币: 83
活跃值: (1087)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
15
没看懂 啥意思  打开程序 再开个反调试的脚本 不断地对程序内存修改一个字节?
2019-2-9 11:01
0
雪    币: 1563
活跃值: (272)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
16
killpy 没看懂 啥意思 打开程序 再开个反调试的脚本 不断地对程序内存修改一个字节?
不用打开程序,直接运行脚本,每次循环会复制一次要被修改的程序,并且对复制的程序任意修改一个字节,然后检测能否被gdb和r2正常打开调试。
2019-2-9 12:04
0
雪    币: 83
活跃值: (1087)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
gdb r2是静态调试吗 复制程序是啥意思
2019-2-11 08:11
0
游客
登录 | 注册 方可回帖
返回
//