0%

柏鹭、MT、DASCTF

柏鹭、MT、DASCTF

这三天打了许多比赛,题目质量我不好说,但自己还是很菜,继续加油吧!

柏鹭杯

他这个比赛的逆向,咋不直接改成密码呢?

walk

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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
void __noreturn sub_231280()
{
int v0; // ecx
const struct _s_FuncInfo *v1; // ecx
int v2; // esi
int v3; // edx
char v4; // al
unsigned int *v5; // esi
unsigned int v6; // edi
int v7; // ecx
unsigned __int8 *v8; // eax
unsigned __int8 v9; // bl
int v10; // edx
unsigned int v11; // eax
unsigned __int8 *v12; // edi
unsigned __int8 *v13; // esi
int v14; // edx
int v15; // ecx
int v16; // edx
int v17; // ecx
int v18; // ecx
int v19; // ecx
int v20; // [esp-20h] [ebp-8Ch]
int v21; // [esp-1Ch] [ebp-88h]
int v22; // [esp-18h] [ebp-84h]
int v23; // [esp-14h] [ebp-80h]
int v24; // [esp-10h] [ebp-7Ch] BYREF
const _ThrowInfo *v25; // [esp-Ch] [ebp-78h]
int v26; // [esp-8h] [ebp-74h] BYREF
const _ThrowInfo *v27; // [esp-4h] [ebp-70h]
int v28; // [esp+0h] [ebp-6Ch] BYREF
int v29[4]; // [esp+Ch] [ebp-60h] BYREF
int v30[3]; // [esp+1Ch] [ebp-50h] BYREF
int v31[3]; // [esp+28h] [ebp-44h] BYREF
char v32[8]; // [esp+34h] [ebp-38h] BYREF
unsigned int *v33; // [esp+40h] [ebp-2Ch]
_DWORD *v34; // [esp+44h] [ebp-28h]
int *v35; // [esp+48h] [ebp-24h]
int v36; // [esp+4Ch] [ebp-20h]
unsigned __int8 *v37; // [esp+50h] [ebp-1Ch]
const struct _s_FuncInfo *v38; // [esp+54h] [ebp-18h]
int v39; // [esp+58h] [ebp-14h]
int *v40; // [esp+5Ch] [ebp-10h]
int v41; // [esp+68h] [ebp-4h]

v40 = &v28;
v41 = 0;
sub_2311F0(v31, (int)v25, v26, (int)v27);
v27 = &_TI1_AUTI__;
v26 = v0;
v40 = &v26;
v1 = (const struct _s_FuncInfo *)v35[1];
v2 = v35[2];
v3 = *v35;
v39 = *v35;
v38 = v1;
v36 = v2;
if ( (int)v1 < v2 )
{
v4 = *((_BYTE *)v1 + v3);
if ( v4 == 'c' )
{
LOBYTE(v41) = 2;
__FrameHandler3::TryBlockMap::TryBlockMap((__FrameHandler3::TryBlockMap *)v32, v1, v2);
v25 = &_TI1_AUTC1__;
v24 = v18;
v40 = &v24;
if ( *v34 + 6 <= v34[1] )
{
LOBYTE(v41) = 4;
sub_231230(v29, v20, v21, v22, v23);
v5 = v33;
if ( sub_231150(*v33, v33[1]) )
{
v6 = v5[1];
v7 = 10 * *v5;
v8 = (unsigned __int8 *)(v6 + v7 + v5[3]);
v37 = v8;
v9 = *v8;
v10 = *v8;
if ( *v8 )
{
v11 = v7 + v6;
v12 = (unsigned __int8 *)v38 + v39;
v13 = (unsigned __int8 *)(5 * v11 + v5[2]);
if ( (v10 ^ *v13) != *((unsigned __int8 *)v38 + v39 + 1)
|| (v10 ^ v13[1]) != v12[2]
|| (v10 ^ v13[2]) != v12[3]
|| (v10 ^ v13[3]) != v12[4]
|| (v10 ^ v13[4]) != v12[5] )
{
return;
}
v8 = v37;
}
++dword_2525DC;
dword_2525E4 += 6;
*v8 = v9 & 0xFE;
}
}
}
else if ( v4 == 'w' )
{
if ( sub_2310B0(x - 1, y) )
{
v14 = x;
v15 = 5 * x;
byte_2518B0[10 * x + y] |= 0x80u;
x = v14 - 1;
LABEL_33:
++dword_2525E4;
LOBYTE(v41) = 6;
sub_231260(v30, v15, v2, v15);
}
}
else
{
if ( v4 != 's' )
{
if ( v4 == 'a' )
{
if ( !sub_2310B0(x, y - 1) )
return;
v17 = y;
byte_2518B0[10 * x + y] |= 0x80u;
v15 = v17 - 1;
}
else
{
if ( v4 != 'd' || !sub_2310B0(x, y + 1) )
return;
v19 = y;
byte_2518B0[10 * x + y] |= 0x80u;
v15 = v19 + 1;
}
y = v15;
goto LABEL_33;
}
if ( sub_2310B0(x + 1, y) )
{
v16 = x;
v15 = 5 * x;
byte_2518B0[10 * x + y] |= 0x80u;
x = v16 + 1;
goto LABEL_33;
}
}
}
}

