/
fuzz.py
executable file
·129 lines (93 loc) · 3.16 KB
/
fuzz.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python
from ptrace.debugger.debugger import PtraceDebugger
from ptrace.debugger.child import createChild
from ptrace.tools import locateProgram
from ptrace.debugger.process import NewProcessEvent
from sys import stderr, argv, exit
from ptrace.binding import func as ptrace_bindings
def playWithProcess(process):
process.cont()
event = process.waitEvent()
def traceProgram(arguments):
# Copy the environment variables
env = None
# Get the full path of the program
arguments[0] = locateProgram(arguments[0])
# Create the child process
return createChild(arguments, False, env)
def allocateMemory(process):
syscall_opcode = "\xCD\x80"
mmap_syscall_nr = 192
eip = process.getreg("eip")
old_regs = process.getregs()
old_instrs = process.readBytes(eip, len(syscall_opcode))
process.writeBytes(eip, syscall_opcode)
process.setreg("eax", mmap_syscall_nr)
process.setreg("ebx", 0)
process.setreg("ecx", 0x2000)
process.setreg("edx", 0x3)
process.setreg("esi", 0x22)
process.setreg("edi", -1)
process.setreg("ebp", 0)
process.singleStep()
print process.waitEvent()
mem = process.getreg("eax")
process.setregs(old_regs)
process.setInstrPointer(eip)
process.writeBytes(eip, old_instrs)
print hex(mem)
return mem
def createCheckpoint(process):
syscall_opcode = "\xCD\x80"
fork_syscall_nr = 2
eip = process.getreg("eip")
old_eax = process.getreg("eax")
old_instrs = process.readBytes(eip, len(syscall_opcode))
process.writeBytes(eip, syscall_opcode)
process.setreg("eax", fork_syscall_nr)
child = None
process.singleStep()
ev = process.waitEvent()
child = ev.process
process.setreg("eax", old_eax)
process.setInstrPointer(eip)
process.writeBytes(eip, old_instrs)
child.setreg("eax", old_eax)
child.setInstrPointer(eip)
child.writeBytes(eip, old_instrs)
return child
class Fuzz(object):
def try_arg(self, str_argument):
print "Trying argument %s" % str_argument
process = self.test_process
new_str_addr = self.mem + 0x100
arg_addr = process.getreg("esp") + 4
arg = process.readWord(arg_addr)
process.writeBytes(new_str_addr, str_argument)
process.writeWord(arg_addr, new_str_addr)
arg = process.readWord(arg_addr)
playWithProcess(process)
def fuzz(self, arguments, address):
self.arguments = arguments
self.address = address
self.mem = None
self.pid = traceProgram(self.arguments)
self.is_attached = True
self.dbg = PtraceDebugger()
self.process = self.dbg.addProcess(self.pid, self.is_attached)
self.process.createBreakpoint(self.address, None)
self.process.setoptions(ptrace_bindings.PTRACE_O_TRACEFORK)
self.mem = allocateMemory(self.process)
playWithProcess(self.process)
ip = self.process.getInstrPointer() - 1
breakpoint = self.process.findBreakpoint(ip)
if breakpoint:
print ("Stopped at %s" % breakpoint)
breakpoint.desinstall(set_ip=True)
for length in range(0, 20):
self.test_process = createCheckpoint(self.process)
self.try_arg("a" * length)
#self.test_process.terminate(True)
self.dbg.quit()
if __name__ == "__main__":
Fuzz().fuzz(argv[2:], int(argv[1], 16))