Analyse préliminaire
On commence par analyser le type du fichier :
$ file aaarg
aaarg: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=f5b07c01242cc5987bed7730c2762ae0491b5ddc, stripped
aaarg
est donc un fichier exécutable ELF x86-64, strippé donc sans symboles de débogage.
On tente d’afficher les chaînes de caractères du binaire :
$ strings aaarg
/lib64/ld-linux-x86-64.so.2
libc.so.6
[...] Rien d'intéressant
Le flag ne semble pas être en clair dans le programme, on passe donc à de l’analyse statique.
Analyse statique
On importe et analyse le binaire aaarg
dans Ghidra.
Dans la liste des fonctions reconnues de Ghidra, on trouve la fonction entry
qui est le point d’entrée habituel pour un tel binaire.
Dedans on trouve un appel à la fonction __libc_start_main
qui prend en premier argument une fonction main
.
On renomme donc FUN_00401190
en main
et on l’annote. On obtient :
long main(int argc,char **argv)
{
long lVar1;
ulong uVar2;
char *local_10;
lVar1 = 1;
if (1 < argc) {
uVar2 = strtoul(argv[1],&local_10,10);
lVar1 = 1;
if ((*local_10 == '\0') && (lVar1 = 2, uVar2 == (long)-argc)) {
uVar2 = 0;
do {
putc((int)(char)(&DAT_00402010)[uVar2],stdout);
uVar2 = uVar2 + 4;
} while (uVar2 < 0x116);
putc(10,stdout);
lVar1 = 0;
}
}
return lVar1;
}
Par la lecture de ce programme, on en déduit que pour arriver aux appels à putc
, il faut que :
- le programme prenne au moins 1 argument ;
- cet argument est un entier en écriture décimale (
strtoul(argv[1],&local_10,10)
) ; - cet entier doit être égal à
-argc
.
Il ne faut pas oublier que argc
compte également le nom du programme.
On trouve alors le flag :
$ ./aaarg -2
FCSC{f9a38adace9dda3a9ae53e7aec180c5a73dbb7c364fe137fc6721d7997c54e8d}
$ ./aaarg -3 test
FCSC{f9a38adace9dda3a9ae53e7aec180c5a73dbb7c364fe137fc6721d7997c54e8d}
$ ./aaarg -4 test test
FCSC{f9a38adace9dda3a9ae53e7aec180c5a73dbb7c364fe137fc6721d7997c54e8d}
Il est également possible de retrouver le flag en allant inspecter DAT_00402010
.
On se rend compte que cette chaîne de caractères contient des zero-width joiner \xE2\x80\x8D
, cela explique pourquoi strings
ne trouve pas directement le flag.