这个题先是很多try_catch块,对应恢复后,是个迷宫。有五个字符,首先c字符,当当前位置在map中是奇数,后面的5个字符将要进行运算与对比,接下来就是wasd,走迷宫,要求是走的时候map中的值小于0x80

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
from os import TMP_MAX


map = [0x61, 0x18, 0x60, 0x54, 0x52, 0x06, 0xD0, 0xA8, 0x9C, 0xCB, 0xDA, 0xF3, 0xE0, 0xA6, 0xE7, 0x60, 0xEC, 0xDD, 0x81, 0xE7, 0xFD, 0xB7, 0x71, 0x56, 0x50, 0x30, 0xE7, 0xD4, 0xA0, 0xAA, 0x88, 0xEC, 0x62, 0xC5, 0xE7, 0xEE, 0xD4, 0xF0, 0xCC, 0xA1, 0x94, 0x86, 0x08, 0x50, 0x74, 0x58, 0xA5, 0x88, 0xE9, 0xA7, 0x81, 0xC0, 0x8A, 0xE0, 0xFC, 0x04, 0xCF, 0xFE, 0xBC, 0x9A, 0xD1, 0x85, 0x80, 0x00, 0x01, 0x6C, 0xC0, 0xE6, 0xD5, 0xCB, 0xF3, 0xF0, 0x8A, 0x2C, 0xE1, 0xF5, 0xF7, 0xF7, 0x97, 0xC6, 0x9D, 0xEA, 0xC7, 0x40, 0x66, 0x0A, 0x44, 0x52, 0xD6, 0xAD, 0xCA, 0xBC, 0xE5, 0xAD, 0x84, 0x9E, 0xF2, 0x2A, 0x2D, 0xDD]
arr = [0x11, 0x0B, 0x15, 0x1B, 0x00, 0x7C, 0x6E, 0x69, 0x7B, 0x77, 0x0B, 0x16, 0x14, 0x0E, 0x01, 0x24, 0x22, 0x25, 0x3A, 0x35, 0x3F, 0x34, 0x22, 0x2B, 0x31, 0x6A, 0x67, 0x72, 0x61, 0x69, 0xB4, 0xA1, 0xBF, 0xA0, 0xA8, 0xDB, 0xDE, 0xC1, 0xC1, 0xD2, 0xFD, 0xFD, 0xEE, 0xE5, 0xF7, 0xAE, 0xA1, 0xA6, 0xBE, 0xAA, 0xAD, 0xA9, 0xB0, 0xA2, 0xB4, 0x84, 0x98, 0x92, 0x80, 0x9A, 0x8E, 0x8F, 0x82, 0x96, 0x84, 0xC9, 0xD5, 0xD3, 0xD5, 0xD5, 0x88, 0x9D, 0x80, 0x81, 0x92, 0x05, 0x07, 0x19, 0x04, 0x1A, 0x8D, 0x98, 0x9D, 0x98, 0x96, 0xB6, 0xB8, 0xAB, 0xB9, 0xB1, 0xE0, 0xF5, 0xF4, 0xE3, 0xF8, 0x8C, 0x8B, 0x9F, 0x9D, 0x96, 0x88, 0x9E, 0x8D, 0x96, 0x98, 0xDB, 0xC7, 0xD8, 0xDD, 0xCE, 0x15, 0x17, 0x08, 0x1E, 0x05, 0x34, 0x2C, 0x24, 0x3B, 0x3D, 0x31, 0x38, 0x21, 0x24, 0x21, 0x5E, 0x56, 0x52, 0x40, 0x58, 0x91, 0x9E, 0x83, 0x9E, 0x8A, 0xA1, 0xAC, 0xA6, 0xAD, 0xA7, 0xD4, 0xC3, 0xD2, 0xD4, 0xD5, 0xDC, 0xDF, 0xC4, 0xC2, 0xCC, 0xEB, 0xEC, 0xE4, 0xEA, 0xFC, 0x88, 0x98, 0x8D, 0x80, 0x9B, 0x12, 0x0C, 0x0D, 0x14, 0x11, 0xA2, 0xA1, 0xAE, 0xB2, 0xA6, 0x97, 0x84, 0x85, 0x86, 0x9F, 0x8A, 0x84, 0x89, 0x8D, 0x9E, 0xBF, 0xBD, 0xB8, 0xA4, 0xB6, 0x87, 0x98, 0x9E, 0x9A, 0x95, 0xB9, 0xAD, 0xA5, 0xB6, 0xBD, 0xC2, 0xC4, 0xD7, 0xD8, 0xC8, 0xED, 0xE2, 0xE3, 0xF2, 0xF8, 0xE5, 0xE1, 0xFF, 0xF7, 0xF6, 0x71, 0x6F, 0x6F, 0x7E, 0x7D, 0x3D, 0x29, 0x26, 0x3C, 0x27, 0x10, 0x07, 0x1E, 0x1D, 0x01, 0x20, 0x29, 0x3F, 0x2E, 0x2D, 0xC4, 0xDF, 0xCC, 0xD0, 0xDD, 0xFE, 0xF8, 0xEA, 0xF2, 0xEE, 0x81, 0x8B, 0x88, 0x84, 0x8E, 0xC3, 0xCA, 0xCE, 0xD6, 0xC5, 0xE2, 0xEB, 0xE3, 0xE9, 0xE6, 0xAC, 0xA7, 0xA9, 0xB1, 0xB0, 0xE5, 0xFB, 0xEB, 0xF2, 0xE9, 0x8C, 0x93, 0x93, 0x88, 0x9A, 0x8A, 0x97, 0x9F, 0x9A, 0x98, 0x73, 0x67, 0x62, 0x6C, 0x72, 0xBF, 0xBA, 0xBA, 0xAD, 0xBB, 0x9B, 0x8E, 0x93, 0x91, 0x96, 0xC4, 0xCB, 0xC6, 0xDD, 0xD3, 0xEE, 0xF6, 0xFB, 0xF2, 0xF1, 0xBD, 0xB8, 0xBB, 0xB4, 0xBA, 0xE6, 0xF5, 0xED, 0xE0, 0xE2, 0xEE, 0xE3, 0xE8, 0xF2, 0xF2, 0x77, 0x79, 0x62, 0x69, 0x67, 0x79, 0x6E, 0x60, 0x69, 0x6A, 0x1E, 0x15, 0x01, 0x02, 0x1B, 0xAA, 0xA9, 0xB0, 0xAB, 0xAD, 0x88, 0x8E, 0x89, 0x8F, 0x94, 0xB1, 0xB3, 0xA2, 0xB7, 0xAC, 0xA1, 0xA0, 0xBC, 0xB8, 0xA5, 0x92, 0x9B, 0x86, 0x87, 0x89, 0x91, 0x8A, 0x95, 0x9E, 0x86, 0xE2, 0xED, 0xF3, 0xEE, 0xFF, 0x46, 0x46, 0x55, 0x44, 0x45, 0x8C, 0x88, 0x82, 0x87, 0x95, 0x93, 0x96, 0x9E, 0x92, 0x82, 0x95, 0x9C, 0x83, 0x98, 0x90, 0x9E, 0x81, 0x87, 0x92, 0x8E, 0xFA, 0xE3, 0xF5, 0xFD, 0xE1, 0xA1, 0xAB, 0xAA, 0xA4, 0xBF, 0xEB, 0xE4, 0xF7, 0xF7, 0xFC, 0x9C, 0x89, 0x80, 0x83, 0x9B, 0xA2, 0xB0, 0xB5, 0xB4, 0xA4, 0x35, 0x32, 0x38, 0x23, 0x35, 0x0E, 0x02, 0x1F, 0x02, 0x05, 0x64, 0x70, 0x64, 0x7F, 0x65, 0x34, 0x20, 0x28, 0x29, 0x2B, 0x3A, 0x27, 0x3E, 0x27, 0x31, 0xA4, 0xB1, 0xBC, 0xB4, 0xAE, 0xCF, 0xCF, 0xCE, 0xDE, 0xDF, 0xA8, 0xB8, 0xBD, 0xB3, 0xB9, 0xC5, 0xCA, 0xD4, 0xD8, 0xDF, 0x87, 0x97, 0x86, 0x80, 0x93, 0xDC, 0xCB, 0xDA, 0xC2, 0xD4, 0xF2, 0xE7, 0xFD, 0xEA, 0xEE, 0xE6, 0xE6, 0xF9, 0xEC, 0xFA, 0x97, 0x9F, 0x95, 0x93, 0x95, 0x4B, 0x45, 0x5B, 0x4F, 0x45, 0x4C, 0x48, 0x55, 0x59, 0x5F, 0xBF, 0xAB, 0xBE, 0xA8, 0xA5]
tmp = []
for i in range(len(map)):
if map[i] < 0x80:
tmp.append(map[i])
else:
map[i] = 0xff
print(tmp)
for i in range(10):
for j in range(10):
print(hex(map[i*10+j])[2:].zfill(2),end=",")
print(" ")
stra = []
for i in range(len(map)):
if(map[i]!=0xff):
tmp=i*5
tmp_str = "c"
for j in range(5):
tmp_str+=chr(map[i]^arr[tmp+j])
stra.append(tmp_str)
print(stra)

