第三届京麒CTF挑战赛·决赛 WriteUp (Reverse方向)

3k 词

今天决赛一共有三个re,前两个还挺简单的,小小地抢了一下血,第三个是rust的webre,坐牢到最后也没牢出来,燃尽了😭

InMemoryDex

在内存中搜索dex文件头和文件尾找到两个内容相同的dex文件,提取出来后jeb打开,发现一个nu.ll类:

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
package nu.ll;

import a.a;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Base64;

@a
public class object {
// This method was un-flattened
public static String getFirstScreenshot(Context context0) {
String s;
Cursor cursor0;
ArrayList arrayList0 = new ArrayList();
ContentResolver contentResolver0 = context0.getContentResolver();
try {
cursor0 = contentResolver0.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"_data"}, "bucket_display_name = ?", new String[]{"Screenshots"}, "date_added DESC");
if(cursor0 == null) {
goto label_18;
}
}
catch(Exception exception0) {
return null;
}

try {
if(!cursor0.moveToFirst()) {
goto label_18;
}

int v = cursor0.getColumnIndexOrThrow("_data");
arrayList0.add(cursor0.getString(v));
s = cursor0.getString(v);
goto label_16;
}
catch(Throwable throwable0) {
}

try {
cursor0.close();
throw throwable0;
}
catch(Throwable throwable1) {
}

try {
throwable0.addSuppressed(throwable1);
throw throwable0;
label_16:
cursor0.close();
return s;
label_18:
if(cursor0 != null) {
cursor0.close();
return null;
}

return null;
}
catch(Exception exception0) {
}

return null;
}

// This method was un-flattened
public static int lcg(BigInteger bigInteger0, BigInteger bigInteger1, BigInteger bigInteger2, BigInteger bigInteger3, BigInteger bigInteger4) {
BigInteger bigInteger5 = bigInteger3;
BigInteger bigInteger6 = BigInteger.ZERO;
while(bigInteger6.compareTo(bigInteger4) < 0) {
BigInteger bigInteger7 = bigInteger0.multiply(bigInteger5).add(bigInteger1).mod(bigInteger2);
bigInteger6 = bigInteger6.add(BigInteger.ONE);
bigInteger5 = bigInteger7;
}

return bigInteger5.and(BigInteger.valueOf(0xFFL)).intValue();
}

@a
public static void m(Context context0) {
String s = object.getFirstScreenshot(context0);
Log.i("null", s);
try {
File file0 = new File(s);
long v = file0.length();
Log.i("Decrypt", String.valueOf(v));
byte[] arr_b = new byte[((int)v)];
FileInputStream fileInputStream0 = new FileInputStream(file0);
fileInputStream0.read(arr_b);
fileInputStream0.close();
Base64.getEncoder().encodeToString(arr_b);
__alloc_invoke__ u0.a, Object().a(arr_b); // Mismatched object-allocation/constructor-invocation, likely indicating an inlined constructor call
FileOutputStream fileOutputStream0 = new FileOutputStream("/sdcard/flag.png");
fileOutputStream0.write(arr_b);
fileOutputStream0.close();
}
catch(Exception exception0) {
}
}
}

发现是将图片加密后用base64进行了编码,在内存中确实获取到了一大串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
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
package u0;

import android.util.Log;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import nu.ll.object;

public final class a {
public int a;

// This method could be un-flattened, but the demo build has limitations that prevented it
public final void a(byte[] arr_b) {
SecretKeySpec secretKeySpec0 = null;
Cipher cipher0 = null;
int v = 0;
int v1 = 0;
byte[] arr_b1 = null;
int v2 = 0;
int v3 = 0;
int v4 = 0;
String s = null;
String s1 = null;
StringBuilder stringBuilder0 = null;
int v5 = 0;
int v6 = 0;
label_14:
switch(s2.hashCode() ^ 390 ^ 829 ^ 461 ^ 1020 ^ 366 ^ 5 ^ 0x304 ^ 0xFA400AD5) {

v5 = v1;

System.arraycopy(arr_b1, 0, arr_b, v1, 16);

v = arr_b.length;

return;

stringBuilder0.append(s);

Thread.sleep(5000L);

cipher0.init(2, secretKeySpec0);

secretKeySpec0 = new SecretKeySpec(Arrays.copyOfRange(arr_b, 0, 16), "AES");

Log.i(s1, stringBuilder0.toString());

s1 = "Decrypt";

v2 = arr_b1[v4];

v1 = v6 + 16;

v4 = 0;

v6 = v5;

v3 = v4 + 1;

stringBuilder0 = new StringBuilder();

stringBuilder0.append(": ");

cipher0 = Cipher.getInstance("AES/ECB/NoPadding");

s = Base64.getEncoder().encodeToString(arr_b1);

stringBuilder0.append(this.a);

arr_b1[v4] = (byte)(((byte)(object.lcg(BigInteger.valueOf(0x11021L), BigInteger.valueOf(0x10001L), BigInteger.valueOf(0x8000000L), BigInteger.valueOf(10L), BigInteger.valueOf(2L).pow(v6 / 16)) ^ v4)) ^ v2);

v4 = v3;

v6 = 0;

this.a = v6 + v4;

arr_b1 = cipher0.doFinal(arr_b, v1, 16);
}
}
}
}

