本文记录了一道利用 C 语言伪随机数漏洞的经典 CTF 题解。由于程序未调用 srand() 设置随机数种子,导致 rand() 每次执行生成的初始随机数固定不变(在标准 glibc 环境中固定为 0x6b8b4567) 。利用异或运算的可逆特性,通过 key = random ^ 0xcafebabe 逆向推导出目标值,最终将其转换为十进制 2708864985 提交,轻松绕过 if 判断语句并获取 flag。解题思路非常清晰干脆! 本文记录了一道利用 C 语言伪随机数漏洞的经典 CTF 题解。由于程序未调用 srand() 设置随机数种子,导致 rand() 每次执行生成的初始随机数固定不变(在标准 glibc 环境中固定为 0x6b8b4567) 。利用异或运算的可逆特性,通过 key = random ^ 0xcafebabe 逆向推导出目标值,最终将其转换为十进制 2708864985 提交,轻松绕过 if 判断语句并获取 flag。解题思路非常清晰干脆!
Random
#include <stdio.h>
int main(){
unsigned int random;
random = rand(); // random value!
unsigned int key=0;
scanf("%d", &key);
if( (key ^ random) == 0xcafebabe ){
printf("Good!\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
return 0;
}
printf("Wrong, maybe you should try 2^32 cases.\n");
return 0;
}
调用一次 rand(),在未调用 srand() 的情况下是可预测的
根据(key ^ random) == 0xcafebabe
可以算出key = random XOR 0xcafebabe
scanf("%d", &key);其中%d是输入十进制数
所以我们要查看random的值

key = 0x6b8b4567 XOR 0xcafebabe = 2708864985


就ok了,很简单
This post has not been translated to English yet.
Random
#include <stdio.h>
int main(){
unsigned int random;
random = rand(); // random value!
unsigned int key=0;
scanf("%d", &key);
if( (key ^ random) == 0xcafebabe ){
printf("Good!\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
return 0;
}
printf("Wrong, maybe you should try 2^32 cases.\n");
return 0;
}
调用一次 rand(),在未调用 srand() 的情况下是可预测的
根据(key ^ random) == 0xcafebabe
可以算出key = random XOR 0xcafebabe
scanf("%d", &key);其中%d是输入十进制数
所以我们要查看random的值

key = 0x6b8b4567 XOR 0xcafebabe = 2708864985


就ok了,很简单