迷失之门

分析

定位到主函数发现有四个字符串用于flag字符的替换

image-20240503162658301

主加密区域

image-20240503162741747

利用flag与key字符串的差值作为选择替换字符的索引

最终验证区域

image-20240503162943981

结果值为:70,83,66,66,104,75,67,113,79,82,111,89,104,119,120,98,111,90,71,82,75,100,70,70,121,81,54

wp

由于每次加密都是相互独立的,所以可以直接对加密函数进行爆破然后进行判断选择

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include"stdio.h"
#include"windows.h"
#include"string.h"
int __fastcall check(char *flag,int arr[]);
int main(){
int arr[] ={70,83,66,66,104,75,67,113,79,82,111,89,104,119,120,98,111,90,71,82,75,100,70,70,121,81,54};
char flag[27]={0};
check(flag,arr);
puts(flag);
return 0;
}

int __fastcall check(char *flag,int arr[])
{
char v1; // al
char key[32]; // [rsp+20h] [rbp-60h] BYREF
char v4[32]; // [rsp+40h] [rbp-40h] BYREF
__int64 v5; // [rsp+60h] [rbp-20h]
__int64 v6; // [rsp+68h] [rbp-18h]
__int64 v7; // [rsp+70h] [rbp-10h]
__int64 v8; // [rsp+78h] [rbp-8h]
char v9; // [rsp+80h] [rbp+0h]
char v10[32]; // [rsp+90h] [rbp+10h] BYREF
__int64 v11; // [rsp+B0h] [rbp+30h]
__int64 v12; // [rsp+B8h] [rbp+38h]
__int64 v13; // [rsp+C0h] [rbp+40h]
__int64 v14; // [rsp+C8h] [rbp+48h]
char v15; // [rsp+D0h] [rbp+50h]
char v16[32]; // [rsp+E0h] [rbp+60h] BYREF
__int64 v17; // [rsp+100h] [rbp+80h]
__int64 v18; // [rsp+108h] [rbp+88h]
__int64 v19; // [rsp+110h] [rbp+90h]
__int64 v20; // [rsp+118h] [rbp+98h]
char v21; // [rsp+120h] [rbp+A0h]
int v22; // [rsp+124h] [rbp+A4h]
int len; // [rsp+128h] [rbp+A8h]
int i; // [rsp+12Ch] [rbp+ACh]

strcpy(v16, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
v17 = 0;
v18 = 0;
v19 = 0;
v20 = 0;
v21 = 0;
strcpy(v10, "abcdefghijklmnopqrstuvwxyz");
v11 = 0;
v12 = 0;
v13 = 0;
v14 = 0;
v15 = 0;
strcpy(v4, "0123456789+/-=!#&*()?;:*^%");
v5 = 0;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
strcpy(key, "DABBZXQESVFRWNGTHYJUMKIOLPC");
len = 27;
for ( i = 0; i < len; ++i )
{
for(int j=32;j<=127;j++){
flag[i] =j;
if ( flag[i] != 127 && flag[i] > 32 )
{
if ( flag[i] - key[i] <= 0 )
continue;
else
{
v22 = flag[i] - key[i];
if ( v22 > 25 )
{
if ( v22 > 51 )
v1 = v4[v22 - 52];
else
v1 = v10[v22 - 26];
flag[i] = v1;
}
else
{
flag[i] = v16[v22];
}
}
}
if(flag[i] ==arr[i]){
putchar(j);
break;
}
}
}
return 0;
}
//ISCC{bSoagnjx~xoprPfWhNT~`}

CrypticConundrum

分析

将文件放入exeinfo检查后发现有upx壳,使用upx -d进行脱壳

image-20240503163453162

反编译发现主要加密函数为mix和Encruption

有趣的是进入mix后发现它对字符串先进行加密后又进行解密,只是改变了Str的值

所以主要加密区域为Encryption函数

image-20240503163748904

NewEncryption里对函数进行了与密钥的运算然后交换了字符串位置,而后在这个截图函数中又把位置交换了回来,所以不理解写了很多没意义的运算。。闲的吗。然后将图中运算倒着写一遍

wp

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include"stdio.h"
#include"windows.h"
__int64 __fastcall Encryption(int *a1, int *a2, int a3);
int main(){
__int64 v9[2]; // [rsp+60h] [rbp-30h]
__int64 v10[2];
char Str[28]; // [rsp+40h] [rbp-50h] BYREF
// char v8[4];
int len;
// int arr[] = {0x69, 0xB5, 0xA2, 0x72, 0xE5, 0x67, 0xFA, 0xB,
// 0x60, 0x9D, 0xBA, 0x5D, 0x70, 0xC3, 0xB2, 0x9A,
// 0xD1, 0x2F, 0x9A, 0xB0, 0xD5, 0x16, 0x69, 0xAA,
// 0x0D, 0x34};
int arr[]={0xBB,0x63,0xF4,0x20,0x37,0x15,0xBA,0x72,0xE9,0x35,0x95,0x98,0xF7,0x34,0x36,0xE5,0xAA,0x73,0x07,0x42,0x45,0xE4,0x8B,0xBB,0xCA,0x34};

int v8[] = {0x49,0x53,0x43,0x43};
strcpy(Str, "So--this-is-the-right-flag");
len = strlen(Str);

Encryption(arr,v8,len);

for(int i=0;i<26;i++)
putchar(arr[i]&0xff);
return 0;
}

__int64 __fastcall Encryption(int *a1, int *a2, int a3)
{
__int64 result; // rax
char v4; // [rsp+2Bh] [rbp-15h]
int m; // [rsp+2Ch] [rbp-14h]
int l; // [rsp+30h] [rbp-10h]
int k; // [rsp+34h] [rbp-Ch]
int j; // [rsp+38h] [rbp-8h]
int i; // [rsp+3Ch] [rbp-4h]

/*
NewEncryption(a1, a2, a3);
for ( i = 0; i < a3 / 2; ++i ) // 交换位置
{
v4 = a1[i];
a1[i] = a1[a3 - i - 1];
a1[a3 - i - 1] = v4;
}
for ( j = 0; j < a3; j += 2 ) // 偶数位参与密钥运算
a1[j] ^= a2[j % 4];
*/


for ( m = 0; ; ++m )
{
result = (unsigned int)m;
if ( m >= a3 )
break;
a1[m] -= 10;
}
for ( l = 0; l <= a3-2; ++l )
a1[l] += a1[l + 1];
for ( k = 0; k < a3 - 1; ++k )
a1[k] ^= a2[2];
for ( j = 0; j < a3; j += 2 ) // 偶数位参与密钥运算
a1[j] ^= a2[j % 4];
for ( i = 0; i < a3; ++i )
a1[i] += a2[i % 4];
return result;
}
//ISCC{a4W,SF=^u{W/Iyu&{B#p}

Badcode

分析

image-20240505164651307

函数的加密逻辑很容易看出来,先对输入进行长度判断,然后进行奇偶运算和利用随机数产生的密钥进行加密,最后对结果进行xxtea加密

image-20240505164842630

随机数和xxtea密钥可以通过动调得到

image-20240505165026250

wp

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include"stdio.h"
#include"windows.h"
#include"stdint.h"

#define _DWORD __int64
#define delta 0x61C88647
#define MX (((z>>5^y<<2) +(y>>3^z<<4)) ^((sum^y) +(key[(p&3)^e] ^z)))
#define arr(v16, j) v16[j]

//int __cdecl sub_4014C0(__int64 *a1, int a2, int a3);
void beta(uint32_t* v, int n, int key[4]);
int encry(int* arr, char v16[]);

int main() {
uint32_t Buf2[6];
int arr[24] = { 0 };
Buf2[0] = 0xEC5432D0;
Buf2[1] = 0x6FC5FC7;
Buf2[2] = 0x9D20D069;
Buf2[3] = 0xAF6DBF25;
Buf2[4] = 0xE3167389;
Buf2[5] = 0x88E01452;
char v17[] = "674094872038771148666737";
int key[] = { 0x12345678,0x9ABCDEF0,0x0FEDCBA98,0x76543210 };
// for(int i=0;i<6;i+=2){
beta(Buf2, -6, key);
// }

for (int j = 0, m = 0; m < 6; j += 4, m++) {
arr[j] = Buf2[m] & 0xff;
arr[j + 1] = (Buf2[m] >> 8) & 0xff;
arr[j + 2] = (Buf2[m] >> 16) & 0xff;
arr[j + 3] = (Buf2[m] >> 24) & 0xff;
}
encry(arr, v17);
for (size_t k = 0; k < 24; k++)
{
putchar(arr[k]);
}

return 0;
}

void beta(uint32_t* v, int n, int key[4])
{
uint32_t y, z, sum=0;
unsigned p, rounds, e;
if (n > 1) { //判断加密还是解密
rounds = 6 + 52 / n; //定义迭代次数,n=2即是32
sum = 0;
z = v[n - 1];
do {
sum += delta;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++) { //p:0->n-1
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX; //p=n-1
} while (--rounds);
}
else if (n < -1)
{
n = -n;
rounds = 6 + 52 / n;
sum -= rounds * delta;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--) { //p:n-1->0
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX; //n=0
sum += delta;
} while (--rounds);
}
}
int encry(int* arr, char v16[]) {
int j, k;
int v8, v9, v10;

// sub_9E1620(v16);
// LOBYTE(v21) = 1;
for (k = 0; k < strlen(v16); ++k)
{
v9 = arr[k];
v10 = (v16[k] - 48) ^ v9;
arr[k] = v10;
}
for (j = 0; j < strlen(v16); ++j)
{
if (j % 2)
v8 = arr[j] - 2;
else
v8 = arr[j] + 3;
arr[j] = v8;
}
return 0;
}
//ISCC{3NScka9RRIDO8H3h@!}

