Énoncé
Résolution
Dans ce challenge nous avons un binaire ELF 64-bit not stripped :
$ file revme
revme: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=78c3d3682fb7390af718b39dfec9af2475858c3e, for GNU/Linux 3.2.0, not stripped
Commençons et désassemblons ce binaire !
Décompilateur Ghidra, pour la fonction main
:
undefined8 main(void)
{
time_t tVar1;
uint local_74;
uint local_70;
uint local_6c;
char local_68 [80];
uint local_18;
uint local_14;
uint local_10;
uint local_c;
tVar1 = time((time_t *)0x0);
local_10 = (uint)tVar1;
srand(local_10);
local_14 = rand();
local_c = (local_14 - 3) * 3;
if ((local_c & 1) != 0) {
local_c = local_c - 1;
}
local_18 = (int)local_c / 2 + 7;
puts("Guess The numbers that i am thinking...");
printf("Enter first number: ");
__isoc99_scanf(&DAT_00102045,&local_6c);
printf("Enter second number: ");
__isoc99_scanf(&DAT_00102045,&local_70);
printf("Enter third number: ");
__isoc99_scanf(&DAT_00102045,&local_74);
if (((local_14 == local_6c) && (local_c == local_70)) && (local_18 == local_74)) {
itachi();
}
else {
puts("wrong guess ");
sprintf(local_68,"%d %d %d %d",(ulong)local_10,(ulong)local_14,(ulong)local_c,(ulong)local_18);
puts(local_68);
}
return 0;
}
Dans cette fonction main
, nous pouvons voir qu’un nombre random est généré avec un seed (pas vraiment un nombre alétoire du coup) avec le temps actuel.
Après nous voyons qu’il y a 3 variables dans une condition et que si cette condition est validé alors la fonction itachi
sera lancé.
Voyons ce qu’il y a dans la fonction itachi
:
void itachi(void)
{
int local_10;
int local_c;
b._48_4_ = a._48_4_;
for (local_c = 0xc; -1 < local_c; local_c = local_c + -1) {
*(int *)(a + (long)(local_c + -1) * 4) =
*(int *)(a + (long)(local_c + -1) * 4) - *(int *)(a + (long)local_c * 4);
*(int *)(b + (long)(local_c + -1) * 4) =
*(int *)(b + (long)(local_c + -1) * 4) + *(int *)(a + (long)(local_c + -1) * 4);
}
for (local_10 = 0; local_10 < 0xd; local_10 = local_10 + 1) {
putchar(*(int *)(b + (long)local_10 * 4));
}
putchar(10);
return;
}
Ici nous pouvons voir beaucoup d’opérations et un appel à la fonction putchar
vers la fin, cette fonction affiche donc certainement le flag.
Démarrons le binaire revme
avec ltrace
:
ltrace ./revme
time(0) = 1647815274
srand(0x6237aa6a, 0x7ffea2a634d8, 0x7ffea2b44080, 0x55efad498400) = 0
rand(0x7fda3b6d7240, 0x7fda3b6d7740, 0x7fda3b6d71c4, 0xffffffff) = 0x4b0a1705
puts("Guess The numbers that i am thin"...Guess The numbers that i am thinking...
) = 40
printf("Enter first number: ") = 20
__isoc99_scanf(0x55efad499045, 0x7ffea2a6337c, 0, 0Enter first number:
Nous voyons la valeur du 1er nombre(local_14 | “random”) qui est utilisé pour générer le 2ème nombre(local_c) et le 3ème nombre(local_18) à deviner.
Maintenant nous devons créer un programme pour “deviner” le 2ème nombre et le 3ème nombre :
#include <stdio.h>
int main(){
unsigned int random_N = 0x4b0a1705; // number 1
unsigned int number2 = (random_N - 3) * 3;
if( (number2 & 1) != 0)
number2 = number2 - 1;
unsigned int number3 = (int)number2 / 2 + 7;
printf("%d %d %d", random_N, number2, number3);
return 0;
}
Sortie :
$ gcc solve.c -o solve && ./solve
1258952453 -518109946 -259054966
Essayons d’entrer les 3 nombres “deviné” :
$ ltrace ./revme
time(0) = 1647815274
srand(0x6237aa6a, 0x7ffea2a634d8, 0x7ffea2b44080, 0x55efad498400) = 0
rand(0x7fda3b6d7240, 0x7fda3b6d7740, 0x7fda3b6d71c4, 0xffffffff) = 0x4b0a1705
puts("Guess The numbers that i am thin"...Guess The numbers that i am thinking...
) = 40
printf("Enter first number: ") = 20
__isoc99_scanf(0x55efad499045, 0x7ffea2a6337c, 0, 0Enter first number: 1258952453
) = 1
printf("Enter second number: ") = 21
__isoc99_scanf(0x55efad499045, 0x7ffea2a63378, 0, 0Enter second number: -518109946
) = 1
printf("Enter third number: ") = 20
__isoc99_scanf(0x55efad499045, 0x7ffea2a63374, 0, 0Enter third number: -259054966
) = 1
putchar(116, 0xffffffff, 0, 0xffffff8c) = 116
putchar(33, 0x55efae9f62a0, 4, 3072) = 33
putchar(109, 0x55efae9f62a0, 8, 3072) = 109
putchar(51, 0x55efae9f62a0, 12, 3072) = 51
putchar(95, 0x55efae9f62a0, 16, 3072) = 95
putchar(33, 0x55efae9f62a0, 20, 3072) = 33
putchar(53, 0x55efae9f62a0, 24, 3072) = 53
putchar(95, 0x55efae9f62a0, 28, 3072) = 95
putchar(109, 0x55efae9f62a0, 32, 3072) = 109
putchar(48, 0x55efae9f62a0, 36, 3072) = 48
putchar(110, 0x55efae9f62a0, 40, 3072) = 110
putchar(51, 0x55efae9f62a0, 44, 3072) = 51
putchar(121, 0x55efae9f62a0, 48, 3072) = 121
putchar(10, 0x55efae9f62a0, 0, 3072t!m3_!5_m0n3y
) = 10
+++ exited (status 0) +++
FLAG : vishwactf{t!m3_!5_m0n3y}