浙江省赛决赛2025_Re

总结

线下赛暴露了自己很多问题,继续沉淀

Reverse

你是我的天命人吗

类smc,跟进加载后的情况

1
2
3
4
5
6
7
enc=bytes.fromhex('4440514050437D3E386C3A3F3E6F386D232124202D7420742C2F2E282525782D124344471015405A')  
flag=''
for i in range(len(enc)):
tmp=enc[i]^i
flag+=chr(tmp)
print(flag)
#DASCTF{90e042b6b30639a6c464398f22bfd40f}

androidtest

xor+base32

base32,一直以为是变表,其实没变,AbstractC0199a.a混淆处未知,比赛时忘用jeb分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static final String f1683z = w.i("vQWWGCrOG6+1DZ4QIsYTt60Vhgg63gu/pR3nb1u9atDB\n", "/EfVXG+IXOc=\n");

public static String i(String str, String str2) {
byte[] a2 = AbstractC0199a.a(str);
byte[] a3 = AbstractC0199a.a(str2);
int length = a2.length;
int length2 = a3.length;
int i2 = 0;
int i3 = 0;
while (i2 < length) {
if (i3 >= length2) {
i3 = 0;
}
a2[i2] = (byte) (a2[i2] ^ a3[i3]);
i2++;
i3++;
}
return new String(a2, StandardCharsets.UTF_8);
}

换jeb清晰很多

so层enc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
__int64 __fastcall Java_com_example_myapplication_MainActivity_ret_1str(__int64 a1, __int64 a2, __int64 a3)
{
unsigned int v4; // r15d
const char *s1; // rax
const char *s1_1; // r12

v4 = 0;
s1 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);
if ( s1 )
{
s1_1 = s1;
LOBYTE(v4) = strcmp(s1, "NBWX633YNJLU2QSILZBUKSDTJVBFQRLTJVBEQ42YJFPVQ42FL5ZUKQSYJFPESX2YIVBEWUI=") == 0;
(*(void (__fastcall **)(__int64, __int64, const char *))(*(_QWORD *)a1 + 1328LL))(a1, a3, s1_1);
}
return v4;
}

解密

1
2
3
4
5
6
7
8
9
10
enc='NBWX633YNJLU2QSILZBUKSDTJVBFQRLTJVBEQ42YJFPVQ42FL5ZUKQSYJFPESX2YIVBEWUI='
# table='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
tmp=base64.b32decode(enc)
flag=''
print(tmp)
for i in range(len(tmp)):
flag+=chr(tmp[i]^44)
print(flag)
# b'hm\x7foxjWMBH^CEHsMBXEsMBHsXI_XsE_sEBXI^I_XEBKQ'
# DASCTF{android_anti_and_test_is_interesting}

Warning! Warning!(复现)

vm,tracelog还原opcode

trace xor

1
2
3
4
5
6
7
8
import idc

base=idc.get_reg_value("r9")
index=idc.get_reg_value("rdx")
val=idc.read_dbg_qword(base+index*8)

v1=idc.get_reg_value("rax")
print(f'XOR: {val:#x} ^ {v1:#x} = {val^v1:#x}')

trace cmp

1
2
3
4
5
6
7
8
import idc

base=idc.get_reg_value("rsi")
index=idc.get_reg_value("rcx")
val=idc.read_dbg_qword(base+index*8)

v1=idc.get_reg_value("rax")
print(f'CMP: {val:#x} == {v1:#x}')

命令行输入检测,长度为0x40,按长度位异或,再是0x100=256,联想rc4,还是凭感觉吧,将中间结果与密钥流异或

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
XOR: 0x31 ^ 0x0 = 0x31
CMP: 0x40 == 0x1
XOR: 0x31 ^ 0x1 = 0x30
CMP: 0x40 == 0x2
XOR: 0x31 ^ 0x2 = 0x33
CMP: 0x40 == 0x3
XOR: 0x31 ^ 0x3 = 0x32
CMP: 0x40 == 0x4
XOR: 0x31 ^ 0x4 = 0x35
CMP: 0x40 == 0x5
........................
XOR: 0x31 ^ 0x3e = 0xf
CMP: 0x40 == 0x3f
XOR: 0x31 ^ 0x3f = 0xe
CMP: 0x40 == 0x40
CMP: 0x100 == 0x1
CMP: 0x100 == 0x2
CMP: 0x100 == 0x3
........................
CMP: 0x100 == 0xff
CMP: 0x100 == 0x100
XOR: 0x31 ^ 0x50 = 0x61
CMP: 0x1 == 0x2e
XOR: 0x30 ^ 0x67 = 0x57
CMP: 0x2 == 0x2e
XOR: 0x33 ^ 0x21 = 0x12
CMP: 0x3 == 0x2e
XOR: 0x32 ^ 0x2b = 0x19
CMP: 0x4 == 0x2e
XOR: 0x35 ^ 0xce = 0xfb
CMP: 0x5 == 0x2e
XOR: 0x34 ^ 0xd7 = 0xe3
CMP: 0x6 == 0x2e
XOR: 0x37 ^ 0x84 = 0xb3
CMP: 0x7 == 0x2e
........................

