收获

  • 注意随机数产生函数 srand(),是由函数 rand 使用的随机数发生器

在给定随机数种子 seed 时,srand(seed) 是按照种子 seed 生成伪随机数,并非真的随机,其实每次运行结果都是一样的

  • 当执行产生随机数的代码时,尽量在 Linux 下执行代码,在 Windows 下产生的随机数可能会不一样

【NISACTF】string


思路

拖入 IDA 查看 main 函数

NISACTF-string1.png

输入字符串 v4,然后调用 flag() 函数

查看 flag() 函数:

NISACTF-string2.png

在下半部分发现一段直接输出 flag 的代码:

puts("The length of flag is 13");
srand(seed);
printf("NSSCTF{");
for ( m = 0; m < 13; ++m )
{
  v4 = rand();
  printf("%d", (v4 % 8 + 1));
}
putchar(125);

这里的 putchar(125) 就是输出 "}" ,for 循环内的 printf() 输出就是输出的 flag

查看种子 seed 的初值: seed = 0x2766

NISACTF-string3.png

这里 seed = 0x2766 定义了随机数种子, srand(seed) 是按照种子 seed 生成伪随机数,并非真的随机,其实每次运行结果都是一样的

直接跑一遍代码:

#include <iostream>  
#include <string.h>  
using namespace std;  
  
int main() {  
    int v4;  
    int seed = 0x2766;  
    srand(seed);  
  
    printf("NSSCTF{");  
    for (int m = 0; m < 13; ++m) {  
        v4 = rand();  
        printf("%d", (v4 % 8 + 1));  
    }  
    putchar(125);  
}

在 Windows 上的运行结果:

NISACTF-string4.png

但是这个答案是错误的

这是一个坑点,不能使用 Windows 运行这段代码,因为生产出的随机数不一样

在 Kali Linux 上执行该代码:

NISACTF-string5.png

编译并执行:

NISACTF-string6.png

这个结果是正确的


脚本

#include<stdio.h>
int main()
{
	int seed = 0x2766;
	srand(seed);
	printf("NSSCTF{");
	for ( int l = 0; l < 13; ++l )
	{
		int v4 =rand();
		printf("%d", (unsigned int)(v4 % 8 + 1));
	}
	printf("}\n");
	return 0;
}

结果

NSSCTF{5353316611126}

NISACTF-string7.png