Lately I've been investigating fuzzing techniques. In particular, memory fuzzing. So, inevitably I had to study PyDgb and PaiMei. These two took me to sinn3r's InMemoryFuzzer, and in it I found an imprecision (or bug) on the documentation (or code) of the fuzzer. It goes like this:
1. When you run the tracer it collects an execution flow log dumped into the flow_log.txt. This log file looks like this:
2. After analyzing this trace dump, you're supposed to use the function addresses and the arguments of relevance to build a breakpoints.txt file that will feed the InMemoryFuzzer.py. This file (should) resembles this:
0x100594c 0x100239d ESP+16
This is what I understood from reading the documentation and it seem's quite logic, right? The problem is that, in the Tracer.py code, the argument is built and saved to flow_log.txt as a decimal value:
You can see from the excerpt of the log function that the arg_counter variable is a decimal value incremented 4 bytes each interaction and is saved without any transformation or hex encoding.
Later on, in InMemoryFuzzer.py the function responsible for reading the breakpoints.txt file is getHookpointsFromFile, but the one that uses the argument item is modifyArgument. The modifyArgument function grabs this value "ESP+16" and assumes it is in hexadecimal format.
So, the correct format of breakpoints.txt is:
0x100594c 0x100239d ESP+0xF
OR, you could just correct the code to whatever you encoding favorite flavor is. Mine is decimal; so this change to InMemoryFuzzer.py does the trick to continue using breakpoints.txt with ESP+16:
argString = self.hooks[self.hookIndex][2].replace("ESP+", "")
argInt = int(argString, 10)
pydbg.write_process_memory(pydbg.context.Esp + argInt, pydbg.flip_endian(self.lastChunkAddr))
argInt = int(argString, 10)
pydbg.write_process_memory(pydbg.context.Esp + argInt, pydbg.flip_endian(self.lastChunkAddr))
Best regards.
Sem comentários:
Enviar um comentário