Post

Circle City Con CTF2021 - Little Mountain

Reversing

Climb this mountain and score some points :)

Primeros pasos

Para este se entrega un binario llamado “little”:

1
2
$ file little
little: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=e351b1170c55d3a63fde69c338ff1b2911dd1d88, for GNU/Linux 3.2.0, not stripped

Ni con strings ni con strace se puede obtener información interesante, si se ejecuta aparece un menú con 3 opciones:

1
2
3
4
$ ./little
Option 0: Guess the number
Option 1: Change the number
Option 2: Exit
  • La opción 0 imprime la cadena “Go ahead, give it a shot…”, lee un entero e imprime la cadena “Try again?”.

  • La opción 1 solamente imprime la cadena “Always ready for more”.

  • La opción 2 termina la ejecución del programa.

Análisis estático

Si se decompila con Ghidra, se puede ver el funcionamiento del main, que es la función que muestra las opciones y llama a las demás funciones. Estas funciones no son llamadas directamente sino que primero se obtiene su dirección de memoria de una estructura. Llama la atenciñón que hay 4 direcciones en esta estructura, esto quiere decir que se puede llamar a una 4ª función (opción 3).

También se pueden buscar las cadenas anteriores, y buscando las referencias a estas, encontrar rapidamente las funciones de las opciones 0, 1 y 2. Estas funciones se llaman ‘a’, ‘b’ y ‘c’ respectivamente, y la función “oculta” de la opción 3 se llama ‘d’.

a

b

c

d

Parece que la función ‘d’ imprime la flag cuando la variable ‘modded’ tiene un valor de 20 (0x14). En este punto hay dos opciones:

  • Poner un breakpoint en la comparación del valor modded y cambiar su valor a 20.

  • La función ‘b’ incrementa ‘modded’ una unidad cada vez que se la llama, entonces podría ser llamada 20 veces y luego llamar a la función ‘d’ para que imprima la flag.

A continuación se muestra el codigo de un script que resuelve el reto:

solver.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python3

from pwn import *

b = process("./little")

for i in range(20):    
    b.recv().decode("utf-8")
    b.sendline('1')
    b.recvline().decode("utf-8")

b.sendline('3')
b.recv().decode("utf-8")
print(b.recvuntil('}').decode("utf-8"))
b.close()

This post is licensed under CC BY 4.0 by the author.