生成地图和c开头的字符串,只考虑地图dddddssaaassdddssaassddddsd,c开头的要筛选,当tmp中是奇数,就是要找的,得到路线cpjtzadddddssaaacdfyotssdddssacxoahkassddddsdcaextr,输入得flag。

MTCTF

small

直接审汇编,发现不能反汇编,其实将0xea处改为retn就行,该处本来就是exit,所以没问题

image-20220920155829547

得到返汇编后,发现是一个tea加密

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
_BYTE *__fastcall sub_67(__int64 a1, int a2)
{
unsigned int v2; // eax
int v3; // ebx
int v4; // ebp
int v5; // edi
_BYTE *v6; // rsi
unsigned int v7; // ebp
int v8; // edi
_BYTE *result; // rax
int v10; // esi
int v11; // [rsp+10h] [rbp+10h]

*(_BYTE *)(a1 + 1159922115) += v2;
v7 = ((v3 + v5) ^ ((v2 >> 5) + 35) ^ (16 * a1 + 1)) + v4;
v8 = ((v3 + v7) ^ (16 * v7 + 69) ^ ((v7 >> 5) + 103)) + v5;
if ( a2 + 1 < 35 )
JUMPOUT(0x52i64);
*((_DWORD *)v6 - 2) = v7;
*((_DWORD *)v6 - 1) = v8;
if ( (int)v6 < v11 + 32 )
JUMPOUT(0x1Ci64);
result = v6;
v10 = 32;
while ( *(_BYTE *)(unsigned int)(v10 + 65783) == *result )
{
--v10;
--result;
if ( !v10 )
{
result = (_BYTE *)(&loc_0 + 1);
__asm { syscall; Low latency system call }
return result;
}
}
return result;
}
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
#include <stdio.h>
#include <stdint.h>

//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0x67452301*35, i; /* set up */
uint32_t delta=0x67452301; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<35; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}

int main()
{
uint32_t v[]={0xDE087143, 0xC4F91BD2, 0xDAF6DADC, 0x6D9ED54C, 0x75EB4EE7, 0x5D1DDC04, 0x511B0FD9, 0x51DC88FB},k[4]={0x01,0x23,0x45,0x67};
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
for (int i=0;i<8;i+=2)
{
decrypt(v+i, k);
printf("decode:%x %x\n",v[i],v[1+i]);
}
return 0;
}
//flag{327a6c4304ad5938eaf0efb6cc3e53dc}

delta是0x67452301,很简单。

DASCTF

landing

这题还是很简单的,就是try、catch

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
std::ostream *v3; // rax
std::ostream *v4; // rax
char Str[32]; // [rsp+450h] [rbp+3D0h] BYREF
int i; // [rsp+48Ch] [rbp+40Ch]

_main();
v3 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "Input something.");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v3);
std::operator>><char,std::char_traits<char>>(refptr__ZSt3cin, Str);
if ( strlen(Str) == 28 )
{
for ( i = 0; i <= 27; ++i )
{
Str[i] ^= 0x22u;
++Str[i];
}
func1(Str);
}
else
{
v4 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "nono");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v4);
system("pause");
}
return 1;
}

主程序是这样的,func1里是一个base64加密不过是骗人的,发现func1处有一个try块,找到对应catch块,然后patch一下

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
std::ostream *v3; // rax
__int64 v4; // rdx
std::ostream *v5; // rax
size_t v7; // rax
void *v8; // rsp
int v9; // eax
size_t v10; // rax
std::ostream *v11; // rax
std::ostream *v12; // rax
char v13[15]; // [rsp+20h] [rbp-60h] BYREF
char v14[25]; // [rsp+2Fh] [rbp-51h] BYREF
char Str1[1024]; // [rsp+50h] [rbp-30h] BYREF
char Str[32]; // [rsp+450h] [rbp+3D0h] BYREF
char *Str2; // [rsp+470h] [rbp+3F0h]
size_t v18; // [rsp+478h] [rbp+3F8h]
void *v19; // [rsp+480h] [rbp+400h]
int j; // [rsp+488h] [rbp+408h]
int i; // [rsp+48Ch] [rbp+40Ch]

_main();
v3 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "Input something.");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v3);
std::operator>><char,std::char_traits<char>>(refptr__ZSt3cin, Str);
if ( strlen(Str) == 28 )
{
for ( i = 0; i <= 27; ++i )
{
Str[i] ^= 0x22u;
v4 = (unsigned int)(unsigned __int8)Str[i]++ + 1;
}
if ( v4 == 1 )
{
v19 = _cxa_begin_catch(Str);
qmemcpy(v13, "GUw\\D~UHG#kYG~", 14);
v13[14] = 127;
qmemcpy(v14, "BA#{QJT(\\A {BG~$BG~$BGz//", sizeof(v14));
v7 = strlen(v13);
v18 = v7 - 1;
v8 = alloca(16 * ((v7 + 15) >> 4));
Str2 = v13;
for ( j = 0; j < strlen(v13); ++j )
Str2[j] = v13[j] ^ 0x12;
v9 = strlen(Str);
nothing(Str1, Str, v9);
v10 = strlen(Str2);
if ( !strncmp(Str1, Str2, v10) )
v11 = (std::ostream *)std::operator<<<std::char_traits<char>>(
refptr__ZSt4cout,
"Goodgood!\n...Please packed the flag with\"DASCTF{}\"");
else
v11 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "nono");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v11);
system("pause");
_cxa_end_catch();
}
else
{
_cxa_begin_catch(Str);
v12 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "nono");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v12);
system("pause");
_cxa_end_catch();
}
}
else
{
v5 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cout, "nono");
refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v5);
system("pause");
}
return 1;
}