原函数中有大量平坦化混淆(已去除),可以看到函数中存在一个AES-ECB加密/解密,密钥为文件前16位字符,还有一个已知初始化值的LCG异或,编写脚本解密:

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
from Crypto.Cipher import AES
from tqdm import tqdm

def lcg(a, c, m, seed, n):
if n == 0:
return seed
if a == 1:
return (seed + c * n) % m
a_n = pow(a, n, m * (a - 1))
state = (pow(a, n, m) * seed + c * (a_n - 1) // (a - 1)) % m
return state & 0xFF

def pad(data, block_size=16):
padding_length = block_size - (len(data) % block_size)
return data + bytes([padding_length] * padding_length)

def decrypt_block(block, block_index, cipher):
decrypted_block = bytearray(cipher.decrypt(block))
n = pow(2, block_index)
for j in range(16):
lcg_val = lcg(a=0x11021, c=0x10001, m=0x8000000, seed=10, n=n)
decrypted_block[j] ^= (lcg_val ^ j)
return decrypted_block

def decrypt_file(full_decrypt=True, debug_size=1024):
try:
with open("data.dat", "rb") as f:
encrypted_data = f.read()
print(f"file length:{len(encrypted_data)} bytes")

key = encrypted_data[:16]
cipher = AES.new(key, AES.MODE_ECB)

if not full_decrypt:
debug_data = encrypted_data[:debug_size + 16]
encrypted_data = debug_data
print(f"debugging... Only decrypt {debug_size} bytes")

decrypted = bytearray()
block_size = 16
start = 16
encrypted_blocks = encrypted_data[start:]

blocks = (len(encrypted_blocks) + block_size - 1) // block_size
for i in tqdm(range(0, len(encrypted_blocks), block_size), total=blocks, desc="Decrypting"):
block = encrypted_blocks[i:i+block_size]
if len(block) % block_size != 0:
block = pad(block)

block_index = i // block_size
decrypted_block = decrypt_block(block, block_index, cipher)
decrypted.extend(decrypted_block)

output_file = "flag.png" if full_decrypt else "flag_part.png"
with open(output_file, "wb") as f:
f.write(decrypted)

print(f"{'Full' if full_decrypt else 'Debug'} decrypt complete!File saved to {output_file}")

except FileNotFoundError:
print("File not found.")
except Exception as e:
print(f"Error:{e}")

# decrypt_file(full_decrypt=False, debug_size=38400)
decrypt_file(full_decrypt=True)

得到图片:

flag{C8155278-06D9-4087-AE17-A3C9DAB399F3}

YA

用yara源码和yarac盲测规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
rule A
{
meta:
description = "solve this"

strings:
$a = "?????" nocase wide ascii

condition:
$a and
(@a[0] + 0xC1 == 0xCA) and
(@a[0] - 0xC1 == 0xCA) and
(@a[0] + 0xC1 == 0xCA) and
(@a[0] - 0xC1 == 0xCA) and
(@a[0] * 0xC1 == 0xCA) and
(@a[0] ^ 0xC1 == 0xCA) and
(@a[0] * 0xC1 == 0xCA) and
(@a[0] ^ 0xC1 == 0xCA) and
(@a[0] & 0xC1 == 0xCA) and
(@a[0] | 0xC1 == 0xCA) and
(@a[0] & 0xC1 == 0xCA) and
(@a[0] | 0xC1 == 0xCA)
}

生成的二进制文件的hex:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3C 01 00 00 00 00 00 00 0D 03 00 00 00 00 00 00
00 16 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 6A 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 6B 3F CA
64 01 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 6A 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 6B 3F CA
64 01 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 6C 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 07 3F CA
64 01 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 6C 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 07 3F CA
64 01 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 05 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 06 3F CA
64 01 2F 18 00 00 00 3F 00 0D 03 00 00 00 00 00
00 00 19 3F C1 05 3F CA 64 01 2F 18 00 00 00 3F
00 0D 03 00 00 00 00 00 00 00 19 3F C1 06 3F CA
64 01 1D 00 00 00 00 00 00 00 00 FF

结合yara的libyara源代码中的exec.h写虚拟机解析脚本:

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
150
151
152
opcode_map = {
0x01: "OP_AND",
0x02: "OP_OR",
0x03: "OP_NOT",
0x04: "OP(~)",
0x05: "OP(&)",
0x06: "OP(|)",
0x07: "OP(^)",
0x08: "OP_SHL",
0x09: "OP_SHR",
0x0A: "OP_MOD",
0x0B: "OP_INT_TO_DBL",
0x0C: "OP_STR_TO_BOOL",
0x0D: "OP_PUSH",
0x0E: "OP_POP",
0x0F: "OP_CALL",
0x10: "OP_OBJ_LOAD",
0x11: "OP_OBJ_VALUE",
0x12: "OP_OBJ_FIELD",
0x13: "OP_INDEX_ARRAY",
0x14: "OP_COUNT",
0x15: "OP_LENGTH",
0x16: "OP_FOUND",
0x17: "OP_FOUND_AT",
0x18: "OP_FOUND_IN",
0x19: "OP_OFFSET",
0x1A: "OP_OF",
0x1B: "OP_PUSH_RULE",
0x1C: "OP_INIT_RULE",
0x1D: "OP_MATCH_RULE",
0x1E: "OP_INCR_M",
0x1F: "OP_CLEAR_M",
0x20: "OP_ADD_M",
0x21: "OP_POP_M",
0x22: "OP_PUSH_M",
0x23: "OP_SET_M",
0x24: "OP_SWAPUNDEF",
0x25: "OP_FILESIZE",
0x26: "OP_ENTRYPOINT",
0x27: "OP_UNUSED",
0x28: "OP_MATCHES",
0x29: "OP_IMPORT",
0x2A: "OP_LOOKUP_DICT",
0x2B: "OP_JUNDEF",
0x2C: "OP_JUNDEF_P",
0x2D: "OP_JNUNDEF",
0x2E: "OP_JNUNDEF_P",
0x2F: "OP_JFALSE",
0x30: "OP_JFALSE_P",
0x31: "OP_JTRUE",
0x32: "OP_JTRUE_P",
0x33: "OP_JL_P",
0x34: "OP_JLE_P",
0x35: "OP_ITER_NEXT",
0x36: "OP_ITER_START_ARRAY",
0x37: "OP_ITER_START_DICT",
0x38: "OP_ITER_START_INT_RANGE",
0x39: "OP_ITER_START_INT_ENUM",
0x3A: "OP_ITER_START_STRING_SET",
0x3B: "OP_ITER_CONDITION",
0x3C: "OP_ITER_END",
0x3D: "OP_JZ",
0x3E: "OP_JZ_P",
0x3F: "OP_PUSH_8",
0x40: "OP_PUSH_16",
0x41: "OP_PUSH_32",
0x42: "OP_PUSH_U",
0x43: "OP_CONTAINS",
0x44: "OP_STARTSWITH",
0x45: "OP_ENDSWITH",
0x46: "OP_ICONTAINS",
0x47: "OP_ISTARTSWITH",
0x48: "OP_IENDSWITH",
0x49: "OP_IEQUALS",
0x4A: "OP_OF_PERCENT",
0x4B: "OP_OF_FOUND_IN",
0x4C: "OP_COUNT_IN",
0x4D: "OP_DEFINED",
0x4E: "OP_ITER_START_TEXT_STRING_SET",
0x4F: "OP_OF_FOUND_AT",
100: "OP(==)",
101: "OP(!=)",
102: "OP(<)",
103: "OP(>)",
104: "OP(<=)",
105: "OP(>=)",
106: "OP(+)",
107: "OP(-)",
108: "OP(*)",
109: "OP(/)",
110: "OP_INT_MINUS",
120: "OP_DBL_EQ",
121: "OP_DBL_NEQ",
122: "OP_DBL_LT",
123: "OP_DBL_GT",
124: "OP_DBL_LE",
125: "OP_DBL_GE",
126: "OP_DBL_ADD",
127: "OP_DBL_SUB",
128: "OP_DBL_MUL",
129: "OP_DBL_DIV",
130: "OP_DBL_MINUS",
140: "OP_STR_EQ",
141: "OP_STR_NEQ",
142: "OP_STR_LT",
143: "OP_STR_GT",
144: "OP_STR_LE",
145: "OP_STR_GE",
240: "OP_INT8",
241: "OP_INT16",
242: "OP_INT32",
243: "OP_UINT8",
244: "OP_UINT16",
245: "OP_UINT32",
246: "OP_INT8BE",
247: "OP_INT16BE",
248: "OP_INT32BE",
249: "OP_UINT8BE",
250: "OP_UINT16BE",
251: "OP_UINT32BE",
}

opcode_name_map = {v: k for k, v in opcode_map.items()}

def disassemble_yara_bytecode(bytecode: bytes):
print("Off | Opcode / Data")
print("-----|-----------------------------")

i = 0
while i < len(bytecode):
byte = bytecode[i]

if byte == 0x00:
i += 1
continue

if byte == 0x3F:
if i + 2 < len(bytecode):
value = bytecode[i + 1]
addr = bytecode[i + 2]
print(f"{i:04d} | OP_PUSH_8 (value: 0x{value:02X})")
i += 2
else:
print(f"{i:04d} | OP_PUSH_8 (ERROR: Not enough bytes for parameters)")
i += 1
else:
name = opcode_map.get(byte, f"UNKNOWN (0x{byte:02X})")
print(f"{i:04d} | {name}")
i += 1

example_bytecode = bytearray.fromhex("2805000000000000253f2a692f120500003f011f00000000000000001f01000000000000002102000000000000003f00253f2a6b383521030000000000000032c10400002203000000000000003f006af33f803f006a073fe6642f1c0000002203000000000000003f016af33f803f016a073fed64012f1c0000002203000000000000003f026af33f803f026a073fe364012f1c0000002203000000000000003f036af33f803f036a073fe464012f1c0000002203000000000000003f046af33f803f046a073fff64012f1c0000002203000000000000003f056af33f803f056a073fe664012f1c0000002203000000000000003f066af33f803f066a073fe464012f1c0000002203000000000000003f076af33f803f076a073fbe64012f1c0000002203000000000000003f086af33f803f086a073fba64012f1c0000002203000000000000003f096af33f803f096a073fbd64012f1c0000002203000000000000003f0a6af33f803f0a6a073fbb64012f1c0000002203000000000000003f0b6af33f803f0b6a073fb864012f1c0000002203000000000000003f0c6af33f803f0c6a073fbf64012f1c0000002203000000000000003f0d6af33f803f0d6a073fa064012f1c0000002203000000000000003f0e6af33f803f0e6a073fba64012f1c0000002203000000000000003f0f6af33f803f0f6a073fed64012f1c0000002203000000000000003f106af33f803f106a073fa264012f1c0000002203000000000000003f116af33f803f116a073fa664012f1c0000002203000000000000003f126af33f803f126a073fbf64012f1c0000002203000000000000003f136af33f803f136a073fa764012f1c0000002203000000000000003f146af33f803f146a073fac64012f1c0000002203000000000000003f156af33f803f156a073fa364012f1c0000002203000000000000003f166af33f803f166a073fa064012f1c0000002203000000000000003f176af33f803f176a073fba64012f1c0000002203000000000000003f186af33f803f186a073ff964012f1c0000002203000000000000003f196af33f803f196a073faf64012f1c0000002203000000000000003f1a6af33f803f1a6a073fa364012f1c0000002203000000000000003f1b6af33f803f1b6a073faf64012f1c0000002203000000000000003f1c6af33f803f1c6a073fb164012f1c0000002203000000000000003f1d6af33f803f1d6a073faa64012f1c0000002203000000000000003f1e6af33f803f1e6a073ffb64012f1c0000002203000000000000003f1f6af33f803f1f6a073fac64012f1c0000002203000000000000003f206af33f803f206a073fc564012f1c0000002203000000000000003f216af33f803f216a073f9064012f1c0000002203000000000000003f226af33f803f226a073fc364012f1c0000002203000000000000003f236af33f803f236a073fc264012f1c0000002203000000000000003f246af33f803f246a073fc264012f1c0000002203000000000000003f256af33f803f256a073f9c64012f1c0000002203000000000000003f266af33f803f266a073fc264012f1c0000002203000000000000003f276af33f803f276a073fc364012f1c0000002203000000000000003f286af33f803f286a073f9964012f1c0000002203000000000000003f296af33f803f296a073fd464011e01000000000000002200000000000000002202000000000000003b200000000000000000323afbffff0e2201000000000000002200000000000000002202000000000000003c011d0000000000000000ff")
disassemble_yara_bytecode(example_bytecode)

输出:

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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
Off  | code / Data
-----|-----------------------------
0000 | MATCHES
0001 | (&)
0008 | FILESIZE
0009 | PUSH8 (0x2A)
0011 | (>=)
0012 | JFALSE
0013 | OBJFIELD
0014 | (&)
0017 | PUSH8 (0x01)
0019 | CLEARM
0028 | CLEARM
0029 | AND
0037 | PM
0038 | OR
0046 | PUSH8 (0x00)
0048 | FILESIZE
0049 | PUSH8 (0x2A)
0051 | (-)
0052 | ITERSTARTINTRANGE
0053 | ITERNEXT
0054 | PM
0055 | NOT
0063 | JTRUEP
0064 | UNKNOWN (0xC1)
0065 | (~)
0068 | PUSHM
0069 | NOT
0077 | PUSH8 (0x00)
0079 | (+)
0080 | UINT8
0081 | PUSH8 (0x80)
0083 | PUSH8 (0x00)
0085 | (+)
0086 | (^)
0087 | PUSH8 (0xE6)
0089 | (==)
0090 | JFALSE
0091 | INITRULE
0095 | PUSHM
0096 | NOT
0104 | PUSH8 (0x01)
0106 | (+)
0107 | UINT8
0108 | PUSH8 (0x80)
0110 | PUSH8 (0x01)
0112 | (+)
0113 | (^)
0114 | PUSH8 (0xED)
0116 | (==)
0117 | AND
0118 | JFALSE
0119 | INITRULE
0123 | PUSHM
0124 | NOT
0132 | PUSH8 (0x02)
0134 | (+)
0135 | UINT8
0136 | PUSH8 (0x80)
0138 | PUSH8 (0x02)
0140 | (+)
0141 | (^)
0142 | PUSH8 (0xE3)
0144 | (==)
0145 | AND
0146 | JFALSE
0147 | INITRULE
0151 | PUSHM
0152 | NOT
0160 | PUSH8 (0x03)
0162 | (+)
0163 | UINT8
0164 | PUSH8 (0x80)
0166 | PUSH8 (0x03)
0168 | (+)
0169 | (^)
0170 | PUSH8 (0xE4)
0172 | (==)
0173 | AND
0174 | JFALSE
0175 | INITRULE
0179 | PUSHM
0180 | NOT
0188 | PUSH8 (0x04)
0190 | (+)
0191 | UINT8
0192 | PUSH8 (0x80)
0194 | PUSH8 (0x04)
0196 | (+)
0197 | (^)
0198 | PUSH8 (0xFF)
0200 | (==)
0201 | AND
0202 | JFALSE
0203 | INITRULE
0207 | PUSHM
0208 | NOT
0216 | PUSH8 (0x05)
0218 | (+)
0219 | UINT8
0220 | PUSH8 (0x80)
0222 | PUSH8 (0x05)
0224 | (+)
0225 | (^)
0226 | PUSH8 (0xE6)
0228 | (==)
0229 | AND
0230 | JFALSE
0231 | INITRULE
0235 | PUSHM
0236 | NOT
0244 | PUSH8 (0x06)
0246 | (+)
0247 | UINT8
0248 | PUSH8 (0x80)
0250 | PUSH8 (0x06)
0252 | (+)
0253 | (^)
0254 | PUSH8 (0xE4)
0256 | (==)
0257 | AND
0258 | JFALSE
0259 | INITRULE
0263 | PUSHM
0264 | NOT
0272 | PUSH8 (0x07)
0274 | (+)
0275 | UINT8
0276 | PUSH8 (0x80)
0278 | PUSH8 (0x07)
0280 | (+)
0281 | (^)
0282 | PUSH8 (0xBE)
0284 | (==)
0285 | AND
0286 | JFALSE
0287 | INITRULE
0291 | PUSHM
0292 | NOT
0300 | PUSH8 (0x08)
0302 | (+)
0303 | UINT8
0304 | PUSH8 (0x80)
0306 | PUSH8 (0x08)
0308 | (+)
0309 | (^)
0310 | PUSH8 (0xBA)
0312 | (==)
0313 | AND
0314 | JFALSE
0315 | INITRULE
0319 | PUSHM
0320 | NOT
0328 | PUSH8 (0x09)
0330 | (+)
0331 | UINT8
0332 | PUSH8 (0x80)
0334 | PUSH8 (0x09)
0336 | (+)
0337 | (^)
0338 | PUSH8 (0xBD)
0340 | (==)
0341 | AND
0342 | JFALSE
0343 | INITRULE
0347 | PUSHM
0348 | NOT
0356 | PUSH8 (0x0A)
0358 | (+)
0359 | UINT8
0360 | PUSH8 (0x80)
0362 | PUSH8 (0x0A)
0364 | (+)
0365 | (^)
0366 | PUSH8 (0xBB)
0368 | (==)
0369 | AND
0370 | JFALSE
0371 | INITRULE
0375 | PUSHM
0376 | NOT
0384 | PUSH8 (0x0B)
0386 | (+)
0387 | UINT8
0388 | PUSH8 (0x80)
0390 | PUSH8 (0x0B)
0392 | (+)
0393 | (^)
0394 | PUSH8 (0xB8)
0396 | (==)
0397 | AND
0398 | JFALSE
0399 | INITRULE
0403 | PUSHM
0404 | NOT
0412 | PUSH8 (0x0C)
0414 | (+)
0415 | UINT8
0416 | PUSH8 (0x80)
0418 | PUSH8 (0x0C)
0420 | (+)
0421 | (^)
0422 | PUSH8 (0xBF)
0424 | (==)
0425 | AND
0426 | JFALSE
0427 | INITRULE
0431 | PUSHM
0432 | NOT
0440 | PUSH8 (0x0D)
0442 | (+)
0443 | UINT8
0444 | PUSH8 (0x80)
0446 | PUSH8 (0x0D)
0448 | (+)
0449 | (^)
0450 | PUSH8 (0xA0)
0452 | (==)
0453 | AND
0454 | JFALSE
0455 | INITRULE
0459 | PUSHM
0460 | NOT
0468 | PUSH8 (0x0E)
0470 | (+)
0471 | UINT8
0472 | PUSH8 (0x80)
0474 | PUSH8 (0x0E)
0476 | (+)
0477 | (^)
0478 | PUSH8 (0xBA)
0480 | (==)
0481 | AND
0482 | JFALSE
0483 | INITRULE
0487 | PUSHM
0488 | NOT
0496 | PUSH8 (0x0F)
0498 | (+)
0499 | UINT8
0500 | PUSH8 (0x80)
0502 | PUSH8 (0x0F)
0504 | (+)
0505 | (^)
0506 | PUSH8 (0xED)
0508 | (==)
0509 | AND
0510 | JFALSE
0511 | INITRULE
0515 | PUSHM
0516 | NOT
0524 | PUSH8 (0x10)
0526 | (+)
0527 | UINT8
0528 | PUSH8 (0x80)
0530 | PUSH8 (0x10)
0532 | (+)
0533 | (^)
0534 | PUSH8 (0xA2)
0536 | (==)
0537 | AND
0538 | JFALSE
0539 | INITRULE
0543 | PUSHM
0544 | NOT
0552 | PUSH8 (0x11)
0554 | (+)
0555 | UINT8
0556 | PUSH8 (0x80)
0558 | PUSH8 (0x11)
0560 | (+)
0561 | (^)
0562 | PUSH8 (0xA6)
0564 | (==)
0565 | AND
0566 | JFALSE
0567 | INITRULE
0571 | PUSHM
0572 | NOT
0580 | PUSH8 (0x12)
0582 | (+)
0583 | UINT8
0584 | PUSH8 (0x80)
0586 | PUSH8 (0x12)
0588 | (+)
0589 | (^)
0590 | PUSH8 (0xBF)
0592 | (==)
0593 | AND
0594 | JFALSE
0595 | INITRULE
0599 | PUSHM
0600 | NOT
0608 | PUSH8 (0x13)
0610 | (+)
0611 | UINT8
0612 | PUSH8 (0x80)
0614 | PUSH8 (0x13)
0616 | (+)
0617 | (^)
0618 | PUSH8 (0xA7)
0620 | (==)
0621 | AND
0622 | JFALSE
0623 | INITRULE
0627 | PUSHM
0628 | NOT
0636 | PUSH8 (0x14)
0638 | (+)
0639 | UINT8
0640 | PUSH8 (0x80)
0642 | PUSH8 (0x14)
0644 | (+)
0645 | (^)
0646 | PUSH8 (0xAC)
0648 | (==)
0649 | AND
0650 | JFALSE
0651 | INITRULE
0655 | PUSHM
0656 | NOT
0664 | PUSH8 (0x15)
0666 | (+)
0667 | UINT8
0668 | PUSH8 (0x80)
0670 | PUSH8 (0x15)
0672 | (+)
0673 | (^)
0674 | PUSH8 (0xA3)
0676 | (==)
0677 | AND
0678 | JFALSE
0679 | INITRULE
0683 | PUSHM
0684 | NOT
0692 | PUSH8 (0x16)
0694 | (+)
0695 | UINT8
0696 | PUSH8 (0x80)
0698 | PUSH8 (0x16)
0700 | (+)
0701 | (^)
0702 | PUSH8 (0xA0)
0704 | (==)
0705 | AND
0706 | JFALSE
0707 | INITRULE
0711 | PUSHM
0712 | NOT
0720 | PUSH8 (0x17)
0722 | (+)
0723 | UINT8
0724 | PUSH8 (0x80)
0726 | PUSH8 (0x17)
0728 | (+)
0729 | (^)
0730 | PUSH8 (0xBA)
0732 | (==)
0733 | AND
0734 | JFALSE
0735 | INITRULE
0739 | PUSHM
0740 | NOT
0748 | PUSH8 (0x18)
0750 | (+)
0751 | UINT8
0752 | PUSH8 (0x80)
0754 | PUSH8 (0x18)
0756 | (+)
0757 | (^)
0758 | PUSH8 (0xF9)
0760 | (==)
0761 | AND
0762 | JFALSE
0763 | INITRULE
0767 | PUSHM
0768 | NOT
0776 | PUSH8 (0x19)
0778 | (+)
0779 | UINT8
0780 | PUSH8 (0x80)
0782 | PUSH8 (0x19)
0784 | (+)
0785 | (^)
0786 | PUSH8 (0xAF)
0788 | (==)
0789 | AND
0790 | JFALSE
0791 | INITRULE
0795 | PUSHM
0796 | NOT
0804 | PUSH8 (0x1A)
0806 | (+)
0807 | UINT8
0808 | PUSH8 (0x80)
0810 | PUSH8 (0x1A)
0812 | (+)
0813 | (^)
0814 | PUSH8 (0xA3)
0816 | (==)
0817 | AND
0818 | JFALSE
0819 | INITRULE
0823 | PUSHM
0824 | NOT
0832 | PUSH8 (0x1B)
0834 | (+)
0835 | UINT8
0836 | PUSH8 (0x80)
0838 | PUSH8 (0x1B)
0840 | (+)
0841 | (^)
0842 | PUSH8 (0xAF)
0844 | (==)
0845 | AND
0846 | JFALSE
0847 | INITRULE
0851 | PUSHM
0852 | NOT
0860 | PUSH8 (0x1C)
0862 | (+)
0863 | UINT8
0864 | PUSH8 (0x80)
0866 | PUSH8 (0x1C)
0868 | (+)
0869 | (^)
0870 | PUSH8 (0xB1)
0872 | (==)
0873 | AND
0874 | JFALSE
0875 | INITRULE
0879 | PUSHM
0880 | NOT
0888 | PUSH8 (0x1D)
0890 | (+)
0891 | UINT8
0892 | PUSH8 (0x80)
0894 | PUSH8 (0x1D)
0896 | (+)
0897 | (^)
0898 | PUSH8 (0xAA)
0900 | (==)
0901 | AND
0902 | JFALSE
0903 | INITRULE
0907 | PUSHM
0908 | NOT
0916 | PUSH8 (0x1E)
0918 | (+)
0919 | UINT8
0920 | PUSH8 (0x80)
0922 | PUSH8 (0x1E)
0924 | (+)
0925 | (^)
0926 | PUSH8 (0xFB)
0928 | (==)
0929 | AND
0930 | JFALSE
0931 | INITRULE
0935 | PUSHM
0936 | NOT
0944 | PUSH8 (0x1F)
0946 | (+)
0947 | UINT8
0948 | PUSH8 (0x80)
0950 | PUSH8 (0x1F)
0952 | (+)
0953 | (^)
0954 | PUSH8 (0xAC)
0956 | (==)
0957 | AND
0958 | JFALSE
0959 | INITRULE
0963 | PUSHM
0964 | NOT
0972 | PUSH8 (0x20)
0974 | (+)
0975 | UINT8
0976 | PUSH8 (0x80)
0978 | PUSH8 (0x20)
0980 | (+)
0981 | (^)
0982 | PUSH8 (0xC5)
0984 | (==)
0985 | AND
0986 | JFALSE
0987 | INITRULE
0991 | PUSHM
0992 | NOT
1000 | PUSH8 (0x21)
1002 | (+)
1003 | UINT8
1004 | PUSH8 (0x80)
1006 | PUSH8 (0x21)
1008 | (+)
1009 | (^)
1010 | PUSH8 (0x90)
1012 | (==)
1013 | AND
1014 | JFALSE
1015 | INITRULE
1019 | PUSHM
1020 | NOT
1028 | PUSH8 (0x22)
1030 | (+)
1031 | UINT8
1032 | PUSH8 (0x80)
1034 | PUSH8 (0x22)
1036 | (+)
1037 | (^)
1038 | PUSH8 (0xC3)
1040 | (==)
1041 | AND
1042 | JFALSE
1043 | INITRULE
1047 | PUSHM
1048 | NOT
1056 | PUSH8 (0x23)
1058 | (+)
1059 | UINT8
1060 | PUSH8 (0x80)
1062 | PUSH8 (0x23)
1064 | (+)
1065 | (^)
1066 | PUSH8 (0xC2)
1068 | (==)
1069 | AND
1070 | JFALSE
1071 | INITRULE
1075 | PUSHM
1076 | NOT
1084 | PUSH8 (0x24)
1086 | (+)
1087 | UINT8
1088 | PUSH8 (0x80)
1090 | PUSH8 (0x24)
1092 | (+)
1093 | (^)
1094 | PUSH8 (0xC2)
1096 | (==)
1097 | AND
1098 | JFALSE
1099 | INITRULE
1103 | PUSHM
1104 | NOT
1112 | PUSH8 (0x25)
1114 | (+)
1115 | UINT8
1116 | PUSH8 (0x80)
1118 | PUSH8 (0x25)
1120 | (+)
1121 | (^)
1122 | PUSH8 (0x9C)
1124 | (==)
1125 | AND
1126 | JFALSE
1127 | INITRULE
1131 | PUSHM
1132 | NOT
1140 | PUSH8 (0x26)
1142 | (+)
1143 | UINT8
1144 | PUSH8 (0x80)
1146 | PUSH8 (0x26)
1148 | (+)
1149 | (^)
1150 | PUSH8 (0xC2)
1152 | (==)
1153 | AND
1154 | JFALSE
1155 | INITRULE
1159 | PUSHM
1160 | NOT
1168 | PUSH8 (0x27)
1170 | (+)
1171 | UINT8
1172 | PUSH8 (0x80)
1174 | PUSH8 (0x27)
1176 | (+)
1177 | (^)
1178 | PUSH8 (0xC3)
1180 | (==)
1181 | AND
1182 | JFALSE
1183 | INITRULE
1187 | PUSHM
1188 | NOT
1196 | PUSH8 (0x28)
1198 | (+)
1199 | UINT8
1200 | PUSH8 (0x80)
1202 | PUSH8 (0x28)
1204 | (+)
1205 | (^)
1206 | PUSH8 (0x99)
1208 | (==)
1209 | AND
1210 | JFALSE
1211 | INITRULE
1215 | PUSHM
1216 | NOT
1224 | PUSH8 (0x29)
1226 | (+)
1227 | UINT8
1228 | PUSH8 (0x80)
1230 | PUSH8 (0x29)
1232 | (+)
1233 | (^)
1234 | PUSH8 (0xD4)
1236 | (==)
1237 | AND
1238 | INCRM
1239 | AND
1247 | PUSHM
1256 | PUSHM
1257 | OR
1265 | ITERCONDITION
1266 | ADDM
1275 | JTRUEP
1276 | ITERSTARTSTRINGSET
1277 | UINT32BE
1278 | UNKNOWN (0xFF)
1279 | UNKNOWN (0xFF)
1280 | P
1281 | PUSHM
1282 | AND
1290 | PUSHM
1299 | PUSHM
1300 | OR
1308 | ITEREND
1309 | AND
1310 | MATCHRULE
1319 | UNKNOWN (0xFF)

发现加密方式是异或0x80的定值和索引,密文已经给出,编写脚本解密:

1
2
3
4
5
targets = bytearray.fromhex("E6EDE3E4FFE6E4BEBABDBBB8BFA0BAEDA2A6BFA7ACA3A0BAF9AFA3AFB1AAFBACC590C3C2C29CC2C399D4")
for i in range(len(targets)):
targets[i] ^= 0x80
targets[i] ^= i
print(targets)

flag{cb924133-4b27-4866-a694-7e3e1aaf9dd1}