Challenge Problem :
“Strip my statically linked clothes off”
The given executable is statically linked and stripped which means reversing will be a bit tougher. However, “main” isn’t too complicated and so we’ll be able to guess what functions are used.
undefined8 FUN_00400b4d(void)
{
char cVarl;
uint uVar2;
int iVarl;
undefined8 uVar3;
undefined8 uVar4;
byte bVar2;
uVar2 = fc_1(0);
fc_2((ulong)uVar2); uVar3 = fc_3("flag.txt",aDAT_00492aa4);
uVar4 = fc_3("out.txt",GDAT_00492aaf);
while( true )
{ cVarl = fc 4();
if (cVarl = -1) break;
iVarl = fc_5();
bVar2 = cVarl A (char)iVarl + (char)(iVarl /0x666) * -0x66 + 1U;
fc_6(bVar2,(char)uVar4,bVar2);
fc_7(uVar3);
1 fc_7(uVar4);
return 0;
Unique disassembled functions from top to bottom:
- syscall with eax=0xc9 (time syscall) – time.
- uses the time as a parameter – srand.
- takes filename as first parameter – fopen.
- takes FILE* as input, return value is compared with EOF (-1) – fgetc.
- does not accept parameters return value is used, uses shared global variables with srand – rand.
- number of parameters is off, the function uses output’s FILE* and a manipulated value – fputc.
- FILE* parameter, return value unused – fclose
Renaming to :
{
char c;
uint t;
int rand_num;
FILE *flag;
FILE *out;
t = time((time t *)0x0);
srand((uint)_t);
flag = (FILE *)fc_3("flag.txt",&DAT_00492aa4);
out = (FILE *)fc_3("out.txt",‘DAT_00492aaf);
while( true ) {
_c = fgetc(flag);
if ((char)_c = -1) break;
rand_num = rand();
fputc((int)(char)_c A rand_num % 0x666 + 1U,out);
fclose(flag);
fclose(out);
return 0;
}
As you can see, the actions of the binary are much more clear.
it seeds with time(0), reads characters from the flag one by one
and then xors them with a random value between 1 and 666. Since the challenge is given to us inside a .rar -, we can use the modification time of out.txt to guess the time that was passed to the srand.
$ stat -c %Y out.txt
1586541672
1586541672 is the timestamp we can use to start guessing with.
int main() { FILE *out = fopen("out.txt", "r"); char buff[35] = {0}, test[35] = {0}; fread(buff, 1, 34, out); unsigned int t = 1586541672; do { srand(t--); for(char i = 0; i < 6; i++) test[i] = buff[i] ^ rand() % 0x666 + 1; } while(strcmp(test, "hexCTF")); srand(t + 1); for(char i = 0; i < 34; i++) test[i] = buff[i] ^ rand() % 0x666 + 1; printf("%s\n", test); fclose(out); }
The script then prints our flag :
hexCTF{nam3s_ar3_h4rd_t0_r3m3mb3r}