J’ai utilisé Hopper Disassembler pour résoudre ce challenge.
Dans la fenêtre “labels”, figurent 2 références intéressantes :
0x201020 flag_enc
0x201080 pass_enc
On a alors :
flag_enc:
0x0000000000201020 db 0x56 ; 'V' ; DATA XREF=main+87, main+99
0x0000000000201021 db 0x64 ; 'd'
0x0000000000201022 db 0x6b ; 'k'
0x0000000000201023 db 0x6b ; 'k'
0x0000000000201024 db 0x1f ; '.'
0x0000000000201025 db 0x63 ; 'c'
0x0000000000201026 db 0x6e ; 'n'
0x0000000000201027 db 0x6d ; 'm'
0x0000000000201028 db 0x64 ; 'd'
0x0000000000201029 db 0x20 ; ' '
0x000000000020102a db 0x1f ; '.'
0x000000000020102b db 0x53 ; 'S'
0x000000000020102c db 0x67 ; 'g'
0x000000000020102d db 0x64 ; 'd'
0x000000000020102e db 0x1f ; '.'
0x000000000020102f db 0x65 ; 'e'
0x0000000000201030 db 0x6b ; 'k'
0x0000000000201031 db 0x60 ; '`'
0x0000000000201032 db 0x66 ; 'f'
0x0000000000201033 db 0x1f ; '.'
0x0000000000201034 db 0x68 ; 'h'
0x0000000000201035 db 0x72 ; 'r'
0x0000000000201036 db 0x39 ; '9'
0x0000000000201037 db 0x1f ; '.'
0x0000000000201038 db 0x45 ; 'E'
0x0000000000201039 db 0x42 ; 'B'
0x000000000020103a db 0x52 ; 'R'
0x000000000020103b db 0x42 ; 'B'
0x000000000020103c db 0x7a ; 'z'
0x000000000020103d db 0x37 ; '7'
0x000000000020103e db 0x32 ; '2'
0x000000000020103f db 0x65 ; 'e'
0x0000000000201040 db 0x33 ; '3'
0x0000000000201041 db 0x30 ; '0'
0x0000000000201042 db 0x33 ; '3'
0x0000000000201043 db 0x32 ; '2'
0x0000000000201044 db 0x30 ; '0'
0x0000000000201045 db 0x62 ; 'b'
0x0000000000201046 db 0x30 ; '0'
0x0000000000201047 db 0x30 ; '0'
0x0000000000201048 db 0x30 ; '0'
0x0000000000201049 db 0x2f ; '/'
0x000000000020104a db 0x35 ; '5'
0x000000000020104b db 0x31 ; '1'
0x000000000020104c db 0x63 ; 'c'
0x000000000020104d db 0x2f ; '/'
0x000000000020104e db 0x2f ; '/'
0x000000000020104f db 0x32 ; '2'
0x0000000000201050 db 0x63 ; 'c'
0x0000000000201051 db 0x63 ; 'c'
0x0000000000201052 db 0x2f ; '/'
0x0000000000201053 db 0x31 ; '1'
0x0000000000201054 db 0x30 ; '0'
0x0000000000201055 db 0x32 ; '2'
0x0000000000201056 db 0x62 ; 'b'
0x0000000000201057 db 0x65 ; 'e'
0x0000000000201058 db 0x37 ; '7'
0x0000000000201059 db 0x31 ; '1'
0x000000000020105a db 0x33 ; '3'
0x000000000020105b db 0x63 ; 'c'
0x000000000020105c db 0x35 ; '5'
0x000000000020105d db 0x35 ; '5'
0x000000000020105e db 0x65 ; 'e'
0x000000000020105f db 0x36 ; '6'
0x0000000000201060 db 0x36 ; '6'
0x0000000000201061 db 0x2f ; '/'
0x0000000000201062 db 0x60 ; '`'
0x0000000000201063 db 0x2f ; '/'
0x0000000000201064 db 0x61 ; 'a'
0x0000000000201065 db 0x64 ; 'd'
0x0000000000201066 db 0x30 ; '0'
0x0000000000201067 db 0x32 ; '2'
0x0000000000201068 db 0x2f ; '/'
0x0000000000201069 db 0x34 ; '4'
0x000000000020106a db 0x64 ; 'd'
0x000000000020106b db 0x31 ; '1'
0x000000000020106c db 0x37 ; '7'
0x000000000020106d db 0x30 ; '0'
0x000000000020106e db 0x32 ; '2'
0x000000000020106f db 0x65 ; 'e'
0x0000000000201070 db 0x30 ; '0'
0x0000000000201071 db 0x34 ; '4'
0x0000000000201072 db 0x63 ; 'c'
0x0000000000201073 db 0x63 ; 'c'
0x0000000000201074 db 0x36 ; '6'
0x0000000000201075 db 0x35 ; '5'
0x0000000000201076 db 0x34 ; '4'
0x0000000000201077 db 0x2f ; '/'
0x0000000000201078 db 0x32 ; '2'
0x0000000000201079 db 0x60 ; '`'
0x000000000020107a db 0x38 ; '8'
0x000000000020107b db 0x30 ; '0'
0x000000000020107c db 0x63 ; 'c'
0x000000000020107d db 0x7c ; '|'
0x000000000020107e db 0x00 ; '.'
0x000000000020107f db 0x00 ; '.'
pass_enc:
0x0000000000201080 db 0x4e ; 'N' ; DATA XREF=main+68
0x0000000000201081 db 0x7a ; 'z'
0x0000000000201082 db 0x54 ; 'T'
0x0000000000201083 db 0x66 ; 'f'
0x0000000000201084 db 0x64 ; 'd'
0x0000000000201085 db 0x76 ; 'v'
0x0000000000201086 db 0x73 ; 's'
0x0000000000201087 db 0x34 ; '4'
0x0000000000201088 db 0x51 ; 'Q'
0x0000000000201089 db 0x34 ; '4'
0x000000000020108a db 0x74 ; 't'
0x000000000020108b db 0x74 ; 't'
0x000000000020108c db 0x78 ; 'x'
0x000000000020108d db 0x31 ; '1'
0x000000000020108e db 0x73 ; 's'
0x000000000020108f db 0x65 ; 'e'
Et donc une référence dans la fonction main :
int main() {
var_8 = *0x28;
// Récupère la string var_30
fgets(&var_30, 0x20, *__TMC_END__);
// transforme la chaine
transform(&var_30);
// compare la chaîne utilisateur avec le bon mot de passe (pass_enc)
rax = memcmp(&var_30, pass_enc, 0x10);
// si elles sont identiques
if (rax == 0x0) {
// transforme la chaîne flag_enc
transform(flag_enc);
// affichage de la chaîne flag_enc transformée
puts(flag_enc);
rax = 0x1;
}
else {
rax = 0x0;
}
rcx = var_8 ^ *0x28;
if (rcx != 0x0) {
__stack_chk_fail();
}
return rax;
}
Donc le flag est affiché si l’entrée utilisateur est conforme au mot de passe. Voici la fonction transform
:
int transform(void * ) {
var_8 = arg_0;
// Parcours la chaine jusqu'à la fin (0x00)
do {
rax = var_8;
// incrémente la position dans la chaine
var_8 = rax + 0x1;
// transforme le caractère actuel (position rax)
// stocke à la même position la valeur ordinale du caractère +1
// Ex : si c'est "A" (65), on stockera "B" (66)
*(int8_t *)rax = (*(int8_t *)rax & 0xff) + 0x1;
// caractère suivant pour test de sortie de boucle
rax = *(int8_t *)var_8 & 0xff;
} while (rax != 0x0);
return rax;
}
Ce code en Python donne :
def transform(thestring):
return ''.join(chr(x + 1) for x in thestring)
Si on l’applique à flag_enc
:
# Chaîne codée
flag_enc = [
0x56, 0x64, 0x6B, 0x6B, 0x1F, 0x63, 0x6E, 0x6D, 0x64, 0x20, 0x1F, 0x53,
0x67, 0x64, 0x1F, 0x65, 0x6B, 0x60, 0x66, 0x1F, 0x68, 0x72, 0x39, 0x1F,
0x45, 0x42, 0x52, 0x42, 0x7A, 0x37, 0x32, 0x65, 0x33, 0x30, 0x33, 0x32,
0x30, 0x62, 0x30, 0x30, 0x30, 0x2F, 0x35, 0x31, 0x63, 0x2F, 0x2F, 0x32,
0x63, 0x63, 0x2F, 0x31, 0x30, 0x32, 0x62, 0x65, 0x37, 0x31, 0x33, 0x63,
0x35, 0x35, 0x65, 0x36, 0x36, 0x2F, 0x60, 0x2F, 0x61, 0x64, 0x30, 0x32,
0x2F, 0x34, 0x64, 0x31, 0x37, 0x30, 0x32, 0x65, 0x30, 0x34, 0x63, 0x63,
0x36, 0x35, 0x34, 0x2F, 0x32, 0x60, 0x38, 0x30, 0x63, 0x7C ]
# Décodage
def transform(thestring):
return ''.join(chr(x + 1) for x in thestring)
print(f"{transform(flag_enc)}")
Cela donne :
Well done! The flag is: FCSC{83f41431c111062d003dd0213cf824d66f770a0be1305e2813f15dd76503a91d}
On peut trouver le mot de passe en inversant la méthode transform
:
# Chaîne codée (Vive Canal)
pass_enc = [0x4e, 0x7a, 0x54, 0x66, 0x64, 0x76, 0x73, 0x34, 0x51, 0x34, 0x74, 0x74, 0x78, 0x31, 0x73, 0x65]
# Décodage
decoded = ''.join(chr(x - 1) for x in pass_enc)
print(f"{decoded}")
Cela donne :
MySecur3P3ssw0rd