## pwnable.kr [Part I] Random

#### Sept. 29, 2020 // echel0n

It is a really easy challenge but enjoyable.
When we look the source code, this line seems weird:

```random = rand();	// random value!
```

Let's check the description of rand() function.

```int rand(void):
returns a pseudo-random number in the range of 0 to RAND_MAX.
RAND_MAX: is a constant whose default value may vary
between implementations but it is granted to be at least 32767.
```

But we can see that, it declared without a seed.

```The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand().
These sequences are repeatable by calling srand() with the same seed value.
If no seed value is provided, the rand() function is automatically seeded with a value of 1.
```

So, it is generating the same number all the time. Easy solution would be inserting a printf() call and run the binary on your machine.

```unsigned int random;
random = rand();	// random value!
printf("%d", random);
```
```gcc source.c -o random
```
```\$ ./random
1804289383
```

It yields the generated number now.

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

We can XOR the generated number with 0xdeadbeef to get key.

```>>> 1804289383 ^ 0xdeadbeef
3039230856
>>>
```

The result is our key.

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

The other way, let's assume that we dont own the source code. So, we will use a debugger.

```0x00000000000011dd <+84>:	call   0x1070 <__isoc99_scanf@plt>

0x00000000000011e2 <+89>:	mov    eax,DWORD PTR [rbp-0x10]
0x00000000000011e5 <+92>:	xor    eax,DWORD PTR [rbp-0xc]
0x00000000000011ed <+100>:	jne    0x1213 <main+138>
0x00000000000011ef <+102>:	lea    rdi,[rip+0xe15]        # 0x200b
0x00000000000011f6 <+109>:	call   0x1030
0x00000000000011fb <+114>:	lea    rdi,[rip+0xe0f]        # 0x2011
0x0000000000001202 <+121>:	mov    eax,0x0
0x0000000000001207 <+126>:	call   0x1050 <system@plt>
```

After scanf() the binary compares two value (11e8: cmp eax, 0xdeadbeef), they are located at [rbp-0x10] and [rbp-0xc] We can put a breakpoint there and check these.

```gef➤  print \$rbp-0x10
\$1 = (void *) 0x7fffffffe820
gef➤  print *0x7fffffffe820
\$2 = 0x0
gef➤  print \$rbp-0xc
\$3 = (void *) 0x7fffffffe824
gef➤  print *0x7fffffffe824
\$4 = 0x6b8b4567
gef➤  print/d *0x7fffffffe824
\$5 = 1804289383
gef➤
```

We got the same value again but at this time we grabbed that from our memory.