[NISACTF 2022]string
[NISACTF 2022]string

题目链接:https://www.nssctf.cn/problem/2042
题目flag标准:以NSSCTF{}包裹
打开题目,下载附件
常规逆向流程,拿到一个可执行文件之后第一步便应该用exeinfo或peid这样的查壳工具扫一下。
可以看到,工具显示了这是Linux下的可执行文件elf,并且是64位的。
而且没有加壳。

将文件拖进64位ida分析

必须判断文件位数选择相应位数的ida,否则ida反编译会报错。
快捷键(Shift+F12)打开字符串窗口查看一下都有哪些字符串

分析发现两个关键字符串
第一个是:The length of flag is 13
第二个是:NSSCTF{
第一个英文翻译过来就是:这个flag长度为13
第二个即flag标识,题目要求就是flag必须以NSSCTF{}包裹。
双击NSSCTF{进入只读变量段查看。
这里科普一下只读常量段是什么,顾名思义。只读常量就是存放文件中的常量的段,比如字符串。

双击常量名format,并按交叉引用快捷键(x)查看引用函数。
这里科普一下什么是交叉引用。交叉引用即是ida分析在哪些地方调用了这个函数,亦或者读或写了这个量。

可以看到只有一个地方引用了这个常量。
双击引用项,进入引用的函数查看。

按快捷键(F5)反编译汇编代码
反编译就是将汇编代码翻译成编译前的类C语言代码,不过只是近似而且不能运行所以称为伪代码


分析伪代码,发现下面都是混淆代码直接忽略。
之所以认为它们混淆代码是因为我们发现下面有一个printf函数输出NSSCTF标准头,这就是flag的开头。
所以我们只需要查看这段代码有什么被影响的量就行。
分析发现,所有变量在这部分代码中都被重新赋值。
因此其他代码并不能影响这部分代码。
因此,可以直接忽略。

这些才是核心代码内容

printf函数先输出一个flag为13长度的字符串
srand函数表示设置随机数种子
seed表示一个变量,为srand参数。
值为十六进制数:0x2766h
科普一下srand函数和rand函数:rand函数用于生成伪随机数,srand函数用于给rand函数设置随机数种子。rand函数通过对种子的一系列计算得到随机数序列。如果不使用srand函数设置种子,则种子默认为1。每次程序执行时,如果种子相同,那么生成的随机数序列也是相同的。

之后printf函数,输出一个flag标准头。
猜测下面就是flag具体内容。
然后一个for循环,循环13次, 每次输出一个rand生成的随机数,并将随机数模8+1转为无符号整数并以十进制整数输出。
下面一个putchar函数输出125,但是putchar函数表示输出一个字符,即输出这个数根据ASCII码翻译成字符的内容。

即右括号
根据核心代码编写exp
直接将题目的运算逻辑照搬过来,只需要将随机数种子设置成题目的值就可以拿到flag。
#include<stdio.h>
int main(){
seed=0x2766;
srand(seed);
printf("NSSCTF{");
for(int i=0;i<13;i++){
int v4=rand();
printf("%d",(unsigned int)(v4%8+1));
}
printf("}\n");
return 0;
}

浙公网安备 33010602011771号