本道题主要是base64解密的魔改所以要清楚的知道base64的加解密的原理(这里可以去看小新的前一篇的解题文章),还要了解一些宏定义的函数。
解题思路:
题目给的是一个exe文件先双击运行一下,随便输入一些东西发现有回显,再进行查壳。
发现是一个32位的程序,直接用32位的IDA打开,F5查看主函数
初步分析主函数代码可得,就是把flag输入然后被v15接收,然后又把v15当作sub_401520函数的参数,分析到这里大概可以猜到flag被sub_401520函数加密了,加密后成了v4,后面又对v4进行了判断,所以要得到flag主要还是要看sub_401520函数
int __cdecl sub_401520(_BYTE *a1, int a2)
{
_BYTE *v2; // ebp
_BYTE *v3; // ecx
int v4; // ebx
int v5; // eax
int i; // edx
_BYTE *v7; // edx
int j; // ecx
_BYTE *v9; // ecx
int k; // ebx
int v12; // [esp+0h] [ebp-38h]
int v13; // [esp+4h] [ebp-34h]
int v14; // [esp+Ch] [ebp-2Ch]
if ( !*a1 )
return 0;
v2 = a1 + 4;
v3 = a1;
v4 = 0;
v5 = 0;
v13 = 0;
while ( 1 )
{
v14 = -1;
for ( i = 0; i != 64; ++i )
{
while ( byte_404000[i] != *v3 )
{
if ( ++i == 64 )
goto LABEL_7;
}
LOBYTE(v14) = i; //得到第一个下标
}
LABEL_7:
LOBYTE(i) = 0;
do
{
while ( byte_404000[i] != a1[v4 + 1] )
{
if ( ++i == 64 )
goto LABEL_11;
}
BYTE1(v14) = i++; //得到第二个下标
}
while ( i != 64 );
LABEL_11:
v7 = &a1[v4 + 2];
for ( j = 0; j != 64; ++j )
{
while ( byte_404000[j] != *v7 )
{
if ( ++j == 64 )
goto LABEL_15;
}
BYTE2(v14) = j; //得到第三个下标
}
LABEL_15:
v9 = &a1[v4 + 3];
for ( k = 0; k != 64; ++k )
{
while ( byte_404000[k] != *v9 )
{
if ( ++k == 64 )
goto LABEL_19;
}
HIBYTE(v14) = k; //得到第四个下标并把它储存在最高字节位
}
//下面一部分就是对得到的4个进行解密
LABEL_19:
v12 = v5 + 1;
*(_BYTE *)(a2 + v5) = (4 * HIBYTE(v14)) | (BYTE2(v14) >> 4) & 3;
if ( *v7 == 61 )
return v12;
v12 = v5 + 2;
*(_BYTE *)(a2 + v5 + 1) = (16 * BYTE2(v14)) | (BYTE1(v14) >> 2) & 0xF;
if ( *v9 == 61 )
return v12;
v5 += 3;
v3 = v2;
v2 += 4;
v13 += 4;
v4 = v13;
*(_BYTE *)(a2 + v5 - 1) = (BYTE1(v14) << 6) | v14 & 0x3F;
if ( !*(v2 - 4) )
return v5;
}
}
分析上面代码可知这是一个base64解密的函数,但又不一样正常的base64解密是4个为一组进行解密这4个是从低位到高位进行排序,但这里是从高位开始的,举个例子就是说假如本来要解密abcd,但到了这里变成了解密dcba,所以得到的也是反的,知道了这些就可以对应也脚本了,就是把v4先进行base64加密,然后4个为一组把他反回过来,后根据题目提示最后一位要爆破。
import base64
import hashlib
str_encoded = [0x46, 0xed, 0x18, 0x96, 0x56, 0x9E, 0xd2, 0x72, 0xb2, 0xb3, 0x80, 0x70]
bytes_encoded = bytes(str_encoded)
encode = base64.b64encode(bytes_encoded).decode('utf-8')
print(encode)
#Ru0Yllae0nKys4Bw
encode = 'Y0uReallyKn0wB4s'
print(encode)
for i in range(255):
if hashlib.md5((encode + chr(i) + '===').encode()).hexdigest()== '5a3ebb487ad0046e52db00570339aace' :
print(encode + chr(i) + '===')
总结来说就是要注意这里的解码被反过来了