网安课挑战:如何破解srand(time(0))生成的秘密数字?代码解析
代码含义与破解方法
代码逐行解释
先贴出目标代码:
#include <stdlib.h> #include <time.h> #include <stdio.h> void init() { setbuf(stdin, NULL); setbuf(stdout, NULL); } int main() { init(); srand(time(0)); int secret = 0; puts("Your secret: "); scanf("%d", &secret); if(secret == rand()) { system("/bin/sh"); } else { puts("failed"); } }
核心组件说明
- 头文件:
<stdlib.h>:提供rand()(生成随机数)、srand()(初始化随机数种子)、system()(执行系统命令)的函数声明<time.h>:提供time()函数,用于获取当前秒级时间戳<stdio.h>:提供puts()(输出字符串)、scanf()(读取输入)等IO操作函数
init()函数:setbuf(stdin, NULL)和setbuf(stdout, NULL):关闭标准输入输出的缓冲区,让输入输出立即生效,避免缓冲导致的交互延迟问题
main()函数逻辑:- 调用
init()完成IO初始化 srand(time(0)):用当前秒级时间戳作为随机数生成器的种子,这是整个程序的关键漏洞——同一秒内种子固定,生成的随机数序列完全可预测- 提示用户输入
secret,并读取输入的整数 - 对比输入值与
rand()生成的第一个随机数,若匹配则执行/bin/sh获取shell权限,否则输出failed
- 调用
如何找到秘密数字
核心利用rand()的种子可预测性,步骤如下:
- 生成匹配的随机数:编写一个简单程序,用和目标程序相同的种子生成第一个随机数:
#include <stdlib.h> #include <time.h> #include <stdio.h> int main() { srand(time(0)); printf("%d\n", rand()); return 0; } - 同步时间输入:编译运行上述程序,得到的数字就是目标程序当前秒内的
rand()输出值,必须在同一秒内将该数字输入到目标程序中(因为每秒时间戳会变化,种子也会跟着变) - 自动化优化(可选):如果手动输入来不及,可以写脚本自动化流程——先获取当前秒的随机数,再自动将数值传入目标程序,确保操作在同一秒完成
内容的提问来源于stack exchange,提问作者Peter Harry
相关产品推荐
相关产品推荐

