random

random is the 6th challenge of Toddler's Bottle at pwnable.kr

Pseudo-random value without seed

First, let's analise the source of the challenge.

#include <stdio.h>

int main(){
	unsigned int random;
	random = rand();	// random value!

	unsigned int key=0;
	scanf("%d", &key);

	if( (key ^ random) == 0xdeadbeef ){
		printf("Good!\n");
		system("/bin/cat flag");
		return 0;
	}

	printf("Wrong, maybe you should try 2^32 cases.\n");
	return 0;
}

The program is extremely simple, it initializes a random value using rand(), which uses a static seed, different from srand(), that reads an argument as the seed to do generate pseudo-random values. Therefore, we can generate the random number locally using rand().

After generating the pseudo-random value, the program XORs it with a user provided key, and if the output matches 0xdeadbeef, the flag is returned. If you know how a XOR work you also know they are reversible operations, which means a^b=c <=> (c^a=b and c^b=a). With that in mind and knowing the value of the pseudo-random number, we can XOR it with 0xdeadbeef to extract the key.

Final Exploit

#include <stdio.h>

int main(){
    unsigned random = rand(0xdeadbeef); //static seed
    unsigned key = random ^ 0xdeadbeef;
    unsigned proof = key ^ random;
    printf("Random: %u\n",random);
    printf("Key: %u\n", key);
    printf("Proof: 0x%x\n", proof);
    return 0;
}

I used the code above to generate the correct key.

Last updated