I got the CTF zoomies so I’m moving right along to the ‘random’ challenge in the Pwnable.kr “Toddler’s Bottle” CTF series. Our hint is:

Daddy, teach me how to use random value in programming!

ssh random@pwnable.kr -p2222 (pw:guest)

If we ssh in and print out the random.c file, we see:

```
random@ubuntu:~$ cat random.c
#include
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;
}
```

## lol im so random

You’ve likely heard about random not being actually, truly random. I experienced this during a recent hobby project where I forgot to provide the rand() function with a seed, and got the same value every time.

If we make our own file in a tmp folder:

```
$ mkdir /tmp/jl
$ cd /tmp/jl
$ vi randtest.c
```

Let’s make our own copy of the program, and use it to print up the output to rand().

```
#include
int main(){
unsigned int random;
random = rand(); // random value!
printf("random is %x\n", random);
return 0;
}
```

We compile it:

```
$ gcc randtest.c -o randtest
```

If we run it:

```
random@ubuntu:/tmp/jl$ ./randtest
6b8b4567
```

And we run it again, and again, and again:

```
random@ubuntu:/tmp/jl$ ./randtest
6b8b4567
random@ubuntu:/tmp/jl$ ./randtest
6b8b4567
random@ubuntu:/tmp/jl$ ./randtest
6b8b4567
```

Just like I thought… not very random. It’s the same value every time.

## What’s this ^ thing about?

So we have the not-random value of `random`

. We know that we have to enter a `key`

value to get past this `if`

statement:

```
if( (key ^ random) == 0xdeadbeef ){
```

The ^ symbol is the bitwise XOR operator in C. XOR is the equivalent of the English “or”… meaning “one or the other, but not both.” Alternatively, bitwise OR is “one or the other or both.”

The equation being bitwise XOR allows us to solve for `key`

.

Here’s an example of how XOR works with a small set of numbers:

```
a = 00101010
b = 10100110
a ^ b = 10001100
```

We can see that:

```
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
```

## 0xdeadbeef

If we convert 0xdeadbeef into binary, we get `11011110101011011011111011101111`

.

If we convert 0x6b8b4567 (“random”), we get `01101011100010110100010101100111`

.

There’s probably a quicker way to do this, but I lined the values up and solved for key (the top line) by hand. Then I checked my math using this calculator, since my first couple tries didn’t work with my computed value.

```
1011 0101 0010 0110 1111 1011 1000 1000 # key
0110 1011 1000 1011 0100 0101 0110 0111 # "random" value
1101 1110 1010 1101 1011 1110 1110 1111 # deadbeef
```

I convert key into decimal, which is 3039230856. Then, I run the program again, and provide the `key`

value, and voila!

```
random@ubuntu:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...
```