异或回去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
key=[0x50, 0x67, 0x21, 0x2b, 0xce, 0xd7, 0x84, 0x3a, 0xf5, 0xc2,
0xc2, 0x22, 0x48, 0x1d, 0x14, 0x2a, 0x71, 0x25, 0xa7, 0x73,
0x3c, 0x9c, 0x72, 0xfe, 0x3c, 0xb7, 0xad, 0x80, 0xa9, 0x6f,
0x37, 0x46, 0x91, 0x32, 0xb4, 0xf7, 0xa5, 0xad, 0xd8, 0x6b,
0x35, 0x8c, 0xe4, 0x0, 0x20, 0x2e]

enc=[0x14,0x27,0x70,0x6B,0x9E,0x94,0xF9,0x51,0x8E,0x9F,
0xB2,0x51,0x69,0x73,0x2F,0x46,0x53,0x5,0xDC,0x36,
0x69,0xA4,0x3,0x86,0x4B,0xC4,0xC6,0xD5,0xE6,0x5F,
0x50,0x37,0xF7,0x5C,0xC6,0x86,0xF9,0xA5,0xCA,0x74,
0x24,0xCC,0xBA,0x7E,0x64,0x7E]

flag=''
for i in range(len(enc)):
tmp=enc[i]^i^key[i]
flag+=chr(tmp)
print(flag)
# DASCTF{lsTzx-c5c21iVA-goojqNS-ynFOPRx-489itUh}

信创安全

鸿蒙逆向,hap解压为一个项目

工具:abc-decompiler

matrix+xor+rc4+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
public Object matrixEncryptBlocks(Object functionObject, Object newTarget, EUtils this, Object arg0, Object arg1) {
r24 = arg1.length;
newobjrange = Uint8Array(arg0.length);
i = 0;
while (true) {
i2 = i;
if ((i2 < arg0.length ? 1 : 0) == 0) {
return newobjrange;
}
slice = arg0.slice(i2, i2 + r24);
ldlexvar = _lexenv_0_0_;
mulMatrixVectorMod256 = ldlexvar.mulMatrixVectorMod256(arg1, Array.from(slice));
for (i3 = 0; (i3 < r24 ? 1 : 0) != 0; i3 = tonumer(i3) + 1) {
newobjrange[i2 + i3] = mulMatrixVectorMod256[i3] & 255;
}
i = i2 + r24;
}
}

public Object mulMatrixVectorMod256(Object functionObject, Object newTarget, EUtils this, Object arg0, Object arg1) {
obj = arg0.length;
newobjrange = Array(obj);
for (i = 0; (i < obj ? 1 : 0) != 0; i = tonumer(i) + 1) {
i2 = 0;
for (i3 = 0; (i3 < obj ? 1 : 0) != 0; i3 = tonumer(i3) + 1) {
i2 += arg0[i][i3] * arg1[i3];
}
newobjrange[i] = i2 & 255;
}
return newobjrange;
}

解密

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
import base64
from Crypto.Cipher import ARC4
from sympy import Matrix
import numpy as np

#base64
custom_table='3GHIJKLMzxy01245PQRSTUFabcdefghijklmnopqrstuv6789+/NOVWXYZABCDEw'
table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
trans_table=str.maketrans(custom_table,table)
enc='37L9UF8uNl1TSgYMLIW/RosGPMxVYXNcUoTTQXihX8ZyaQVgxY9Ywz/0fIwRzI4H'
enc=enc+'='*(4-len(enc)%4) if len(enc)%4 else enc
e=enc.translate(trans_table)
e2=base64.b64decode(e)
# print(e2)

#rc4
k1=b'HarMonyOS_S3cur3_K3y!2025'
cipher = ARC4.new(k1)
e3=cipher.decrypt(e2)
# print(e3.hex())
# 5a3ce7e6671be974c53bc174b8b742cc6e9e62e00547c2fddcf763f889566ed2b8037923d4d3a1ba470813d11c71299a

# xor
k2=[90, 60, 231, 145, 47]
e4=bytes.fromhex('5a3ce7e6671be974c53bc174b8b742cc6e9e62e00547c2fddcf763f889566ed2b8037923d4d3a1ba470813d11c71299a')
# print(e4)
e5=[]
for i in range(len(e4)):
e5.append(e4[i]^k2[i%5])
# print(e5)

#matrix
a=[[1, 2, 3],
[0, 1, 4],
[0, 0, 1]]
n=len(a)
e5_array=np.frombuffer(bytes(e5),dtype=np.uint8)
inv_a=Matrix(a).inv_mod(256)
flag=bytearray()
for block in e5_array.reshape(-1,n): #一维变二维
plain_vec=(inv_a*Matrix(block))%256
flag.extend(int(x) for x in plain_vec)
print(flag.decode())

# , DASCTF{H4rmOny0S_Mult1_L4y3r_Crypt0_M4st3r!}

浙江省赛决赛2025_Re
https://alenirving.github.io/2025/11/18/浙江省赛决赛2025_Re/
作者
Ma5k
许可协议
CC-BY-NC-SA