> For the complete documentation index, see [llms.txt](https://kunalwalavalkar.gitbook.io/write-ups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kunalwalavalkar.gitbook.io/write-ups/pwanable.kr/random.md).

# random

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

```c
#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;
}
```

As we can see the program generates a pseudo-`random` number (it isn't exactly random because no `seed` has been set).

The it takes in a `key` from the user.

If the XOR of the `key` and `random` results in `0xdeadbeef`, cat is called which prints out the flag.

Let's open the binary in gdb.

```
~$ gdb random
```

On disassembling `main`, we can see that it is calling `rand`.

```
(gdb) disass main
Dump of assembler code for function main:
=> 0x00000000004005f4 <+0>:     push   %rbp
   0x00000000004005f5 <+1>:     mov    %rsp,%rbp
   0x00000000004005f8 <+4>:     sub    $0x10,%rsp
   0x00000000004005fc <+8>:     mov    $0x0,%eax
   0x0000000000400601 <+13>:    callq  0x400500 <rand@plt>
   0x0000000000400606 <+18>:    mov    %eax,-0x4(%rbp)
   0x0000000000400609 <+21>:    movl   $0x0,-0x8(%rbp)
   0x0000000000400610 <+28>:    mov    $0x400760,%eax
   0x0000000000400615 <+33>:    lea    -0x8(%rbp),%rdx
   0x0000000000400619 <+37>:    mov    %rdx,%rsi
   0x000000000040061c <+40>:    mov    %rax,%rdi
   0x000000000040061f <+43>:    mov    $0x0,%eax
   0x0000000000400624 <+48>:    callq  0x4004f0 <__isoc99_scanf@plt>
   0x0000000000400629 <+53>:    mov    -0x8(%rbp),%eax
   0x000000000040062c <+56>:    xor    -0x4(%rbp),%eax
   0x000000000040062f <+59>:    cmp    $0xdeadbeef,%eax
   0x0000000000400634 <+64>:    jne    0x400656 <main+98>
   0x0000000000400636 <+66>:    mov    $0x400763,%edi
   0x000000000040063b <+71>:    callq  0x4004c0 <puts@plt>
   0x0000000000400640 <+76>:    mov    $0x400769,%edi
   0x0000000000400645 <+81>:    mov    $0x0,%eax
   0x000000000040064a <+86>:    callq  0x4004d0 <system@plt>
   0x000000000040064f <+91>:    mov    $0x0,%eax
   0x0000000000400654 <+96>:    jmp    0x400665 <main+113>
   0x0000000000400656 <+98>:    mov    $0x400778,%edi
   0x000000000040065b <+103>:   callq  0x4004c0 <puts@plt>
   0x0000000000400660 <+108>:   mov    $0x0,%eax
   0x0000000000400665 <+113>:   leaveq
   0x0000000000400666 <+114>:   retq
End of assembler dump.
```

We can set a break point at the instruction at `<+18>`.

The result of the `rand` call is stored in register $rax.

```
(gdb) x/s $rax
0x6b8b4567
```

Now we know that the randomly generated value was `0x6b8b4567` which in binary is `01101011100010110100010101100111`.

If we XOR it with `0xdeadbeef`, which is `11011110101011011011111011101111` in binary, we should get our answer.
