本文记录了一道利用 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的值

image

key = 0x6b8b4567 XOR 0xcafebabe = 2708864985

image
image

就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的值

image

key = 0x6b8b4567 XOR 0xcafebabe = 2708864985

image
image

就ok了,很简单