DLLCode

分析

image-20240505195032485

通过动调发现将输入字符串划分为了两部分,前一部分进入enocode加密,后一部分使用给定数组作为索引打乱顺序。

通过分析,encode函数中以ISCC为密钥对每个字符进行异或

image-20240505195259659

wp

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
#include<string.h>
#include<stdio.h>
#include<windows.h>
int main() {
int arr[] = { 0x0, 0x10, 0x38, 0x14, 0x11, 0xa, 0x8, 0x10, 0x1b, 0x0, 0x14, 0x3, 0x43, 0x59, 0x53, 0x59, 0x53, 0x62, 0x3f, 0x64, 0x74, 0x7d, 0x75,98};
int v4[12];
int temp = 0;
char key[] = "ISCC";
int flag[24] = { 0 };
//v4[0] = 0;
v4[0] = 2;
v4[1] = 0;
v4[2] = 3;
v4[3] = 1;
v4[4] = 6;
v4[5] = 4;
v4[6] = 7;
v4[7] = 5;
v4[8] = 10;
v4[9] = 8;
v4[10] = 11;
v4[11] = 9;
int m = 1;
for (int i = 0; i < 12; i++ ) {
//temp = arr[12 + i];
flag[m] = arr[v4[i] + 12];
//arr[v4[i] + 12] = temp;
//= arr[12 + i];
m += 2;
}
int n = 0;
for (int j = 0; j < 12; j++) {
arr[j] ^=key[j&3];
flag[n] = arr[j];
n += 2;
}
for (int n = 0; n < 24; n++) {
putchar(flag[n]);
//printf("%c", arr[n]);
}
return 0;
}
//ISCC{YWYX?YSKdSbRuStWb@}