AlexCTF - RE2 C++ is awesome (100pts)

Durante el fin de semana pasado estuvimos cacharreando en AlexCTF sin ir muy en serio debido a la falta de tiempo, pero entre ratico y ratico pudimos sacar alguna que otra flag. Este es el writeup del segundo reto de reversing, en el que optamos por un approach de vagos.

.0x00. Intro

En este caso se nos presentaba un binario y la siguiente descripción:

They say C++ is complex, prove them wrong!

Las características del binario eran las siguientes:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400a60
  Start of program headers:          64 (bytes into file)
  Start of section headers:          8864 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 28

.0x01. Análisis inicial

Al ejecutar el binario vemos que pide el argumento <flag>:

> ./re2
Usage: ./re2 flag

Lo que hicimos es empezar a probar cosas sin sentido antes de analizar estáticamente el fichero, hasta que nos dimos cuenta de que se podia bruteforcear la flag. Si ejecutamos el fichero con cualquier carácter válido de la flag (en el orden correcto), el binario nos escupe lo siguiente:

> ./re2 A
You should have the flag by now

Sabiendo que el formato de flag es ALEXCTF{xxxx}, al añadir el resto de carácteres de la parte de la flag que ya conocemos, el output no varía:

> ./re2 ALEXCTF{
You should have the flag by now

En el momento de que alguno de los carácteres no sea correcto, el output que escupe es el siguiente:

> ./re2 ALEXCTF{A
Better luck next time

Por lo que decidimos bruteforcear la flag parseando la salida con un scriptillo en bash.

.0x02. Profit

El script utilizado para obtener la flag fue el siguiente:

#!/bin/bash

FLAG=""

while true; do
  for x in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 '{' '}' '!' '@' '#' '$' '%' '^' '&' '*' '(' ')' '-' '-' '_' '+' '=' '[' ']' '.' ';' '\\' '/' ',' '<' '>' '`' '~' "'" '"' '?'; do
    ./re2 $FLAG$x | grep "You should" 1>/dev/null
    if [[ $? -eq 0 ]]; then
      FLAG="$FLAG$x"
      if [[ $x == "}" ]]; then
        echo $FLAG
        exit 0
      fi
    fi
  done
done

Sabiendo que el último carácter corresponde a }, solo printamos la flag al acabar:

> bash brute.sh
ALEXCTF{W3_L0v3_C_W1th_CL45535}

Cheers! srm

Made with lots of coffee and Hugo.