Exploiting with python

The purpose with this project was to learn the basics around building an exploit. I will do my best to write a step-by-step guide from what I learned, including some fails I encountered during this project. To make this as easy as possible, I decided to take a already known vulnerable program and exploit it in my own way.

What I used:
Victim:
Windows XP (unpatched)
WAR-FTPD 1.65
Immunity Debugger

Attacker:
Python
Telnet
Netcat

Step 1 – Initial setup

Run Immunity Debugger and open/run WAR-FTPD on the windows machine.
Telnet and verify that you are able to access it from attacker.
1_telnet

Step 2 – Fuzzing, overflow please?

This is where we start trying to crash the FTP server by a buffer overflow. Feeding large amount of data into a input in hope that the input will crash the FTP serve and the first obvious place to begin would be the username or password.

2_fuzzing
As you see here, the “[+] server is down” when we tested with a payload length of 1000 bytes, which means it probably crashed on the 500 attempt.
In immunity, the EIP was also overwritten with 41414141 (AAAA) which matches the payload. Remember to restart WAR-FTPD between each crash.
3_immunity

The next thing we want to do is find the max allowed input for the exploit. This basically tells how much space is available for the payload and are done by repeating the method above while manually increasing or decreasing the size while verifying the crash with Immunity Debugger.
When testing with 1200+ bytes, I end up up in a DLL named msvcrt.dll where the EIP is something completely different than 41414141. We still have control over the EIP when the payload is at or below 1100 bytes.
4_immunity

Step 3 – Locating the EIP

EIP is a pointer to the next instruction and by having control over it we can force the FTP server to run and execute code at non-intended locations. You can always locate the EIP by manual testing, but this takes quite some time and so I rather wrote a script helping me to identify the pointer. See: bufferoverflow.py

5_bufferoverflow
When running bufferoverflow.py and parsing the input to the exploit script, Immunity debugger reports that the EIP is 32714131, then I run the EIP address back into bufferoverflow.py, which is able to identify the location the EIP and identify that it is in Little Endian.

Step 4 – Test and verify bad characters

So far we know this:
EIP is located at ‘A’ * 485 + ‘EIP_ADDRESS’
Payload max length is 1100 bytes

I then replace the EIP with 42424242 (BBBB) –  making it easier to verify I got the exact location.
If we follow the ESP dump we can also see that the EIP is followed by a lot of C’s (this is where we can put the exploit code)
7_immunity

Now we need to test if there are any bad characters that may cause problems for the exploit.

Common bad characters that may break the exploit.
Hex Dec Description
--- --- ---------------------------------------------
0x00 0 Null byte, terminates a C string
0x0A 10 Line feed, may terminate a command line
0x0D 13 Carriage return, may terminate a command line
0x20 32 Space, may terminate a command line argument

By running this code, we will try each of every combination between 0x00 and 0xFF

 

By testing multiple of times while inspecting the ESP dump, we can now remove bad characters as they break the overflow injetion.

try1

Something weird happened on the forth test. The program started to not crash when I removed both \x00, \x0a, and \x0d from the payload.
After some testing, I found out that the character causing this “fix”, was \x40, or the symbol “@”. I need to research this later, because it makes no sense why a program should continue to work even after writing all B’s to the EIP.

Step 5 – Building the exploit

We can now start building the exploit since we know all bad characters. To make it simple, I will use a reverse TCP shell to the attacking machine on port 4444, rather than a staged meterpreter. I also did a few tests with msfvenom, but was not able to generate a working shellcode.

Add the buf payload to the code, run it and inspect the ESP dump at the crash.
What you can expect to see: a lot of AAAAA, then hexadecimals looking like the exploit, and then followed by CCCCCC. If you don’t see any CCCCCC’s – it probably mean that the exploit is to long and you used up the available space (padding), or forgot to remove bad characters with the “-b” argument. You can verify the remaining length by running the exploit.

Step 6 – Locating a valid injection point

EIP is located at ‘A’ * 485 + ‘EIP_ADDRESS’
payload max length is 1100 bytes
Bad characters: \x00 \x0a \x0d \x40

Bad characters does not only apply for the shell code, but also the EIP which we want to manipulate. Since WAR-FTPD runs with a memory location that starts with “00”, means that we can’t inject the payload into this location and need to find another file loaded in the memory by WAR-FTPD.

modules
I highly recommended to verify that the file is not protected by ASLR or Rebase, which will make this harder. You can download the mona plugin and run “!mona modules” to check files for ASLR and Rebase. There are two types of instructions we will be looking for, which is ‘JMP ESP’ or the instruction sequence ‘PUSH ESP; RET’

ole32.dll seem to be inside a valid memory range (base: 7774e0000, top: 0013d000), and after opening it I was able to find a JMP ESP with a ‘valid’ memory address: 7755A930

Note: JMP ESP with odd hex numbers like (1,3,5,7,9,B,D,F), will not work.
target

Now that we got a target address, we can replace the ‘BBBB’ in the exploit with 7755A930. Remember that the WAR-FTPD uses Little Endian, which means that we need to reverse the pointer address to 30a95577.

Step 7 – Pwning WAR-FTPD

Run netcat or similar on the attacking host, making it listen to 4444. (nc -nlvp 4444)
Start pwning!

pwn

Thats it!

Some awesome resources I found along the way:

Windows Exploit Development – Part 1: The Basics


https://samsclass.info/127/proj/vuln-server.htm

3 Responses to “Exploiting with python”

  1. yan says:

    Hi,

    Firstly thank you for this helpful tutorial. I get some error when the http://ftp.py is running, Can you check the code. Why it can be Thank you.

    File “./ftp.py”, line 20
    send_exploit()
    ^
    IndentationError: expected an indented block

  2. yan says:

    It is solved, I find some characters in code. It is running no problem. .

  3. ben says:

    I have read many article about bof, I think you are the best, brilliant 😉 Because, No unnecessary information in your articles and Easy understandable..Thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *