Researchers have recently uncovered a mysterious ancient artifact beneath the Cogswell Halls. Its purpose remains unknown, but its potential seems invaluable. Who knows? The secrets it holds could revolutionize modern knowledge. They need an expert eyeโyours! Let's dig in !
Ce challenge tourne sur un docker et n'est pas disponible
Solution
Pour ce challenge, on commence par dรฉcompiler. Ici, j'utilise Ghidra.
Ensuite, rendez-vous dans la fonction HackDay :
On voit un jump vers c95WsZt4xa. Dans celui-ci, on place une valeur dans EBX, puis on jump ร nouveau.
Ce qu'on a mis dans EBX, c'est SEFD, avec un peu d'intuition, on s'aperรงoit que c'est le dรฉbut de la base64 de HACKDAY :
En fait, le binaire place dans les registres EAX, EBX, ECX et EDX un bout du flag encodรฉ en base64. On peut ร la main rรฉcupรฉrer toutes ces valeurs dans le bon ordre, mais on va plutรดt automatiser รงa afin de montrer comment รงa fonctionne.
Ici, j'utilise python avec gdb :
import gdb
import re
from base64 import b64decode
def get_register_value(register: str) -> str:
s = gdb.execute(f"info register {register}", to_string=True)
s = re.sub(' +', ' ', s).split(' ')[1]
return s
def get_address_value(address: str) -> str:
s = gdb.execute(f"x /w {address}", to_string=True)
s = bytes.fromhex(s.split('\t')[1][2:]).decode()[::-1] # little endian
return s
# Charger le binaire
gdb.execute("file ./just-dig-out")
# On break sur le tout premier jump de HackDay (premier screen)
gdb.execute("break *0x565561e4")
# On lance le binaire
gdb.execute(f"run")
# Une fois le breakpoint atteint
# On rรฉcupรจre la valeur des registres
old_registers = [get_register_value(r) for r in ['eax', 'ebx', 'ecx', 'edx']]
# On prend le jmp suivant et on se cale APRES le MOV dans le registre
for i in range(2):
gdb.execute("ni")
encoded_flag = ''
for _ in range(11):
# Rรฉcupรจre les nouvelles valeurs des registres
registers = [get_register_value(r) for r in ['eax', 'ebx', 'ecx', 'edx']]
# Dรฉtecte le registre qui a changรฉ (et rรฉcupรจre l'adresse qu'il contient)
address = [registers[i] for i in range(len(registers)) if registers[i] != old_registers[i]][0]
# Rรฉcupรจre la valeur ร l'adresse
value = get_address_value(address)
# Ajoute cetete valeur ร notre chaรฎne finale
encoded_flag += value
# Remplace les anciens registres par les nouveaux
old_registers = registers
# Prendre le prochain jump
for i in range(4):
gdb.execute("ni")
# Dรฉcode et affiche le flag
print(b64decode(encoded_flag).decode())
gdb.execute("quit")
On lance la commande gdb -q -x just.py, et on admire le travail :