思路:
拿到题目,使用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#b074d58a
flag:
flag{d780c9b2d2aa9d40010a753bc15770de}