九:no-strings-attached
首先利用下载附件,使用EXEinfo PE查看文件类型 为32位
利用IDA打开,找到主函数查看伪代码
对比比较发现 最后一个函数与flag有关
不难分析出s2就是我们所需得flag
decrypt是包装加码,我们点击跟踪
它先把参数 s 复制给 dest,与就是s=dest,然后把 dest 的每个值减去 a2 的值,然后再返回加密后的 dest。那么,我们就把s与a2找出来,相减就得到flag。
跟进s:
shift+E 如下:
得到以下代码
int main()
{
unsigned char s[] =
{
58, 20, 0, 0, 54, 20, 0, 0, 55, 20,
0, 0, 59, 20, 0, 0, 128, 20, 0, 0,
122, 20, 0, 0, 113, 20, 0, 0, 120, 20,
0, 0, 99, 20, 0, 0, 102, 20, 0, 0,
115, 20, 0, 0, 103, 20, 0, 0, 98, 20,
0, 0, 101, 20, 0, 0, 115, 20, 0, 0,
96, 20, 0, 0, 107, 20, 0, 0, 113, 20,
0, 0, 120, 20, 0, 0, 106, 20, 0, 0,
115, 20, 0, 0, 112, 20, 0, 0, 100, 20,
0, 0, 120, 20, 0, 0, 110, 20, 0, 0,
112, 20, 0, 0, 112, 20, 0, 0, 100, 20,
0, 0, 112, 20, 0, 0, 100, 20, 0, 0,
110, 20, 0, 0, 123, 20, 0, 0, 118, 20,
0, 0, 120, 20, 0, 0, 106, 20, 0, 0,
115, 20, 0, 0, 123, 20, 0, 0, 128, 20,
0, 0
};
unsigned char a[] =
{
1, 20, 0, 0, 2, 20, 0, 0, 3, 20,
0, 0, 4, 20, 0, 0, 5, 20, 0, 0
};
int v4 = 0;
int v6 = sizeof(s);
int v7 = sizeof(a);
while (v4 < v6)
{
for (int i = 0;i < v7 &&v4 < v6;++i)
{
printf("%c", s[v4++] - a[i]);
}
}
return 0;
}
得出 9447{you_are_an_international_mystery}。
十:电脑报错无法下载文件,后期有机会补上。
十一:getit
首先利用下载附件,使用EXEinfo PE查看文件类型 为64位
利用IDA打开,找到主函数查看伪代码
我们分析代码:
1~11 变量定义初始化
12~20 定义flag值
20~34 flag值写入文件
关键在于s和t的值,我们继而跟踪
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#pragma warning(disable:4996)
int main(void)
{
char v3;
__int64 v6;
char s[] = "c61b68366edeb7bdce3c6820314b7498";
char t[] = "harifCTF{????????????????????????????????}";
v6 = 0;
while (v6 < strlen(s)) {
if (v6 & 1)
v3 = 1;
else
v3 = -1;
*(t + v6 + 10) = s[v6] + v3;
v6++;
}
printf("%s", t);
system("PAUSE");
return 0;
}
得到答案:SharifCTF{b70c59275fcfa8aebf2d5911223c6589}
十二:maze
首先利用下载附件,使用EXEinfo PE查看文件类型 为64位
老规矩,利用IDA打开,我们shift+F12,好像没有多大用处
我们找到主函数按下F5查看伪代码
接下来我们分析代码,看到 v8 = "Congratulations!";我们就以此位突破口,跟进asc_601060
v10 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != 24 || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + 24) != 125 )
{
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v4 = 5LL;
if ( strlen(&s1) - 1 > 5 )
{
while ( 1 )
{
v5 = *(&s1 + v4);
v6 = 0;
if ( v5 > 78 )
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == 79 )
{
v7 = sub_400650((char *)&v10 + 4, v3);
goto LABEL_14;
}
if ( v5 == 111 )
{
v7 = sub_400660((char *)&v10 + 4, v3);
goto LABEL_14;
}
}
else
{
v5 = (unsigned __int8)v5;
if ( (unsigned __int8)v5 == 46 )
{
v7 = sub_400670(&v10, v3);
goto LABEL_14;
}
if ( v5 == 48 )
{
v7 = sub_400680(&v10, v3);
LABEL_14:
v6 = v7;
goto LABEL_15;
}
}
LABEL_15:
v3 = (const char *)HIDWORD(v10);
if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) )
goto LABEL_22;
if ( ++v4 >= strlen(&s1) - 1 )
{
if ( v6 )
break;
LABEL_20:
v8 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( *(&asc_601060[8 * (signed int)v10] + SHIDWORD(v10)) != 35 )
goto LABEL_20;
v8 = "Congratulations!";
LABEL_21:
puts(v8);
return 0LL;
}
这是一个迷宫题,跟进asc_601060,看来这里存储的是迷宫图,数了下长度为64
可以了解一下:迷宫问题 - CTF Wiki,
迷宫里面刚好有一个#查一下35的ASCII为#最后是要走到这里才能输出Congratulations!
我们继续跟进函数,可以发现其为走的方式,即控制键。
然后看到这个函数
点击打开
查了下ASCII码35是#,32是‘ ’(空格) ,意思就是说必须要按着路径来走,不能走到障碍物上,然后看这句
result = *(unsigned __int8 *)(a1 + a2 + 8LL * a3);,迷宫存储是一个一维数组,但是一定是按二维数组来使用,从这句代码中推出每一行是8个字符,然后将那段迷宫按8个字符一行来划分。
————————————————
原文链接:https://blog.youkuaiyun.com/ookami6497/article/details/118710301
这个就是最后的地图
按照此方法走出迷宫 右下右右下下左下下下右右右右上上左左
最后对应的flag为:nctf{o0oo00O000oooo..OO}