random - pwnable
1.获取题目
我们先用ssh链接上pwnable的服务器获取题目。在终端输入ssh random@pwnable.kr -p2222
,出现提示后输入密码guest
查看目录下有的文件以及文件权限ls -l
2. 运行程序、查看文件类型、保护措施
没有任何提示输出,直接要求输入。输入随机字符串后,提示:错误,请尝试2^32 cases
查看文件的基本信息:64位动态链接的ELF
查看文件的保存措施:有NX(数据执行保护)
3.分析源码
题目有给出源码,查看源码: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;
}
首先从源码来看,如果第十行的if条件成立,那么就可以读取flag文件。if语句中的按位异或运算,在我们知道random值后,就可以逆推出key的值,也就是我们应该输入的值。
而random是一个随机数,正常情况下每次运行的值都是不一样的,但程序中的random是一个伪随机数,也就是说每次运行所生成的值都是一样的。
rand(),是C语言中用来产生一个随机数的函数;
每次rand()生成随机数时,都会调用srand(seed)来初始化它的起始值。如果没有设置seed,那么系统自动给seed赋值,一般为1。
种子seed相同,产生的随机数也就会相同。
----参考于C语言中的rand()函数
那么程序中并没有设置seed,因此每次程序运行都是同一个seed,生成同一个随机数random
我们可以gdb调试看看:断点设置在0x400609(将random压栈)
random在距离栈底0x4位置(0x7fffffffdef4)开始写入
第一次运行:
第二次运行:
那我们就确定了random的值是:0x6b8b4567
;推出key(我们输入值)为:3039230856
4. 总结
-
随机数生成函数rand(),需要搭配动态变化种子seed,否则生成的是伪随机数。
seed决定生成的随机数,seed相同随机数相同。