OneShell

I fight for a brighter tomorrow

0%

[pwnable.kr] random

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

ssh random@pwnable.kr -p2222 (pw:guest)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
random@pwnable:~$ ls -al
total 40
drwxr-x--- 5 root random 4096 Oct 23 2016 .
drwxr-xr-x 117 root root 4096 Nov 10 2022 ..
d--------- 2 root root 4096 Jun 30 2014 .bash_history
dr-xr-xr-x 2 root root 4096 Aug 20 2014 .irssi
drwxr-xr-x 2 root root 4096 Oct 23 2016 .pwntools-cache
-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

random@pwnable:~$ cat 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;
}

使用rand函数前没有使用srand设置随机数种子seed,那么只要编译一个类似的程序就可以获得默认seed、rand产生的随机数值了。

在目录/tmp/创建一个自己账号的文件夹own,然后新增一个randm.c如下,使用gcc编译后可以获得默认seed产生的第一个随机数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
random@pwnable:/tmp/own$ cat random.c
#include <stdio.h>

int main(){
unsigned int random;
random = rand(); // random value!
printf("random=%d", random);
return 0;
}

random@pwnable:/tmp/own$ gcc random.c -o random
random.c: In function ‘main’:
random.c:5:11: warning: implicit declaration of function ‘rand’ [-Wimplicit-function-declaration]
random = rand(); // random value!
^
random@pwnable:/tmp/own$ ./random
random=1804289383

接下来就是计算key值:

1
2
key ^ random == 0xdeadbeef
key = random ^ 0xdeadbeef = 1804289383 ^ 0x0xdeadbeef = 0xB526FB88 = 3039230856
1
2
3
4
5
random@pwnable:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...
random@pwnable:~$

知识点

Linux下使用rand函数会返回一个随机值,范围从0到RAND_MAX。在使用的时候必须提前使用srand设置好随机数种子seed,如果没有设置seed,rand在调用的时候会自动设置seed为1,此时rand函数产生的随机数值就会一样。日常使用中,通常使用getpid或者time的返回值来作为seed。pwnable这道题目中就是因为没有设置seed,导致rand产生的随机数可以被获取。使用相同的种子调用rand函数,会产生相同的随机数序列。

如下是一个正确的随机数序列生成代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
int i, n;
srand(time(0)); // 设置随机数种子为当前时间

printf("请输入要生成的随机数个数:");
scanf("%d", &n);

printf("随机数序列:");
for (i = 0; i < n; i++) {
printf("%d ", rand());
}

return 0;
}