easy-re
下载完后进行查壳,如下图,发现无壳且为64位程序用ida64打开
进去查看字符串发现了几组字符串看着挺可疑但是嘶好像光看这没啥用
然后接下来看反编译分析了一波是有三个加密的fun函数
接着就从fun1开始分析到fun3结束,接下来先看fun1加密函数,fun1我们可以看出他是哈希算法的sha1加密,而在主函数中,这里加密后的字符串为f7fae20f2f0b7facff1281fdd1e8fdf6d14cd4c1
int __fastcall fun1(unsigned __int8 *a1, __int64 a2, char *a3)
{
__int64 v3; // rdx
int result; // eax
unsigned int v5[8]; // [rsp+20h] [rbp-70h] BYREF
unsigned __int8 v6[68]; // [rsp+40h] [rbp-50h] BYREF
unsigned int v7; // [rsp+84h] [rbp-Ch]
unsigned int Size; // [rsp+88h] [rbp-8h]
unsigned int Size_4; // [rsp+8Ch] [rbp-4h]
v5[0] = 1732584193;
v5[1] = -271733879;
v5[2] = -1732584194;
v5[3] = 271733878;
v5[4] = -1009589776;
for ( Size = a2; Size > 0x3F; Size -= 64 )
{
v3 = a2 - Size;
*(_QWORD *)v6 = *(_QWORD *)&a1[v3];
*(_QWORD *)&v6[8] = *(_QWORD *)&a1[v3 + 8];
*(_QWORD *)&v6[16] = *(_QWORD *)&a1[v3 + 16];
*(_QWORD *)&v6[24] = *(_QWORD *)&a1[v3 + 24];
*(_QWORD *)&v6[32] = *(_QWORD *)&a1[v3 + 32];
*(_QWORD *)&v6[40] = *(_QWORD *)&a1[v3 + 40];
*(_QWORD *)&v6[48] = *(_QWORD *)&a1[v3 + 48];
*(_QWORD *)&v6[56] = *(_QWORD *)&a1[v3 + 56];
round(v6, v5);
}
if ( Size <= 0x37 )
{
memset(v6, 0, 0x40ui64);
memcpy(v6, &a1[a2 - Size], Size);
v6[Size] = 0x80;
for ( Size_4 = 56; Size_4 <= 0x3F; ++Size_4 )
v6[Size_4] = (8 * a2) >> (8 * (63 - (unsigned __int8)Size_4));
}
else
{
memset(v6, 0, 0x40ui64);
memcpy(v6, &a1[a2 - Size], Size);
v6[Size] = 0x80;
round(v6, v5);
memset(v6, 0, 0x40ui64);
for ( Size_4 = 56; Size_4 <= 0x3F; ++Size_4 )
v6[Size_4] = (8 * a2) >> (8 * (63 - (unsigned __int8)Size_4));
}
result = round(v6, v5);
for ( Size_4 = 0; Size_4 <= 0x13; ++Size_4 )
{
v7 = (unsigned __int8)(v5[Size_4 >> 2] >> (8 * (~(_BYTE)Size_4 & 3)));
result = sprintf(&a3[2 * Size_4], "%02x", v7);
}
return result;
}
但由于是周赛所以flag的格式是一定的都是SLsec{,这样前六位就可以确定下来了,接下来就是脚本问题了,这个爆破脚本找了好多表示找不到根本找不到,所以这里就只能借鉴学长给的脚本了
import hashlib
known_prefix = "SLsec{"
known_hash = "f7fae20f2f0b7facff1281fdd1e8fdf6d14cd4c1"
# 枚举后两位字符
for i in range(256):
for j in range(256):
candidate = known_prefix + chr(i) + chr(j)
candidate_hash = hashlib.sha1(candidate.encode()).hexdigest()
if candidate_hash == known_hash:
print("Found the original string: ", candidate)
exit()
运行结果为SLsec{co,第一段ok接下来我们看第二个加密函数fun2
char *__fastcall fun2(char *a1, char *a2)
{
char *result; // rax
size_t v3; // [rsp+20h] [rbp-10h]
size_t i; // [rsp+28h] [rbp-8h]
v3 = strlen(a1);
for ( i = 0i64; i < v3; ++i )
a2[i] = (a1[i] ^ 0x66) + 66;
result = &a2[v3];
a2[v3] = 0;
return result;
}
这里就是一个简单的异或,加密后的字符串为JBUWED{WK,所以这里写一个简单的异或脚本``
def decrypt(a2):
v3 = len(a2)
a1 = bytearray(v3)
for i in range(v3):
a1[i] = (a2[i] - 66) ^ 0x66
return a1.decode('utf-8')
encrypted_str = "JBUWED{WK"
decrypt_attempt = decrypt(encrypted_str.encode('utf-8'))
print(decrypt_attempt)
运行结果为nfused_so
最后看fun3加密函数,加密后的字符串为WPrYVgNoQx6vTPNuU8e!,再点进去函数里面看看发现是base表换了的base64但还是base64加密,这里找一个在线网站base64自定义解码
fun3加密函数为
_BYTE *__fastcall fun3(const unsigned __int8 *a1, int a2)
{
int v3; // eax
int v4; // eax
int v5; // eax
int v6; // eax
int v7; // eax
char v8[72]; // [rsp+20h] [rbp-60h] BYREF
_BYTE *v9; // [rsp+68h] [rbp-18h]
int v10; // [rsp+74h] [rbp-Ch]
int v11; // [rsp+78h] [rbp-8h]
int i; // [rsp+7Ch] [rbp-4h]
strcpy(v8, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz+/@!#$");
v10 = 4 * ((a2 + 2) / 3);
v9 = malloc(v10 + 1);
if ( !v9 )
return 0i64;
i = 0;
v11 = 0;
while ( i < a2 )
{
v9[v11] = v8[a1[i] >> 2];
if ( a2 <= i + 1 )
v3 = 0;
else
v3 = a1[i + 1] >> 4;
v9[v11 + 1] = v8[(16 * a1[i]) & 0x30 | v3];
if ( a2 <= i + 1 )
{
v5 = 0;
}
else
{
if ( a2 <= i + 2 )
v4 = 0;
else
v4 = a1[i + 2] >> 6;
v5 = (4 * a1[i + 1]) & 0x3C | v4;
}
v9[v11 + 2] = v8[v5];
if ( a2 <= i + 2 )
v6 = 0;
else
v6 = a1[i + 2] & 0x3F;
v9[v11 + 3] = v8[v6];
i += 3;
v11 += 4;
}
for ( i = a2; i % 3; ++i )
{
v7 = v11++;
v9[v7] = 61;
}
v9[v11] = 0;
return v9;
}
解密后为ul_run_quietly}
所以第三段flag为ul_run_quietly},所以将三段flag何在一起也就是SLsec{confused_soul_run_quietly}
你会解方程组不会
查壳无壳用ida打开,进入主函数的反编译
for循环是对输入的字符出进行异或加密,然后看v1,是一个if函数,函数里面是一堆方程组,然后用z3方程组解密即可
from z3 import *
v2 = Int('a2')
v3 = Int('a3')
v4 = Int('a4')
v5 = Int('a5')
v6 = Int('a6')
v7 = Int('a7')
v8 = Int('a8')
v9 = Int('a9')
v10 = Int('a10')
v11 = Int('a11')
v12 = Int('a12')
v13 = Int('a13')
v14 = Int('a14')
v15 = Int('a15')
s = Solver()
s.add(15 * v11
+ -36 * v10
+ 13 * v9
+ 25 * v8
+ 43 * v6
+ 65 * v4
+ 88 * v2
+ 67 * v3
- 5 * v5
+ 89 * v7
+ 11 * v12
+ 47 * v13
- 60 * v14
+ 29 * v15 == 22748,
-41 * v13
+ 2 * v12
+ 8 * v11
+ 7 * v3
+ 89 * v2
+ 12 * v4
- 25 * v5
+ 41 * v6
+ 23 * v7
+ 20 * v8
- 66 * v9
+ 31 * v10
- 39 * v14
+ 17 * v15 == 7258,
-34 * v14
+ 90 * v13
+ 101 * v12
+ -33 * v10
+ 15 * v9
+ 27 * v8
+ 53 * v6
+ 35 * v3
+ 28 * v2
+ 16 * v4
- 65 * v5
+ 39 * v7
+ 13 * v11
+ 23 * v15 == 26190,
(v9 * 128)
+ 81 * v7
+ -59 * v5
+ 35 * v4
+ 34 * v3
+ 23 * v2
+ 49 * v6
+ 25 * v8
- 32 * v10
+ 75 * v11
+ 81 * v12
+ 47 * v13
- 60 * v14
+ 29 * v15 == 37136,
90 * v8
+ 79 * v7
+ 42 * v6
+ -52 * v5
+ 35 * v4
+ 97 * v3
+ 38 * v2
+ 23 * v9
- 36 * v10
+ 57 * v11
+ 81 * v12
+ 42 * v13
- 62 * v14
- 11 * v15 == 27915,
-61 * v14
+ 41 * v12
+ -26 * v10
+ 49 * v7
+ 47 * v6
+ -45 * v5
+ 35 * v4
+ 22 * v2
+ 27 * v3
+ 29 * v8
+ 18 * v9
+ 35 * v11
+ 40 * v13
+ 28 * v15 == 17298,
43 * v13
+ 76 * v12
+ 34 * v11
+ -47 * v10
+ 85 * v9
+ 23 * v8
+ 86 * v7
+ -42 * v6
+ 45 * v3
+ 12 * v2
+ 35 * v4
- 9 * v5
- 44 * v14
+ 65 * v15 == 19875,
57 * v13
+ 25 * v11
+ -30 * v10
+ 86 * v8
+ 79 * v7
+ 35 * v4
+ 62 * v3
+ 79 * v2
- 85 * v5
+ 33 * v6
+ 14 * v9
+ 11 * v12
- 50 * v14
- 9 * v15 == 22784,
47 * v13
+ 2 * v12
+ -36 * v10
+ 2 * v8
+ 29 * v7
+ (v4 * 64)
+ 8 * v2
+ 6 * v3
- 85 * v5
+ 73 * v6
+ 23 * v9
+ 5 * v11
- (v14 * 64)
+ 27 * v15 == 9710,
41 * v12
+ -38 * v10
+ -51 * v5
+ 68 * v4
+ -68 * v3
+ 67 * v2
- 43 * v6
+ 81 * v7
+ 22 * v8
- 12 * v9
+ 75 * v11
+ 27 * v13
- 52 * v14
+ 31 * v15 == 13376,
-67 * v14
+ 31 * v12
+ 15 * v9
+ -51 * v5
+ 63 * v3
+ 85 * v2
+ 5 * v4
+ 44 * v6
+ 36 * v7
+ 28 * v8
- 6 * v10
+ 45 * v11
+ 7 * v13
+ 78 * v15 == 24065,
43 * v13
+ -35 * v10
+ 25 * v8
+ 43 * v6
+ 47 * v2
+ (v3 * 64)
+ 66 * v4
- 5 * v5
+ 112 * v7
+ 13 * v9
+ 95 * v11
+ 21 * v12
- 61 * v14
+ 20 * v15 == 27687,
-61 * v14
+ 47 * v13
+ 89 * v12
+ 14 * v11
+ -92 * v10
+ 56 * v9
+ 23 * v8
+ 89 * v7
+ 49 * v6
+ -25 * v5
+ 85 * v4
+ 67 * v3
+ 89 * v2
- 29 * v15 == 29250,
-60 * v14
+ 51 * v12
+ 16 * v11
+ 12 * v9
+ 25 * v8
+ -43 * v6
+ 34 * v3
+ 95 * v2
+ 62 * v4
- 9 * v5
+ 83 * v7
- 36 * v10
+ 47 * v13
- 24 * v15 == 15317)
if 'un' not in str(s.check()):
print(s.model()) #输出解
这里解出了方程组的解,但是要注意有些数据换了位置所以要把数据调整后在进行for循环的异或解密,异或脚本如下
direct ={
13 : 74,
3 : 24,
4 : 119,
10 : 108,
12 : 88,
7 : 43,
14 : 88,
9 : 91,
6 : 104,
5 : 7,
8 : 28,
15 : 33,
2 : 10,
11 : 52}
flag = [0 for i in range(15)]
for i in direct:
flag[i-2] = direct[i]
for i in range(13, -1, -1):
flag[i] ^= flag[i + 1]
flag_str = ''
for i in range(14):
flag_str += chr(flag[i])
print(flag_str)
运行两端脚本后即可得出flagSLsec{U_G07_th3_k3y!}
但是这里要注意的是在运用z3模块的时候要下载z3和z3-solve两个模块,这样才能保证脚本的正常运行
总结
我是小趴菜!!!!