[攻防世界]进阶第三题666
第一步下载下来之后,拖入到查壳软件中,发现是一个64位的文件,无壳的软件,那么可以直接拖入到ida中进行分析。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+0h] [rbp-1E0h]
char v5; // [rsp+F0h] [rbp-F0h]
memset(&s, 0, 0x1EuLL);
printf("Please Input Key: ", 0LL);
__isoc99_scanf((__int64)"%s", (__int64)&v5);
encode(&v5, (__int64)&s);
if ( strlen(&v5) == key )
{
if ( !strcmp(&s, enflag) )
puts("You are Right");
else
puts("flag{This_1s_f4cker_flag}");
}
return 0;
}
开始寻找逻辑,把注释写上,你会发现一些信息和可以使用的数据,这里你发现,输入了一个值,这个值是v5,发现最后有一个flag值,提交了一下,发现不对,是一个假flag,之后算到了encode,意思是编码,那么跳转进去看看编码。
int __fastcall encode(const char *a1, __int64 a2)
{
char v3[32]; // [rsp+10h] [rbp-70h]
char v4[32]; // [rsp+30h] [rbp-50h]
char v5[40]; // [rsp+50h] [rbp-30h]
int v6; // [rsp+78h] [rbp-8h]
int i; // [rsp+7Ch] [rbp-4h]
i = 0;
v6 = 0;
if ( strlen(a1) != key )
return puts("Your Length is Wrong");
for ( i = 0; i < key; i += 3 )
{
v5[i] = key ^ (a1[i] + 6);
v4[i + 1] = (a1[i + 1] - 6) ^ key;
v3[i + 2] = a1[i + 2] ^ 6 ^ key;
*(_BYTE *)(a2 + i) = v5[i];
*(_BYTE *)(a2 + i + 1LL) = v4[i + 1];
*(_BYTE *)(a2 + i + 2LL) = v3[i + 2];
}
return a2;
}
这是一个算法,就出来了,稍微改下一下,flag就基本可以,按照第一个main函数,知道key的长度是18,enflag是izwhroz"“w"v.K”.Ni,那么直接改写,反向运算。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char v3[32]; // [rsp+10h] [rbp-70h]
char v4[32]; // [rsp+30h] [rbp-50h]
char v5[40]; // [rsp+50h] [rbp-30h]
int v6; // [rsp+78h] [rbp-8h]
int i; // [rsp+7Ch] [rbp-4h]
char a1[] = "izwhroz\"\"w\"v.K\".Ni";
i = 0;
v6 = 0;
for (i = 0; i < 18; i += 3)
{
v5[i] = (18 ^ a1[i]) - 6;
v5[i + 1] = (a1[i + 1] ^ 18) + 6;
v5[i + 2] = (a1[i + 2]^18)^6;
}
printf("%s", v5);
}
最后输出后面是存在乱码的,我们不需要那些乱码,只要前面正常flag的格式的。
最后获得到的flag值就是unctf{b66_6b6_66b}。