PoliCTF RE200 – REVERSEMEPLZ

This is a 32 bit binary which validates a key. Removing the dead codes, this is what the algorithm looks like:

for (size_t i = 0; i < 0xF; i++) {
if (key[i] < 'a') key[i] = transform(key[1] & 1);
if (key[i] > 'z') key[i] = transform(key[1] & 2);
dec[i] = transform(key[i]);
if (dec[i] != 0xCF && dec[i] > 0xCC) flag = true;
}

if (flag) return 0;

for (size_t i = 1; i < 0xF; i++) {
if (dec[i] - dec[i-1] != diff_array[i]) return 0;
}

return transform(key[0]) == 'b';
So the key length is 15 bytes. The first byte of key is transformed to 'b'. The function at 0x08048519 takes single byte as input and gives a single byte output. Considering all ascii small letters as input, one can create transformation table. If that doesn't work, assume key[1] value and build table for ascii printables under transform(0), transform(1) or transform(2)

Below is the solution:


int8_t flag[16] = {0};
int8_t table[256][1] = {0};

int main(int argc, char **argv)
{
for (size_t c = 97; c <= 122; c++)
table[transform(c)][0] = c;

flag[0] = table['b'][0];

for (size_t i = 0; i < 14; i++)
flag[i+1] = table[table[flag[i]][0] + diff_array[i]][0];

printf("%s\n", flag);
return 0;
}
Flag for the challenge is flag{onetwotheflagyo}. Full source is found here