no-strings-attached
IDA打开,反编译主函数main
int __cdecl main(int argc, const char **argv, const char **envp)
{
setlocale(6, &locale); //locale = 0
banner();
prompt_authentication();
authenticate();
return 0;
}
其中各个函数如下:
int banner()
{
unsigned int v0; // eax
v0 = time(0);
srand(v0);
wprintf(&unk_80488B0); //Welcome to cyber malware control software.
rand();
return wprintf(&unk_8048960); //Currently tracking %d bots worldwide
/*-----------------------------------------------------*/
int prompt_authentication()
{
return wprintf(&unk_80489F8); //Please enter authentication details:
}
/*------------------------------------------------------*/
void authenticate()
{
wchar_t ws[8192];// [esp+1Ch] [ebp-800Ch]
wchar_t *s2;// [esp+801Ch] [ebp-Ch]
s2 = (wchar_t *)decrypt(&s, &dword_8048A90); //s2由decrypt函数加密而来
if ( fgetws(ws, 0x2000, stdin) ) //输入字符串ws
{
ws[wcslen(ws) - 1] = 0;
if ( !wcscmp(ws, s2) ) //字符串ws和s2比较 s2为flag
wprintf(&unk_8048B44);//Sucess! Welcome back!
else
wprintf(&unk_8048BA4);//Access dinied!
}
free(s2);
}
/*--------------------------------------------------*/
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; //这里的返回值dest就是s2的值,即flag
}
有两种方法可以获得flag,一种是分析decrypt()函数计算flag,另一种是动态调试。
这里使用动态调试的方法。
查看decrypt函数的汇编代码。
text:08048658 ; int __cdecl decrypt(wchar_t *s, wchar_t *)
.text:08048658 public decrypt
.text:08048658 decrypt proc near ; CODE XREF: authenticate+18↓p
.text:08048658
.text:08048658 var_1C = dword ptr -1Ch
.text:08048658 var_18 = dword ptr -18h
.text:08048658 var_14 = dword ptr -14h
.text:08048658 var_10 = dword ptr -10h
.text:08048658 dest = dword ptr -0Ch
.text:08048658 s = dword ptr 8
.text:08048658 arg_4 = dword ptr 0Ch
.text:08048658
.text:08048658 ; __unwind {
.text:08048658 push ebp
.text:08048659 mov ebp, esp
.text:0804865B push ebx
.text:0804865C sub esp, 34h
.text:0804865F mov eax, [ebp+s]
.text:08048662 mov [esp], eax ; s
.text:08048665 call _wcslen
.text:0804866A mov [ebp+var_14], eax
.text:0804866D mov eax, [ebp+arg_4]
.text:08048670 mov [esp], eax ; s
.text:08048673 call _wcslen
.text:08048678 mov [ebp+var_10], eax
.text:0804867B mov ebx, [ebp+s]
.text:0804867E mov eax, [ebp+s]
.text:08048681 mov [esp], eax ; s
.text:08048684 call _wcslen
.text:08048689 add eax, 1
.text:0804868C mov [esp], eax ; size
.text:0804868F call _malloc
.text:08048694 mov [ebp+dest], eax
.text:08048697 mov [esp+4], ebx ; src
.text:0804869B mov eax, [ebp+dest] #这里可以看到,dest值是传进了寄存器eax
.text:0804869E mov [esp], eax ; dest
.text:080486A1 call _wcscpy
.text:080486A6 mov [ebp+var_18], 0
.text:080486AD jmp short loc_80486F7
因为文件是ELF格式,所以需要使用到Linux系统内的gdb调试指令。
pwndbg插件安装使用方法可参考教程:https://www.csdn.net/tags/NtTagg1sMzA2MzYtYmxvZwO0O0OO0O0O.html以下为gdb调试指令:
(gdb) file a # file命令 读取文件(文件名为我随便重命名的a)
Reading symbols from a...(no debugging symbols found)...done.
(gdb) b decrypt # b 在decrypt处设置断点
Breakpoint 1 at 0x804865c
(gdb) r # r 运行程序(run) 显示在断点处停止
Starting program: /home/terra/11
Welcome to cyber malware control software.
Currently tracking 1092326991 bots worldwide
Breakpoint 1, 0x0804865c in decrypt ()
(gdb) n # n 单步步入
Single stepping until exit from function decrypt,
which has no line number information.
0x08048725 in authenticate ()
(gdb) x/5sw $eax # x就是查看内存内容 5表示查看的单元个数 s是以字符串形式 w是按字单元(word) $eax表示查看eax寄存器内容
0x804cfd0: U"9447{you_are_an_international_mystery}"
0x804d06c: U""
0x804d070: U""
0x804d074: U""
0x804d078: U""
直接可以看到flag:9447{you_are_an_international_mystery}