校历第8周作业
0x01 Reversing-x64Elf-00
Unpacked-64bit-elf,拖入IDA,在主函数中找到验证程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17signed __int64 __fastcall sub_4006FD(__int64 a1)
{
signed int i; // [rsp+14h] [rbp-24h]
const char *v3; // [rsp+18h] [rbp-20h]
const char *v4; // [rsp+20h] [rbp-18h]
const char *v5; // [rsp+28h] [rbp-10h]
v3 = "Dufhbmf";
v4 = "pG`imos";
v5 = "ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( (&v3)[i % 3][2 * (i / 3)] - *(char *)(i + a1) != 1 )
return 1LL;
}
return 0LL;
}写脚本
1
2
3
4
5
6v3=["Dufhbmf","pG`imos","ewUglpt"]
a1=''
for i in range (12):
a1+=chr(ord(v3[i%3][2*(i//3)])-1)
print(a1)得到flag:
Code_Talkers
0x02 IgniteMe
Unpacked-32bit-exe,拖入IDA,得知flag头为EIS{,找到验证程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48bool __cdecl sub_4011C0(char *a1)
{
int v6; // [sp+50h] [bp-B0h]@6
char v7[32]; // [sp+54h] [bp-ACh]@6
int v8; // [sp+74h] [bp-8Ch]@6
int i; // [sp+78h] [bp-88h]@3
unsigned int j; // [sp+7Ch] [bp-84h]@3
char v11[128]; // [sp+80h] [bp-80h]@5
memset(&v4, 0xCCu, 0xF4u);
if ( strlen(a1) > 4 )
{
j = 4;
for ( i = 0; ; ++i )
{
v2 = strlen(a1);
if ( j >= v2 - 1 )
break;
v11[i] = a1[j++];
}
v11[i] = 0;
v8 = 0;
v6 = 0;
memset(v7, 0, 0x20u);
for ( j = 0; ; ++j )
{
v3 = strlen(v11);
if ( j >= v3 )
break;
if ( v11[j] >= 97 && v11[j] <= 122 )
{
v11[j] -= 32;
v6 = 1;
}
if ( !v6 && v11[j] >= 65 && v11[j] <= 90 )
v11[j] += 32;
v5 = sub_4013C0(v11[j]);
v7[j] = byte_4420B0[j] ^ v5;
v6 = 0;
}
result = strcmp("GONDPHyGjPEKruv{{pj]X@rF", v7) == 0;
}
else
{
result = 0;
}
return result;
}其中,sub_4013C0为
1
2
3
4int __cdecl sub_4013C0(int a1)
{
return (a1 ^ 0x55) + 72;
}byte_4420B0的值为
1
0x0D, 0x13, 0x17, 0x11, 0x2, 0x1, 0x20, 0x1D, 0x0C, 0x2, 0x19, 0x2F , 0x17, 0x2B , 0x24 , 0x1F, 0x1E, 0x16, 0x9, 0x0F,0x15, 0x7 , 0x13, 0x26 , 0x0A, 0x2F , 0x1E, 0x1A, 0x2D , 0x0C, 0x22 , 0x4
就嗯逆,写脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18v7="GONDPHyGjPEKruv{{pj]X@rF"
bytedatda=[0x0D, 0x13, 0x17, 0x11, 0x2, 0x1, 0x20, 0x1D, 0x0C, 0x2, 0x19, 0x2F , 0x17, 0x2B , 0x24 , 0x1F, 0x1E, 0x16, 0x9, 0x0F,0x15, 0x7 , 0x13, 0x26 , 0x0A, 0x2F , 0x1E, 0x1A, 0x2D , 0x0C, 0x22 , 0x4]
v5=[0 for i in range(24)]
ans=''
for i in range(24):
v5[i]=bytedatda[i]^ord(v7[i])
v5[i]-=72
v5[i]^=0x55
while v5[i]<97:
v5[i]+=32
while v5[i]>122:
v5[i]-=32
v5[i]=chr(v5[i])
ans+=v5[i]
print(ans)得到flag:
EIS{wadx_tdgk_aihc_ihkn_pjlm}
0x03 hackme
Unpacked-64bit-Elf,通过查字符串找到程序入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46__int64 __fastcall sub_400F8E(__int64 a1, __int64 a2)
{
char v3[136]; // [rsp+10h] [rbp-B0h]
int v4; // [rsp+98h] [rbp-28h]
char v5; // [rsp+9Fh] [rbp-21h]
int v6; // [rsp+A0h] [rbp-20h]
unsigned __int8 v7; // [rsp+A6h] [rbp-1Ah]
char v8; // [rsp+A7h] [rbp-19h]
int v9; // [rsp+A8h] [rbp-18h]
int v10; // [rsp+ACh] [rbp-14h]
int v11; // [rsp+B0h] [rbp-10h]
int v12; // [rsp+B4h] [rbp-Ch]
_BOOL4 v13; // [rsp+B8h] [rbp-8h]
int i; // [rsp+BCh] [rbp-4h]
sub_407470((unsigned __int64)"Give me the password: ");
sub_4075A0((__int64)"%s", v3, a2);
for ( i = 0; v3[i]; ++i )
;
v13 = i == 22;
v12 = 10;
do
{
v9 = (signed int)sub_406D90("%s", v3) % 22;
v11 = 0;
v8 = byte_6B4270[v9];
v7 = v3[v9];
v6 = v9 + 1;
v10 = 0;
while ( v10 < v6 )
{
++v10;
v11 = 1828812941 * v11 + 12345;
}
v5 = v11 ^ v7;
if ( v8 != ((unsigned __int8)v11 ^ v7) )
v13 = 0;
--v12;
}
while ( v12 );
if ( v13 )
v4 = sub_407470((unsigned __int64)"Congras\n");
else
v4 = sub_407470((unsigned __int64)"Oh no!\n");
return 0LL;
}发现gdb调不了,只能硬逆
flag长度为22
byte_6B4270的值为
1
0x5F, 0x0F2, 0x5E , 0x8B, 0x4E, 0x0E, 0x0A3, 0x0AA, 0x0C7, 0x93, 0x81, 0x3D, 0x5F , 0x74 , 0xA3, 0x9, 0x91, 0x2B, 0x49 , 0x28, 0x93, 0x67, 0x0, 0x0
其中sub_406D90看不懂,看了wp知道可能是随机数(也可以从%22看出)
所以密码的比对是随机进行的,逆向的时候则一个个全部逆出来就行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15data=[0x5F, 0x0F2, 0x5E , 0x8B, 0x4E, 0x0E, 0x0A3, 0x0AA, 0x0C7, 0x93, 0x81, 0x3D, 0x5F , 0x74 , 0xA3, 0x9, 0x91, 0x2B, 0x49 , 0x28, 0x93, 0x67, 0x0, 0x0]
ans=''
for i in range(22):
v11 = 0
v8 = data[i]
v6 = i + 1
v10 = 0
while(v10 < v6):
v10 += 1
v11 = (1828812941 * v11 + 12345)
v7 = (v11 ^ v8) & 0xff
ans += chr(v7)
print(ans)得到flag:
flag{d826e6926098ef46}
0x04 EasyRE
Unpacked-32bit-exe,拖入IDA,找到入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48int sub_401080()
{
unsigned int v0; // kr00_4
signed int v1; // edx
char *v2; // esi
char v3; // al
unsigned int v4; // edx
int v5; // eax
__int128 v7; // [esp+2h] [ebp-24h]
__int64 v8; // [esp+12h] [ebp-14h]
int v9; // [esp+1Ah] [ebp-Ch]
__int16 v10; // [esp+1Eh] [ebp-8h]
sub_401020((int)&unk_402150);
v9 = 0;
v10 = 0;
v7 = '\0';
v8 = '\0';
sub_401050((const char *)&unk_402158, &v7);
v0 = strlen((const char *)&v7);
if ( v0 >= 0x10 && v0 == 24 ) //flag为24位
{
v1 = 0;
v2 = (char *)&v8 + 7;
do
{
v3 = *v2--; //从末尾开始比较
byte_40336C[v1++] = v3;
}
while ( v1 < 24 );
v4 = 0;
do
{
byte_40336C[v4] = (byte_40336C[v4] + 1) ^ 6;
++v4;
}
while ( v4 < 0x18 );
v5 = strcmp(byte_40336C, (const char *)&unk_402124);//unk里存了数据
if ( v5 )
v5 = -(v5 < 0) | 1;
if ( !v5 )
{
sub_401020((int)"right\n");
system("pause");
}
}
return 0;
}写脚本
1
2
3
4
5
6
7data=[0x78, 0x49, 0x72, 0x43, 0x6A, 0x7E, 0x3C, 0x72, 0x7C, 0x32, 0x74, 0x57, 0x73, 0x76, 0x33, 0x50, 0x74, 0x49, 0x7F, 0x7A,0x6E, 0x64, 0x6B, 0x61]
byte=[0 for i in range(24)]
for i in range(24):
byte[i]=(data[i]^6)-1
for i in range(23,-1,-1):
print(chr(byte[i]),end='')flag{xNqU4otPq3ys9wkDsN}