这时主加密其实很清楚就是对一个初始化的对比密文的操作,而对我们输入进行操作的是在nothing里,nothing这个函数点个U就可以看了,发现是个base64,一眼魔改。

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
void __fastcall nothing(char *a1, const char *a2, int a3)
{
char *v3; // rax
char *v4; // rax
char *v5; // rax
char *v6; // rax
unsigned __int64 i; // [rsp+8h] [rbp-18h]
int v8; // [rsp+14h] [rbp-Ch]
int v9; // [rsp+18h] [rbp-8h]
int v10; // [rsp+1Ch] [rbp-4h]

v10 = 0;
v9 = 2;
for ( i = 0i64; a3 > i; ++i )
{
switch ( v9 )
{
case 2:
v8 = (*a2 >> 2) & 0x3F;
break;
case 4:
v8 = (*a2 >> 4) & 0xF;
break;
case 6:
v8 = (*a2 >> 6) & 3;
break;
}
v8 += v10;
v3 = a1++;
*v3 = nothing(char *,char const*,int)::aaa[v8] + 1;
v10 = (*a2 << (6 - v9)) & 0x3F;
v9 += 2;
if ( v9 == 8 )
{
v8 = *a2 & 0x3F;
v4 = a1++;
*v4 = nothing(char *,char const*,int)::aaa[*a2 & 0x3F] + 1;
v10 = 0;
v9 = 2;
}
++a2;
}
if ( v10 )
{
v5 = a1++;
*v5 = nothing(char *,char const*,int)::aaa[v10] + 1;
}
if ( a3 % 3 == 1 )
{
v6 = a1++;
*v6 = 61;
*a1 = 61;
}
if ( a3 % 3 == 2 )
*a1 = 61;
}

很明显在赋值的时候给每个base64后的数加了1,那么我们就很清楚加密流程了。输入->异或->加1->base64->加1

1
2
3
4
5
6
7
8
9
10
11
12
a = 'UGeNVlGZU1yKUlmPS1iCXF:NS2iPUl6PUl6PUh'
flag11 = ""
flag=[0]*28
flag1='LWLRAXOLININGHAXOLGXNNNNNNNN'
for i in range(len(a)):
flag+=chr(ord(a[i]) - 1)
print(flag)
for i in range(28):
flag[i] = ord(flag1[i]) - 1
flag[i] ^=0x22
flag11+=chr(flag[i])
print(flag11)

cbNET

