打开文件,查壳,无壳
拖入到ida中查看,找到主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // esi
int v5[3]; // [esp+8h] [ebp-74h] BYREF
__int16 v6; // [esp+14h] [ebp-68h]
char v7; // [esp+16h] [ebp-66h]
char v8[100]; // [esp+18h] [ebp-64h] BYREF
sub_403CF8(&unk_40E140);
scanf("%s", v8);
memset(v5, 0, sizeof(v5));
v6 = 0;
v7 = 0;
sub_401080(v8, strlen(v8), v5);
v3 = 0;
while ( *(v5 + v3) == byte_40E0E4[v3] )
{
if ( ++v3 > strlen(v5) )
goto LABEL_6;
}
sub_403CF8(aError);
LABEL_6:
if ( v3 - 1 == strlen(byte_40E0E4) )
return sub_403CF8(aAreYouHappyYes);
else
return sub_403CF8(aAreYouHappyNo);
}
[点击并拖拽以移动]
可以看到, sub_401080(v8, strlen(v8), v5);函数对输入的v8进行了处理,我们跟进查看
int __cdecl sub_401080(int a1, int a2, int a3)
{
int v3; // edi
int v4; // esi
int v5; // edx
int v6; // eax
int v7; // ecx
int v8; // esi
int v9; // esi
int v10; // esi
int v11; // esi
_BYTE *v12; // ecx
int v13; // esi
int v15; // [esp+18h] [ebp+8h]
v3 = 0;
v4 = 0;
sub_401000();
v5 = a2 % 3;
v6 = a1;
v7 = a2 - a2 % 3;
v15 = a2 % 3;
if ( v7 > 0 )
{
do
{
LOBYTE(v5) = *(a1 + v3);
v3 += 3;
v8 = v4 + 1;
*(v8 + a3 - 1) = byte_40E0A0[(v5 >> 2) & 0x3F];
*(++v8 + a3 - 1) = byte_40E0A0[16 * (*(a1 + v3 - 3) & 3) + ((*(a1 + v3 - 2) >> 4) & 0xF)];
*(++v8 + a3 - 1) = byte_40E0A0[4 * (*(a1 + v3 - 2) & 0xF) + ((*(a1 + v3 - 1) >> 6) & 3)];
v5 = *(a1 + v3 - 1) & 0x3F;
v4 = v8 + 1;
*(v4 + a3 - 1) = byte_40E0A0[v5];
}
while ( v3 < v7 );
v5 = v15;
}
if ( v5 == 1 )
{
LOBYTE(v7) = *(v3 + a1);
v9 = v4 + 1;
*(v9 + a3 - 1) = byte_40E0A0[(v7 >> 2) & 0x3F];
v10 = v9 + 1;
*(v10 + a3 - 1) = byte_40E0A0[16 * (*(v3 + a1) & 3)];
*(v10 + a3) = 61;
LABEL_8:
v13 = v10 + 1;
*(v13 + a3) = 61;
v4 = v13 + 1;
goto LABEL_9;
}
if ( v5 == 2 )
{
v11 = v4 + 1;
*(v11 + a3 - 1) = byte_40E0A0[(*(v3 + a1) >> 2) & 0x3F];
v12 = (v3 + a1 + 1);
LOBYTE(v6) = *v12;
v10 = v11 + 1;
*(v10 + a3 - 1) = byte_40E0A0[16 * (*(v3 + a1) & 3) + ((v6 >> 4) & 0xF)];
*(v10 + a3) = byte_40E0A0[4 * (*v12 & 0xF)];
goto LABEL_8;
}
LABEL_9:
*(v4 + a3) = 0;
return sub_401030(a3);
}
可以看到是一个很明显的base64加密函数,但是注意看在对数据加密前有sub_401000()函数(做题的时候这个就没看到,哭.jpg)我们跟进查看这个函数
int sub_401000()
{
int result; // eax
char v1; // cl
for ( result = 6; result < 15; ++result )
{
v1 = byte_40E0AA[result];
byte_40E0AA[result] = byte_40E0A0[result];
byte_40E0A0[result] = v1;
}
return result;
}
可以看到,从第七个开始到第15个将byte_40E0AA与byte_40E0A0中的数据进行交换,可以找到byte_40E0AA与byte_40E0A0的数据分别为'KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'和'ABCDEFGHIJ'变换后密码表为’ABCDEFQRSTUVWXYZGHIJKLMNOPabcdefghijklmnopqrstuvwxyz0123456789+/‘
然后接着往下看,发现最后返回的是sub_401030(a3)函数,我们再查看这个函数
int __cdecl sub_401030(const char *a1)
{
__int64 v1; // rax
char v2; // al
v1 = 0i64;
if ( strlen(a1) )
{
do
{
v2 = a1[HIDWORD(v1)];
if ( v2 < 'a' || v2 > 'z' )
{
if ( v2 < 'A' || v2 > 'Z' )
goto LABEL_9;
LOBYTE(v1) = v2 + ' ';
}
else
{
LOBYTE(v1) = v2 - 32;
}
a1[HIDWORD(v1)] = v1;
LABEL_9:
LODWORD(v1) = 0;
++HIDWORD(v1);
}
while ( HIDWORD(v1) < strlen(a1) );
}
return v1;
}
发现是大小写转换,转换后得到 byte_40E0E4(此处出自主函数),分析完后写脚本解密
import base64
import string
str = "ZmxhZ3tiGNXlXjHfaDTzN2FfK3LycRTpc2L9" # 欲解密的字符串
outtab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" # 原生字母表
intab = "ABCDEFQRSTUVWXYZGHIJKLMNOPabcdefghijklmnopqrstuvwxyz0123456789+/" # 换表之后的字母表
print (base64.b64decode(str.translate(str.maketrans(intab,outtab))))
得到flag
学到的知识点:
- 判断函数代码是base64加密,确定是base64加密后,查看加密前后有无变换,此处附上常用的base64换表解密代码
import base64 import string str = "" # 欲解密的字符串 outtab = "" # 原生字母表 intab = "" # 换表之后的字母表 print (base64.b64decode(str.translate(str.maketrans(intab,outtab))))
- 大小写转换代码
int __cdecl sub_401030(const char *a1) { __int64 v1; // rax char v2; // al v1 = 0i64; if ( strlen(a1) ) { do { v2 = a1[HIDWORD(v1)]; if ( v2 < 'a' || v2 > 'z' ) { if ( v2 < 'A' || v2 > 'Z' ) goto LABEL_9; LOBYTE(v1) = v2 + ' '; } else { LOBYTE(v1) = v2 - 32; } a1[HIDWORD(v1)] = v1; LABEL_9: LODWORD(v1) = 0; ++HIDWORD(v1); } while ( HIDWORD(v1) < strlen(a1) ); } return v1; }
- 此处再补充一个关于base家族解密的工具 ,kali的basecrack感觉挺好用,具体参考一位大佬文章basecrack使用
- 对来自用户输入的单个Base编码数据进行解码:python basecrack.py
对通过参数(-b/--base)传递的单个Base编码数据进行解码: python basecrack.py -b SGVsbG8gV29ybGQh 对通过文件(-f/--file)传递的多个Base编码数据进行解码: python basecrack.py -f file.txt 对任意模式的多重Base编码数据进行解码(-m/--magic): python basecrack.py --magic 使用解码的Base数据生成字典文件并输出(-o/--output): python basecrack.py -f file.txt -o output-wordlist.txt