Pwnable.kr - random
Write-up for random in pwnable.kr.
0x00 Puzzle
Daddy, teach me how to use random value in programming!
ssh random@pwnable.kr -p2222 (pw:guest)
0x01 Explore
ssh into the Ubuntu and here we get:
$ ssh random@pwnable.kr 2222
random@ubuntu:~$ ls -l
total 20
-r--r----- 1 random_pwn root 49 Jun 30 2014 flag
-r-sr-x--- 1 random_pwn random 8538 Jun 30 2014 random
-rw-r--r-- 1 root root 301 Jun 30 2014 random.c
Obviously, we need to pwn the random to cat the flag file.
Take a glance at the random.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;
}
Basically, we need to input an int key so that key ^ rand() == 0xdeadbeef
.
I firstly considered using r2 to set breakpoint and looking at the value of random, let's do it.
$ r2 -d random
[0x7f13a99adcc0]> aaa
[0x7f13a99adcc0]> s main
[0x004005f4]> pdf
Here is the disassembling code of main function:

We can see that
- @0x00400601 it calls the rand() and the random return value is stored in $eax.
- @0x00400606 it move $eax to local variable random.
So we can set the breakpoint @0x00400606, then just look at the value of $eax.
[0x004005f4]> db 0x00400606
[0x004005f4]> dc
hit breakpoint at: 400606
= attach 45875 1
[0x004005f4]> dr eax
0x6b8b4567
We got that, which means if we input 0x6b8b4567 ^ 0xdeadbeef = 3039230856
, it should work.
Let's try.
[0x004005f4]> dc
3039230856
Good!
/bin/cat: flag: Permission denied
Seems we got it worked but since it's running by gdb and the gdb is under our random user's privilege which is not in root group.
So we have to run the binary in the home directory, but how can we know the rand() value without debugging it?
Then I run it many times in both gdb and r2 and I found that the value of rand() never changed.
That reminded me that this program does not even set seed before calling rand(), which means every time someone run the program, it always uses the same seed, I guess it's 0, no wonder it's predictable.
0x02 Solution and things learned
Now that we know the theory, just run the random binary and input 3039230856:
random@ubuntu:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...
Got it.
This is pretty straightforward. It warns us do not just use rand() in critical secured project because it's predictable.
At least, set a changeable seed value, like system time, before calling rand().