Contexto y objetivo

Exalton es un challenge de reversing que presenta un binario que solicita una contraseña. El objetivo es analizar la lógica de validación para recuperar la contraseña correcta mediante ingeniería inversa.

La protección consiste en una transformación aritmética aplicada a cada carácter de la entrada, cuyos resultados se comparan contra un array de valores precomputados.


Reconocimiento inicial

Tras descargar el binario, realizamos una identificación básica con file:

file exalton

Se trata de un ejecutable ELF de arquitectura x86-64. No presenta ofuscación aparente ni protecciones anti-debugging.


Análisis estático

Abrimos el binario en Ghidra para realizar el análisis estático. Comenzamos inspeccionando las strings del binario, pero no encontramos información relevante que revele directamente la contraseña.

Función main()

En la función main(), observamos la lógica principal del programa:

Imagen del post

El programa solicita una entrada al usuario mediante scanf y posteriormente la pasa como argumento a una función llamada exalton(). El valor de retorno de esta función se compara contra un array de 36 valores enteros hardcodeados en el código.

Estos valores representan la transformación esperada de cada carácter de la contraseña correcta:

[1152, 1344, 1056, 1968, 1728, 816, 1648, 784, 1584, 816, 
 1728, 1520, 1840, 1664, 784, 1632, 1856, 1520, 1728, 816, 
 1632, 1856, 1520, 784, 1760, 1840, 1824, 816, 1584, 1856, 
 784, 1776, 1760, 528, 528, 2000]

Función exalton()

Analizamos la función exalton() para comprender la transformación aplicada:

Imagen del post

La función realiza las siguientes operaciones sobre cada carácter de la entrada:

  1. Recorre la cadena carácter por carácter mediante un bucle
  2. Convierte cada carácter a su valor ASCII (implícito en C al tratar char como entero)
  3. Aplica un desplazamiento de bits a la izquierda de 4 posiciones (<< 4)

La operación x << 4 equivale a multiplicar por 2⁴ = 16. Por tanto, la transformación es:

valor_transformado = ASCII(carácter) × 16

Solución: Reversión de la transformación

Para recuperar la contraseña original, debemos aplicar la operación inversa a cada valor del array. Si la transformación fue x << 4, la inversa es x >> 4 (desplazamiento a la derecha).

Implementamos un script en Python que:

  1. Toma cada valor del array
  2. Aplica >> 4 para revertir la multiplicación por 16
  3. Convierte el resultado a su carácter ASCII correspondiente
def transform_inversa(numbers):
    result = ""
    for n in numbers:
        ascii_val = n >> 4  # Revertir el desplazamiento
        result += chr(ascii_val)
    return result

password = [1152, 1344, 1056, 1968, 1728, 816, 1648, 784, 1584, 816, 
            1728, 1520, 1840, 1664, 784, 1632, 1856, 1520, 1728, 816, 
            1632, 1856, 1520, 784, 1760, 1840, 1824, 816, 1584, 1856, 
            784, 1776, 1760, 528, 528, 2000]

print(transform_inversa(password))

Resultado y verificación

Al ejecutar el script, obtenemos la contraseña correcta. Verificamos ejecutando el binario con la contraseña recuperada:

Imagen del post

El programa acepta la entrada y nos revela la flag.


Conclusión

Este challenge ilustra una técnica común en reversing: transformaciones aritméticas simples aplicadas a la entrada del usuario. Aunque el operador de desplazamiento de bits puede parecer complejo a simple vista, su equivalencia con operaciones aritméticas lo hace reversible de forma trivial.

Aprendizajes técnicos:

  • Los operadores bit a bit (<<, >>) son frecuentemente usados en validaciones de contraseña
  • La operación << 4 es equivalente a × 16 y >> 4 a ÷ 16
  • Ghidra facilita la identificación de patrones de transformación mediante la descompilación

Implicación defensiva: Este tipo de validación ofrece protección nula contra análisis estático, ya que los valores esperados están expuestos directamente en el binario. Una implementación más robusta requeriría hashing criptográfico o validación remota.