c#逆向

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
private void method_3(object sender, RoutedEventArgs e)
{
string text = this.vmethod_0().Text;
string[] array = new string[24];
int[] array2 = new int[]
{
309,
1981,
2823,
6979,
28339,
39487,
33035,
283711,
623,
4109,
23551,
54761,
67985,
231149,
499603,
1354567,
213,
2651,
22559,
52549,
484663,
290793,
532213,
1746643
};
checked
{
if (text.Length != array2.Length + 7)
{
this.vmethod_2().Content = "wrong";
}
else if (Operators.CompareString(Strings.Mid(text, 1, 6), "CBCTF{", false) != 0 | Operators.CompareString(Strings.Mid(text, array2.Length + 7, 1), "}", false) != 0)
{
this.vmethod_2().Content = "wrong";
}
else
{
this.method_0(ref array, text);
this.method_2(ref array);
int num = array2.Length - 1;
for (int i = 0; i <= num; i++)
{
if (Conversions.ToDouble(array[i]) != (double)array2[i])
{
this.vmethod_2().Content = "wrong";
return;
}
}
this.vmethod_2().Content = "correct";
}
}
}
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
private object method_2(ref string[] string_0)
{
int num = checked(string_0.Length - 1);
int i = 0;
while (i <= num)
{
try
{
string_0[i] = Conversions.ToString((double)(Conversions.ToLong(string_0[i]) ^ Conversions.ToLong(string_0[checked(i - 1)]) / (long)(i % 8)) + Conversions.ToDouble(string_0[checked(i - 1)]) % (double)(i % 8));
goto IL_F3;
}
catch (Exception ex)
{
string_0[i] = Conversions.ToString((double)(Conversions.ToLong(string_0[i]) ^ Conversions.ToLong(string_0[checked(i + 7)]) / 8L) + Conversions.ToDouble(string_0[checked(i + 7)]) % 8.0);
goto IL_F3;
}
goto IL_98;
IL_EA:
double num2;
double num3;
checked
{
i++;
continue;
IL_CE:
if (num2 > num3)
{
goto IL_EA;
}
IL_98:;
}
if (checked(this.method_1((int)Math.Round(num2)) & this.method_1((int)Math.Round(unchecked(Conversions.ToDouble(string_0[i]) - num2)))) == 0)
{
num2 += 1.0;
goto IL_CE;
}
string_0[i] = Conversions.ToString(num2 * (Conversions.ToDouble(string_0[i]) - num2));
goto IL_EA;
IL_F3:
string_0[i] = Conversions.ToString(Conversions.ToDouble(string_0[i]) - 2.0 - Conversions.ToDouble(string_0[i]) % 2.0);
num3 = Conversions.ToDouble(string_0[i]) - 2.0;
num2 = 2.0;
goto IL_CE;
}
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private int method_1(int int_0)
{
checked
{
int result;
if (int_0 < 2)
{
result = 0;
}
else
{
int num = int_0 - 1;
for (int i = 2; i <= num; i++)
{
if (int_0 % i == 0)
{
return 0;
}
}
result = 1;
}
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private object method_0(ref string[] string_0, string string_1)
{
string text = "0rays";
int num = 0;
checked
{
int num2 = string_1.Length - 2;
for (int i = 6; i <= num2; i++)
{
string_0[i - 6] = Conversions.ToString(string_1[i]);
string_0[i - 6] = Conversions.ToString(Strings.Asc(string_0[i - 6]) ^ Strings.Asc(text[num]));
num = (num + 1 ^ 5);
}
return false;
}
}

这个题是真坐牢啊,脚本跑不对,真的难受

学习一下官方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
import hashlib


def isPrime(n):
if n < 2:
return 0
for i in range(2, n - 1):
if n % i == 0:
return 0
return 1


def xordecrypt(key):
str = "0rays"
circle = 0
flag = ""
for i in range(len(key)):
flag = flag + chr(key[i] ^ ord(str[circle]))
circle = (circle + 1) ^ 5
flag = "CBCTF{" + flag + "}"
t = hashlib.sha256()
t.update(flag.encode())
finalflag = t.hexdigest()
if finalflag == "15c4ac7645546a1ef8141441b48e1824954fdbb159bf96400061b17db1af9edf":
print(flag)
exit(0)


def recursion(key2, i):
key = key2.copy()
if (i % 8) != 0:
key[i] = (key[i] - key[i - 1] % (i % 8)) ^ (key[i - 1] // (i % 8))
else:
key[i] = (key[i] - key[i + 7] % 8) ^ (key[i + 7] // 8)
if i != 0:
decrypt(key, i - 1)
else:
xordecrypt(key)


def decrypt(key1, i):
key = key1.copy()
for j in range(2, key[i] - 1):
if key[i] % j == 0 and isPrime(j) and isPrime(key[i] // j): # key[i] % j == 0 因为指数相乘所以是肯定余数为0
key[i] = j + key[i] // j
break
key[i] = key[i] + 2 #+2或者+1都进行测试
recursion(key, i)
key[i] = key[i] + 1
recursion(key, i)


key = [309, 1981, 2823, 6979, 28339, 39487, 33035, 283711, 623, 4109, 23551, 54761, 67985, 231149, 499603, 1354567, 213, 2651, 22559, 52549, 484663, 290793, 532213, 1746643]
decrypt(key, 23)