Bug Hunting and Exploit Development 3: Finding Flaws Using Fuzzing 2
Channel: Z. Cliffe Schreuders
Date: 22/06/2015

This video is part of the computer/information/cyber security and ethical hacking lecture series; by Z. Cliffe Schreuders at Leeds Beckett University. Laboratory work sheets, slides, and other open educational resources are available at http://z.cliffe.schreuders.org. 

The slides themselves are creative commons licensed CC-BY-SA, and images used are licensed as individually attributed.

Topics covered in this lecture include:
A Spike file
In order to fuzz more complex programs, the spike script file needs to have added complexity to send certain parts of the input as expected, and focus on fuzzing the inputs that are most likely to trigger flaws:
Altering input lengths and command options
Altering integers, to test for boundary conditions and outliers
Command injections, invalid characters and so on
Limitations of fuzzing
Can be shallow due to branches in code logic that are hard to follow (for example, needing to send one kind of command before another)
Following every logic branch may be impractical or impossible (exponential order)
Black-box testing may involve a substantial amount of reverse engineering to fuzz proprietory protocols and formats
“Evolutionary fuzzing” can be used to direct code coverage and improve coverage
Finding a buffer overflow
If you cause a stack smashing buffer overflow using a fuzzer the program being tested will typically crash
If you run the target program in a debugger you can watch it crash, and examine the state it ends up in
If we have Wireshark running we can follow the TCP stream to see all of the various inputs from Spike
The stack: important x86 CPU registers
EBP: frame/base pointer - bottom of the current stack frame
ESP: stack pointer - top of the current stack frame
EIP: address of next instruction
Retrieved from the return address stored on the stack
Stack smashing buffer overflows
It is possible to overwrite the return pointer on the stack so that we change the next code that is executed
The return pointer is placed in EIP when the function returns
This is known as stack smashing
Sometimes this will simply crash the program (“segmentation fault” or access violation)
Finding a buffer overflow
Use the debugger to examine EIP
If it is an invalid memory address, we have overwritten it
As a shortcut for detecting this, we typically try to flood the buffer with “AAAAAAAA...”, which will always show up as 0x41414141 
('A' = ASCII 0x41)
If we ever see a crash, and EIP=0x41414141 we know we have a good chance of influencing program control
Finding a buffer overflow
Stack smashing buffer overflows
However, if we carefully craft input we can make the program jump to somewhere else in its own logic (known as arc injection)
Or execute our own “shellcode” (known as code injection)
We enter code that starts a shell and carefully point the return address at our own code
Or point the return address at some of its own code, which we know will return control to our shellcode
Buffer overflow...
The stack grows with each function called, and contains pointers to where to jump to when the function ends
Stack smashing overwrites the return address with a pointer to some code
Buffer overflow...
The buffer could include our shell code, and point the return address at it
The tricky part
The location of our buffer will change each time the program runs (more on this soon)
Address space layout randomization (ASLR)
Changes the location of memory and control structures, makes is harder to predict where the control data or shell code will be: makes it harder (not impossible) to conduct exploits
NO-OP Slide
No-ops are instructions that the cpu ignores
They can be used to make it easier to guess where to jump to
Just need to jump somewhere into the slide
JMP instructions
JMP instructions jump to a location pointed to by a register
If we find a register such as EBP pointing to our code...
Look for a JMP EBP in memory and point the return pointer at it