思路:
拿到题目,使用exeinfo查看
程序是64位的elf
拖入ida查看, 找到主函数按f5查看伪代码
程序读取了用户输入的字符串保存在byte_4080 ,将其重命名成input
又将input的长度赋值给了v4,将v4重命名成len
继续我往下看
有个if判断了input的长度是否等于25,不等于则退出程序
input和len别传入loc_1209,跟进去查看
发现一片红的,ida没有将这个函数识别出来,应该是程序添加了花指令,往下翻
在这边看到了两个指令jz和jnz
jz代表zf标志位为0时跳转
jnz代表zf标志位不为0时跳转
这两个指令都将跳转到13b0+1这个地址,而这个地址别ida识别成了指令
光标定位到这个地址,按下键盘上的U,取消定义
再选中c7,按下键盘上的C,将其转换成代码
这时候地址13b1就出来了,再将上面的E8给nop掉,因为程序经过jz和jnz会跳转到13b1这个地址,13b0这个地址并不会别执行,所以可以直接nop
选中函数头按下键盘上的P创建函数,再按f5, ida成功识别出来这个函数
查看这个函数
程序先初始化了v5,将~(i^a2)的值存入的v5 ,这里的a2是len
第二个循环翻译过来就是
for(j = 0; len > j; j++)
{
input[j] = v5[input[j]]
}这里将input的值作为v5的下标赋值给input
继续往下看,进入sub_160C函数查看
a1 a2 a3 分别是input &unk_4020 len
双击&unk_4020 查看
这就是加密的flag
这个函数将修改后的input和加密后的flag进行比较
看到这里已经可以逆向推算出flag了
我们只要在v5中找加密的flag,取它的下标就是flag
exp:
#include <stdio.h>
int main()
{
unsigned char enc[] =
{
0xD0, 0xD0, 0x85, 0x85, 0x80, 0x80, 0xC5, 0x8A, 0x93, 0x89,
0x92, 0x8F, 0x87, 0x88, 0x9F, 0x8F, 0xC5, 0x84, 0xD6, 0xD1,
0xD2, 0x82, 0xD3, 0xDE, 0x87
};
char table[256] = {0};
for(int i =0; i <= 255; i++)
{
table[i] = ~(i^25);
}
char flag[26] = {0};
for(int j = 0; 25 >j; j++)
{
for(int k = 0; k <= 255; k++)
{
if(enc[j] == table[k])
{
flag[j] = k;
}
}
}
printf("%s", flag);
return 0;
}运行结果
C:\Users\777\Desktop\reverse\NewStarCTF 2023 公开赛道\2>gcc Petals.c
C:\Users\777\Desktop\reverse\NewStarCTF 2023 公开赛道\2>a
66ccff#luotianyi#b074d58aflag:
flag{d780c9b2d2aa9d40010a753bc15770de}











