Writeup CTF 8dot8 2017

El pasado Jueves y Viernes se realizó la 8dot8 en Chile, donde pude participar como charlista y jugar el CTF que finalmente gané. Aquí doy las soluciones a los desafíos que más llamaron mi atención.

ASCII numbers

El primer desafío de programación era responder correctamente 500 números mostrados en ASCII art a través de un servicio de red. El estilo de estos números me recordó a FIGlet, por lo que trate de resolverlo usando ese programa. Los pasos que seguí fueron:

  1. Crear la lista de números ASCII usando FIGlet y aplicar una limpieza para eliminar saltos de línea y espacios. Se supone que el índice de la lista corresponde con el número ASCII (numbers[0] corresponde con el número cero).
  2. Basado en la información recibida, si el servidor envía los números y pide una respuesta, empezamos el procesamiento de los números recibidos.
  3. La información recibida la separamos por líneas y normalmente los números estarán entre las líneas 1-4, por lo tanto realizamos la misma limpieza que en el punto 1 para poder comparar la existencia de un número. De esa forma armamos nuestra respuesta y la enviamos al servidor.
  4. En el caso que no nos pida una respuesta, posiblemente otra información fue recibida y la mostramos por pantalla. Esa información contenía la flag!

Dejo con ustedes el código usado.

import re
import commands

from pwn import remote


# 1
numbers = []
for i in range(10):
    number = commands.getoutput('figlet %d' % i)
    number = re.sub('\n|\s', '', number)
    numbers.append(number)

r = remote('luckyctf.rtfm-ctf.org', 1337)
output = r.recv()

while True:
    output = r.recv()
    
    # 2
    if output.endswith('Answer: '):
        to_guess = output.split('\n\n')

        # 3
        rs = ''
        for i in range(1, 5):
            n = re.sub('\n|\s', '', to_guess[i])

            for i in range(10):
                if n == numbers[i]:
                    rs += '%d' % i
                    break

        print('.')
        r.sendline(rs)
        r.recv()
    else:
        # 4
        print(output)
        break

r.close()

SuperEasy

Este desafío era un binario para Linux y como su nombre lo dice, era super easy. Se aplicaba el comando strings sobre el binario lo que arrojaba un curioso string en base64.

$ strings supereasy -n 14                 
/lib/ld-linux.so.2                        
__gmon_start__                            
_IO_stdin_used                            
__libc_start_main                         
Entre com a senha para abrir a flag:      
YzBkMzU3Njk4OTR0NGNrCg==      

Al decifrarlo, daba la flag del desafío (c0d35769894t4ck).

BabyRevertMe

El segundo desafío de reversing era un binario en Windows. Lo cargué en IDA y llegué al siguiente punto:

Como se puede ver, había una comparación JZ (Jump Zero) antes de la lógica que imprime la flag. Si se realiza el salto depende del valor del registro ZF.

Ante un input cualquiera, el valor del registro ZF era 1 y el programa salía. La misión era lograr que el registro ZF fuera 0 para imprimir la flag.

Pusé un breakpoint en la comparación, cambié el valor de ZF en el debugger de IDA y puse un breakpoint antes que el programa acabara. Así pude obtener la flag para este desafío.

Bugpress

El único desafío web era un servidor que tenía Wordpress. Luego de verificar su versión (4.7.4), corrí wpscan para ver si el desafío se trataba de explotar alguna vulnerabilidad en un plugin, pero estaban instalados solo los plugins por defecto.

En alertot nos consideramos una startup técnica, pero de verdad. Nuestro CTO ha trabajado para la NASA, yo aporto con el background en desarrollo y seguridad, y mi primo Guillermo es el encargado comercial. En vista de este abanico de posibilidades, ¿quién resolvió este desafío? Guillermo.

Después de recordar que a mediados de año me llamó mucho la atención una vulnerabilidad en Wordpress sobre la recuperación de contraseña (Password Reset vulnerability), se lo comenté y me dijo que él estaba interesado en hacer la explotación. Tomó la información del advisory, creo las condiciones para explotar la vulnerabilidad satisfactoriamente y unas horas después me envió la flag.