Nameless
Reverse Engineering ·Description:
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
witheax=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 :
Flag: hexCTF{nam3s_ar3_h4rd_t0_r3m3mb3r}