(75) Hacking Livestream #17 Basics of fuzzing 1 - YouTube (在写..)

【带机翻字幕】

文件准备

首先看一段程序

# a.c > a.exe
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	if (argc != 2){
		return 1;
	}
	FILE *f = fopen(argv[1], "rb");
	if (f == NULL) {
		return 2;
	}
	int w, h;
	fread(&w, 4, 1, f);
	fread(&h, 4, 1, f);

	unsigned char *buf = malloc(w * h);

	for(int j=0; j<h ; j++){
		fread(&buf[j * w], w, 1, f);
	}

	fclose(f);
	return 0;
}
/*
# gcc 编译成32位的
gcc -m32 ./example.c ggdb

# 写测试文件
>>> import struct
>>> open("input.sample", "wb").write(struct.pack("II", 0xa, 0xa))
>>> open("input.sample", "ab").write(("A" * 10*10).encode("ascii"))

# 使用gdb调试
 */

编译后ida看无异

gdb 编译之后拖进ida看下有无优化
在这里插入图片描述

写python代码来随机输入

# https://www.youtube.com/watch?v=iTFmLJ4zn-E    42:09
# example.py
import subprocess
import random
import struct
import sys
import time

def load_file(fname):
	with open(fname, "rb") as f:
		return bytearray(f.read())

def save_file(fname, data):
	with open(fname, "wb") as f:
		f.write(str(data))

def mutate_bits(data):
	data = data[::]  # copy

	count = int((len(data) * 8) * 0.01)
	if count == 0:
		count = 1
	for _ in range(count):
		bit = random.randint(0, len(data)*8 -1 )
		idx_bit = bit % 8
		idx_byte = bit / 8
		data[idx_byte] ^= 1 << idx_bit
	return data


def mutate_bytes(data):
	count = int((len(data)) * 0.01)
	if count == 0:
		count = 1
	for _ in range(count):
		data[random.randint(0, len(data) - 1)] = random.randint(0, 255);
	return data

def mutate_magic(data):
	numbers = [
		(1, struct.pack("B", 0xff)), # malloc((unsigned char)(text_length + 1))
		(1, struct.pack("B", 0x7f)),
		(1, struct.pack("B", 0)),
		(2, struct.pack("H", 0xffff)),
		(2, struct.pack("H", 0)),
		(4, struct.pack("I", 0xffffffff)),
		(4, struct.pack("I", 0)),
		(4, struct.pack("I", 0x80000000)),    # INT_MIN / -1
		(4, struct.pack("I", 0x40000000)),
		(4, struct.pack("I", 0x7fffffff)),
	]

	count = int(len(data) * 0.01)
	if count == 0:
		count = 1
	for _ in range(count):
		n_size, n = random.choice(numbers)
		sz = len(data) - n_size
		if sz < 0:
			continue
		idx = random.randint(0, sz)
		data[idx:idx + n_size] = bytearray(n)

	return data

def mutate(data):
	return random.choice([
		mutate_bits, 
		mutate_bytes, 
		mutate_magic
	])(data[::])
	

def run(execname):
	subprocess.check_call([execname, "test.sample"])


input_samples = [
	load_file("input.sample")
	# , "zzzz"
]

# print(random.choice(input_samples))
# output:
# like this:
# 	bytearray(b'\n\x00\x00\x00\n\x00\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
# or:
# 	zzzz

i = 0

while True:
	i += 1
	if True:  # How many random produce one
		sys.stdout.write(".")
		sys.stdout.flush()

	mutated_sample = mutate( random.choice(input_samples) )
	save_file("test.sample", mutated_sample)

	try:
		run("a.exe")	# produce this one
	except subprocess.CalledProcessError:
		print "CRASH!"
		save_file("crash.samples.%i"%i , mutated_sample)  # when CRASH then save input file


执行 > python example.py

在这里插入图片描述
右边是随机生成出来的数据, 左边是我们的元数据(通过a.c里面的命令生成的正常数据)
0000000a * 4000000a 很明显他会溢出

修改代码, 用gdb script附加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值