新手赛cut

2019-03-21  本文已影响0人  杰_74

百度云链接:https://pan.baidu.com/s/1OVHaQdDduI5NEWLMx75-lQ
提取码:v6ac

把exe文件丢进64位IDA,使用F5大法

v17 = __readfsqword(0x28u);
printf("Please input your flag:", argv, envp);
scanf("%s", &v7);
*v8 = 0LL;
memset(&v9, 0, 0x58uLL);
v10 = 0;
*v11 = 0LL;
memset(&v12, 0, 0x58uLL);
v13 = 0;
*v14 = 0LL;
memset(&v15, 0, 0x58uLL);
v16 = 0;
_substr666(v8, &v7, 0, 6);
_substr666(v11, &v7, 7, 6);
v3 = &v7;
_substr666(v14, &v7, 6, 1);
v4 = 0;
if ( _0x233333(v8) )
{
v3 = &v6;
if ( _0x666666(v11, &v6) )
{
if ( _0x8048000(v14) )
v4 = 1;
}
}
if ( v4 )
printf("Unbelievable! Congratualation!", v3);
else
printf(aSorryTryAgain, v3);

我们可以知道v7是我们的flag
往下看_substr666()这个函数出现了很多次,我们点进去看看

__int64 __fastcall _substr666(char *a1, char *a2, int a3, int a4)
{
int v4; // eax
int v6; // [rsp+20h] [rbp-8h]
int i; // [rsp+24h] [rbp-4h]
v6 = 0;
for ( i = a3; a4 + a3 > i; ++i )
{
v4 = v6++;
a1[v4] = a2[i];
}
return 0LL;
}

我们可以看出666这个函数就是把字符串a2从下标a3开始,数a4位数放到a1里。
_substr666(v8, &v7, 0, 6);//把v7从下标0开始把6位数放到v8
_substr666(v11, &v7, 7, 6);//把v7从下标7开始把6位数放到v11
_substr666(v14, &v7, 6, 1);//把v7[6]放到v14

如果v4为真则正确,那么
_0x233333(v8) ,_0x666666(v11, &v6)和_0x8048000(v14) 为真。
点进去233333函数

_BOOL8 __fastcall _0x233333(char *a1)
{
//此处省略某些不重要的定义
v7 = __readfsqword(0x28u);
*s2 = 0LL;
memset(&v5, 0, 0x58uLL);
v6 = 0;
_substr666(s2, str, 7, 6);
for ( i = 0; i < strlen(a1); ++i )
s1[i] = (a1[i] + 4) ^ 2;
return strcmp(s1, s2) == 0;
}

把从str[7]开始数六位放进s2,那么str是什么呢,点进去是一堆字符vosng%_Ngemkt,要使s1,s2相同,那么v8通过简单的异或加密可得到s1。
回到上一级,点进去666666函数

BOOL8 __fastcall _0x666666(char *a1, char *a2)
{
//此处省略某些不重要的定义
v11 = __readfsqword(0x28u);
v3 = 0;
*s = 0LL;
memset(&v9, 0, 0x58uLL);
v10 = 0;
_substr666(s, str, 0, 6);
for ( i = 0; i < strlen(s); ++i )
a2[i] = s[i];
for ( j = 0; j < strlen(s); ++j )
v7[j] = a1[j] + j - 1;
for ( k = 0; k < strlen(s); ++k )
{
if ( v7[v3] == a2[v3] )
++v3;
}
return v3 == strlen(s);
}

再次使用666函数 _substr666(s, str, 0, 6);//把从str[0]开始数6位放入s,再放入a2,让a1即v11经过这一步“v7[j] = a1[j] + j - 1;”后与a2相等

_0x8048000(v14)函数就更简单了

_BOOL8 _fastcall 0x8048000(char *a1)
{
return strcmp(a1, "
") == 0;//v14就是'
'
}

综上所述,flag分为三段,前6位对应v8,中间是v14即‘_’,后六位对应v11
脚本如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
    
    char a[]={"vosng%_Ngemkt"};
    for(int i=7;i<7+6;i++)
    {
       cout<<char((a[i]^2)-4);
    }   
    cout<<"_";
    for(int i=0;i<6;i++)
    {
       cout<<char(a[i]+1-i);
    } 
    return 0;
} 
image.png

flag格式为gwht{}
所以最终flag为gwht{Hacker_world!}

上一篇 下一篇

猜你喜欢

热点阅读