NDH Prequals RCE300 Write-Up
Un challenge original qui consistait à reverse un jeu de Nintendo DS.
Le “jeu”, tout simple consistait juste à trouver un mot de passe. Avec l’émulateur iDeaS :

Plutôt que de chercher et installer des plugins IDA souvent difficile à faire fonctionner (pour moi en tout cas), j’ai préféré tester le débugger natif de iDeaS dont les échos n’étaient pourtant pas très bon.
On se retrouve avec les instruction asm arm, les registres, et les différentes zones mémoires. Assez simple pour ne pas s’y perdre.
Point néanmoins difficile, comment poser des breakpoint, et où les poser.
Je mets d’abord le jeu en pause “Trace into”… Surement la routine d’attente d’appuie sur les touches du clavier… Là me vient une idée toute bête, “Program Pause F4″ petit tricks des mains :D, j’envoie un mot de passe et au moment de la descente du clavier, j’appuie sur F4.
Je me retrouve donc dans la routine suivante, dans laquelle se trouve surement le test du password. On a d’abord la routine qui fait descendre le clavier, après plusieurs essais, naviguant avec F6 et F8 je détecte que la routine de descente du clavier se termine lorsque R04 = 0xFFFFFF42.
Ensuite je farme la touche F8 tout en surveillant les registres je vois passer 74 “t” en ascii dans R02. Peut être une routine intéressante ? On remarque en passant R03 (0x02043E28) dans lequel se trouve l’adresse de notre chaine de caractère.
Au final, cette routine sert juste à recopier la chaine à l’adresse 0x0B003BD8, on peut voir le strb r2, [r5, 0x00].
Bref rien d’intéressant ici.
Je continue mon chemin pour arriver à 0x020003FE où l’on voit encore “74″, à partir de ce point j’utiliserais le pseudo breakpoint “Run to Cursor F6″ qui me permet de retourner à chaque essai à cette adresse.
Il faut noter 2 constantes qui nous serviront plus tard :
0x332718FA dans R05.
et 0xFFAB5709 dans R06
On a ensuite une série de calcul sur chacune de nos lettres puis lorsqu’il ne trouve plus de lettre :
cmp r1, 0×00
ldr r3,0x33e0D2f1
cmp r0, r3
compare le résultat obtenu avec 0x33E0D2F1.
beq 0x020004D6
saute à 020004D6 si la comparaison est valide.
Forçons le saut en cochant le Z flag.
De nouvelle valeur sont chargés dans R00.
Puis l’on se retrouve à la même routine de calcul sur chacune de nos lettres.
Après ces calculs, encore une comparaison avec 0xBCFA8D3F cette fois, suivie d’un saut si inégal.
On évite le saut cette fois, toujours en cochant le Z flag.
On détache le debugger :
Oh joie, GRANTED.
On a donc 2 checksum d’affilé…
On décide alors de recoder en C la routine de checksum afin de bruteforcer le mot de passe.
Et un script bash dégueu pour bruteforcer… : [BruteSH]
Si vous voulez des précisions sur la retranscription en C n’hésitez pas : agix[at]shell-storm.org
Malheureusement le temps nous a manqué pour trouver le mot de passe.
Mais après 5 bonnes heures :
On était donc un peu déçu de ne pas valider cette épreuve pourtant terminée à 90% !
Mais je mettrais donc un bon point au débugger d’iDeaS qui finalement fait bien son boulot.
Je remercie les nibbles de m’avoir bien accueilli pour mon premier (et surement pas dernier) CTF à leur coté !
agix
























Ta fonction cl est en fait une simple division ;)
Le code de vérification se résume à :
DWORD hash1(BYTE* serial)
{
int i;
DWORD r0 = 0xFFAB5709;
for (i = 0; serial[i]; i++)
r0 = ((r0*0xFFAB5709) / serial[i]) ^ 0x332718FA;
return r0;
}
DWORD hash2(BYTE* serial)
{
int i;
DWORD r0 = 0xABF9997E;
for (i = 0; serial[i]; i++)
r0 = ((r0 * 0xABF9997E) / serial[i]) ^ 0xBCD9870F;
return r0;
}
if ((hash(serial) == 0x33E0D2F1) && (hash2(serial) == 0xBCFA8D3F))
GoodBoy
else
BadBoy