no-strings-attached - wp
分析题目附件:
https://adworld.xctf.org.cn/media/task/attachments/554e0986d6db4c19b56cfdb22f13c834
ELF文件,32位。
拖入ida64,找main函数按F5(Fn+F5)查看伪代码:
int __cdecl main(int argc, const char **argv, const char **envp)
{
setlocale(6, &locale); //开辟内存空间
banner(); //输出
prompt_authentication(); //输入
authenticate(); //加密过程
return 0;
}
四个函数都跟进后发现,只有authenticate()函数有关键信息,所以直接分析authenticate()函数:
void authenticate()
{
wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch]
wchar_t *s2; // [esp+801Ch] [ebp-Ch]
s2 = (wchar_t *)decrypt(&s, &dword_8048A90); //decrypt表示加密
if ( fgetws(ws, 0x2000, stdin) ) //进行输入
{
ws[wcslen(ws) - 1] = 0;
if ( !wcscmp(ws, s2) ) //判断输入的ws是否等于加密过后的s2
wprintf((int)&unk_8048B44); //如果ws=s2,得到unk_8048B44,跟进得到success!
else
wprintf((int)&unk_8048BA4);
}
free(s2);
}
当 ws 和 s2 相等时,会输出正确结果,那么s2就是flag,而s2经过了decrypt()加密。
那么跟进decrypt()函数:
wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
size_t v2; // eax
signed int v4; // [esp+1Ch] [ebp-1Ch]
signed int i; // [esp+20h] [ebp-18h]
signed int v6; // [esp+24h] [ebp-14h]
signed int v7; // [esp+28h] [ebp-10h]
wchar_t *dest; // [esp+2Ch] [ebp-Ch]
v6 = wcslen(s);
v7 = wcslen(a2);
v2 = wcslen(s);
dest = (wchar_t *)malloc(v2 + 1);
wcscpy(dest, s);
while ( v4 < v6 )
{
for ( i = 0; i < v7 && v4 < v6; ++i )
dest[v4++] -= a2[i];
}
return dest;
}
它先把参数 s 复制给 dest,与就是s=dest,然后把 dest 的每个值减去 a2 的值,然后再返回加密后的 dest。那么,我们就把s与a2找出来,相减就得到flag。
跟进s:
选中按shift+E提取出来:
根据得到的信息写c脚本:
#include <stdio.h>
int main()
{
int x=0,i=0,j=0;
int 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,
};
int b[] =
{
1, 20, 0, 0, 2, 20, 0, 0, 3, 20,
0, 0, 4, 20, 0, 0, 5, 20, 0, 0,
};
while(i < 152)
{
x = s[i ++] - b[j ++ % 20];
if(x>32)
printf("%c",x);
}
return 0;
}
运行结果:
则 flag = 9447{you_are_an_international_mystery} 。