Writeup Cyber Threat Force : Take your time
For this challenge, we were given a TakeYourTime
executable, which seems to hang when we run it. We can analyze its code using ghidra:
unsigned int FLAG[] = {
0xb5, 0x63, 0x98, 0x3d,
0xb5, 0x06, 0x46, 0xba,
0x0f, 0xd5, 0x47, 0xce,
0x97, 0xef, 0x7b, 0x28,
0xdb, 0xe7, 0x39, 0x10,
0xb0, 0xf5, 0x44, 0xec,
0x30, 0x88, 0x46, 0xf6,
0x88,
};
undefined8 main(void) {
byte bVar1;
int iVar2;
uint local_28;
int local_24;
ulong local_20;
local_28 = 0;
local_20 = 0x32;
while (local_20 < 0x4f) {
bVar1 = fibonacci();
local_28 = local_28 >> 8 | (local_28 ^ bVar1) << 0x18;
local_20 = local_20 + 1;
}
srand(local_28);
local_24 = 0;
while (local_24 < 0x1d) {
bVar1 = FLAG[local_24];
iVar2 = rand();
putchar((uint)bVar1 ^ iVar2 % 0xff);
local_24 = local_24 + 1;
}
puts("\nGood you can validate the chall with this password ;)!");
return 0;
}
long fibonacci(long param_1) {
long lVar1;
long lVar2;
if (param_1 == 0) {
lVar1 = 0;
}
else {
if (param_1 == 1) {
lVar1 = 1;
}
else {
lVar2 = fibonacci(param_1 + -1);
lVar1 = fibonacci(param_1 + -2);
lVar1 = lVar1 + lVar2;
}
}
return lVar1;
}
What’s happening there is that the program takes too long to execute: the fibonacci implementation is a naive one (recursive).
Let’s be as lazy as possible and rewrite the program hardcoding the values that are needed:
#include <stdio.h>
#include <stdlib.h>
unsigned int fibo(unsigned int param) {
if (param == 50) return 12586269025;
if (param == 51) return 20365011074;
if (param == 52) return 32951280099;
if (param == 53) return 53316291173;
if (param == 54) return 86267571272;
if (param == 55) return 139583862445;
if (param == 56) return 225851433717;
if (param == 57) return 365435296162;
if (param == 58) return 591286729879;
if (param == 59) return 956722026041;
if (param == 60) return 1548008755920;
if (param == 61) return 2504730781961;
if (param == 62) return 4052739537881;
if (param == 63) return 6557470319842;
if (param == 64) return 10610209857723;
if (param == 65) return 17167680177565;
if (param == 66) return 27777890035288;
if (param == 67) return 44945570212853;
if (param == 68) return 72723460248141;
if (param == 69) return 117669030460994;
if (param == 70) return 190392490709135;
if (param == 71) return 308061521170129;
if (param == 72) return 498454011879264;
if (param == 73) return 806515533049393;
if (param == 74) return 1304969544928657;
if (param == 75) return 2111485077978050;
if (param == 76) return 3416454622906707;
if (param == 77) return 5527939700884757;
if (param == 78) return 8944394323791464;
return -1;
}
int main(void) {
unsigned int FLAG[] = {
0xb5, 0x63, 0x98, 0x3d,
0xb5, 0x06, 0x46, 0xba,
0x0f, 0xd5, 0x47, 0xce,
0x97, 0xef, 0x7b, 0x28,
0xdb, 0xe7, 0x39, 0x10,
0xb0, 0xf5, 0x44, 0xec,
0x30, 0x88, 0x46, 0xf6,
0x88,
};
unsigned int seed = 0;
for (unsigned int i = 0x32; i < 0x4f; i++) {
unsigned int res = fibo(i);
seed = seed >> 8 | (seed ^ res) << 0x18;
}
srand(seed);
for (unsigned int i2 = 0; i2 < 0x1d; i2++) {
unsigned int res = FLAG[i2];
putchar((unsigned int) res ^ rand() % 0xff);
}
puts("\n");
return 0;
}
$ gcc solve.c -o solve
... (lots of warnings)
$ ./solve
CYBERTF{Fuck_Fibo_3v3ryWhere}
Here we go, the flag is CYBERTF{Fuck_Fibo_3v3ryWhere}
.
You can view the sources on github or read other writeups.
Read other posts