vm

Windows下的VM
二血。
拖入IDA,可以直接观察到一个SIMD优化的RC4_init,直接看下面的单字节部分就行了,上面的优化只是对于整16字节进行的快速处理,而下面就是对余16字节后的进行的处理。
2024-12-06T06:14:38.png

然后sub_140001970里面是RC4的优化展开。
2024-12-06T06:14:48.png
最后程序直接输出了这个。我们发现rc4的key传入了这个函数,并且这个函数会校验这个key是否正确
2024-12-06T06:15:00.png
该函数就是一个标准的栈VM了。
2024-12-06T06:15:11.png
于是我们直接开始调试,找到下面几个关键点:
2024-12-06T06:15:21.png
2024-12-06T06:15:25.png
2024-12-06T06:15:30.png
VM_sub, VM_div 没调用,所以就不管了,调用的是VM_Add
然后去Xdbg中打断点输出
输入一组测试数据

abcdefghijklmnopqrstuvwxyzABCDEF

我们可以trace出以下结果

INT3 breakpoint at secret_box.00007FF77B1820E3!
1 = (61 >> 0) & 1
2 = 1 * 2
0 = (61 >> 1) & 1
0 = 0 * 3
0 = (61 >> 2) & 1
0 = 0 * 43
0 = (61 >> 3) & 1
0 = 0 * 25
0 = (61 >> 4) & 1
0 = 0 * 29
1 = (61 >> 5) & 1
B = 1 * B
1 = (61 >> 6) & 1
D = 1 * D
0 = (61 >> 7) & 1
0 = 0 * 59
D = D + 0
18 = B + D
18 = 0 + 18
18 = 0 + 18
18 = 0 + 18
18 = 0 + 18
1A = 2 + 18
5C = 1A ^ 46
0 = (62 >> 0) & 1
0 = 0 * 2
1 = (62 >> 1) & 1
3 = 1 * 3
0 = (62 >> 2) & 1
0 = 0 * 43
0 = (62 >> 3) & 1
0 = 0 * 5
0 = (62 >> 4) & 1
0 = 0 * 7
1 = (62 >> 5) & 1
2F = 1 * 2F
1 = (62 >> 6) & 1
3D = 1 * 3D
0 = (62 >> 7) & 1
0 = 0 * 1D
3D = 3D + 0
6C = 2F + 3D
6C = 0 + 6C
6C = 0 + 6C
6C = 0 + 6C
6F = 3 + 6C
6F = 0 + 6F
57 = 6F ^ 38
1 = (63 >> 0) & 1
2 = 1 * 2
1 = (63 >> 1) & 1
43 = 1 * 43
0 = (63 >> 2) & 1
0 = 0 * 25
0 = (63 >> 3) & 1
0 = 0 * 7
0 = (63 >> 4) & 1
0 = 0 * 2B
1 = (63 >> 5) & 1
B = 1 * B
1 = (63 >> 6) & 1
D = 1 * D
0 = (63 >> 7) & 1
0 = 0 * 1F
D = D + 0
18 = B + D
18 = 0 + 18
18 = 0 + 18
18 = 0 + 18
5B = 43 + 18
5D = 2 + 5B
1B = 5D ^ 46
0 = (64 >> 0) & 1
0 = 0 * 61
0 = (64 >> 1) & 1
0 = 0 * 3
1 = (64 >> 2) & 1
29 = 1 * 29
0 = (64 >> 3) & 1
0 = 0 * 49
0 = (64 >> 4) & 1
0 = 0 * B
1 = (64 >> 5) & 1
D = 1 * D
1 = (64 >> 6) & 1
35 = 1 * 35
0 = (64 >> 7) & 1
0 = 0 * 1D
35 = 35 + 0
42 = D + 35
42 = 0 + 42
42 = 0 + 42
6B = 29 + 42
6B = 0 + 6B
6B = 0 + 6B
26 = 6B ^ 4D
1 = (65 >> 0) & 1
61 = 1 * 61
0 = (65 >> 1) & 1
0 = 0 * 43
1 = (65 >> 2) & 1
3 = 1 * 3
0 = (65 >> 3) & 1
0 = 0 * B
0 = (65 >> 4) & 1
0 = 0 * 2B
1 = (65 >> 5) & 1
D = 1 * D
1 = (65 >> 6) & 1
2F = 1 * 2F
0 = (65 >> 7) & 1
0 = 0 * 53
2F = 2F + 0
3C = D + 2F
3C = 0 + 3C
3C = 0 + 3C
3F = 3 + 3C
3F = 0 + 3F
A0 = 61 + 3F
EA = A0 ^ 4A
0 = (66 >> 0) & 1
0 = 0 * 43
1 = (66 >> 1) & 1
5 = 1 * 5
1 = (66 >> 2) & 1
25 = 1 * 25
0 = (66 >> 3) & 1
0 = 0 * 47
0 = (66 >> 4) & 1
0 = 0 * 7
1 = (66 >> 5) & 1
B = 1 * B
1 = (66 >> 6) & 1
59 = 1 * 59
0 = (66 >> 7) & 1
0 = 0 * 1D
59 = 59 + 0
64 = B + 59
64 = 0 + 64
64 = 0 + 64
89 = 25 + 64
8E = 5 + 89
8E = 0 + 8E
D4 = 8E ^ 5A
1 = (67 >> 0) & 1
2 = 1 * 2
1 = (67 >> 1) & 1
3 = 1 * 3
1 = (67 >> 2) & 1
5 = 1 * 5
0 = (67 >> 3) & 1
0 = 0 * B
0 = (67 >> 4) & 1
0 = 0 * D
1 = (67 >> 5) & 1
53 = 1 * 53
1 = (67 >> 6) & 1
35 = 1 * 35
0 = (67 >> 7) & 1
0 = 0 * 3D
35 = 35 + 0
88 = 53 + 35
88 = 0 + 88
88 = 0 + 88
8D = 5 + 88
90 = 3 + 8D
92 = 2 + 90
C5 = 92 ^ 57
0 = (68 >> 0) & 1
0 = 0 * 2
0 = (68 >> 1) & 1
0 = 0 * 3
0 = (68 >> 2) & 1
0 = 0 * 7
1 = (68 >> 3) & 1
47 = 1 * 47
0 = (68 >> 4) & 1
0 = 0 * 2B
1 = (68 >> 5) & 1
53 = 1 * 53
1 = (68 >> 6) & 1
1D = 1 * 1D
0 = (68 >> 7) & 1
0 = 0 * 1F
1D = 1D + 0
70 = 53 + 1D
70 = 0 + 70
B7 = 47 + 70
B7 = 0 + B7
B7 = 0 + B7
B7 = 0 + B7
E5 = B7 ^ 52
1 = (69 >> 0) & 1
7 = 1 * 7
0 = (69 >> 1) & 1
0 = 0 * 49
0 = (69 >> 2) & 1
0 = 0 * B
1 = (69 >> 3) & 1
D = 1 * D
0 = (69 >> 4) & 1
0 = 0 * 35
1 = (69 >> 5) & 1
59 = 1 * 59
1 = (69 >> 6) & 1
1D = 1 * 1D
0 = (69 >> 7) & 1
0 = 0 * 1F
1D = 1D + 0
76 = 59 + 1D
76 = 0 + 76
83 = D + 76
83 = 0 + 83
83 = 0 + 83
8A = 7 + 83
B6 = 8A ^ 3C
0 = (6A >> 0) & 1
0 = 0 * 2
1 = (6A >> 1) & 1
3 = 1 * 3
0 = (6A >> 2) & 1
0 = 0 * 5
1 = (6A >> 3) & 1
25 = 1 * 25
0 = (6A >> 4) & 1
0 = 0 * 7
1 = (6A >> 5) & 1
2B = 1 * 2B
1 = (6A >> 6) & 1
D = 1 * D
0 = (6A >> 7) & 1
0 = 0 * 3D
D = D + 0
38 = 2B + D
38 = 0 + 38
5D = 25 + 38
5D = 0 + 5D
60 = 3 + 5D
60 = 0 + 60
23 = 60 ^ 43
1 = (6B >> 0) & 1
2 = 1 * 2
1 = (6B >> 1) & 1
5 = 1 * 5
0 = (6B >> 2) & 1
0 = 0 * 7
1 = (6B >> 3) & 1
2B = 1 * 2B
0 = (6B >> 4) & 1
0 = 0 * B
1 = (6B >> 5) & 1
D = 1 * D
1 = (6B >> 6) & 1
35 = 1 * 35
0 = (6B >> 7) & 1
0 = 0 * 59
35 = 35 + 0
42 = D + 35
42 = 0 + 42
6D = 2B + 42
6D = 0 + 6D
72 = 5 + 6D
74 = 2 + 72
22 = 74 ^ 56
0 = (6C >> 0) & 1
0 = 0 * 5
0 = (6C >> 1) & 1
0 = 0 * 7
1 = (6C >> 2) & 1
49 = 1 * 49
1 = (6C >> 3) & 1
2B = 1 * 2B
0 = (6C >> 4) & 1
0 = 0 * B
1 = (6C >> 5) & 1
D = 1 * D
1 = (6C >> 6) & 1
3B = 1 * 3B
0 = (6C >> 7) & 1
0 = 0 * 1F
3B = 3B + 0
48 = D + 3B
48 = 0 + 48
73 = 2B + 48
BC = 49 + 73
BC = 0 + BC
BC = 0 + BC
E3 = BC ^ 5F
1 = (6D >> 0) & 1
3 = 1 * 3
0 = (6D >> 1) & 1
0 = 0 * 5
1 = (6D >> 2) & 1
49 = 1 * 49
1 = (6D >> 3) & 1
29 = 1 * 29
0 = (6D >> 4) & 1
0 = 0 * 2B
1 = (6D >> 5) & 1
D = 1 * D
1 = (6D >> 6) & 1
53 = 1 * 53
0 = (6D >> 7) & 1
0 = 0 * 59
53 = 53 + 0
60 = D + 53
60 = 0 + 60
89 = 29 + 60
D2 = 49 + 89
D2 = 0 + D2
D5 = 3 + D2
95 = D5 ^ 40
0 = (6E >> 0) & 1
0 = 0 * 2
1 = (6E >> 1) & 1
7 = 1 * 7
1 = (6E >> 2) & 1
47 = 1 * 47
1 = (6E >> 3) & 1
B = 1 * B
0 = (6E >> 4) & 1
0 = 0 * 2B
1 = (6E >> 5) & 1
D = 1 * D
1 = (6E >> 6) & 1
1D = 1 * 1D
0 = (6E >> 7) & 1
0 = 0 * 3D
1D = 1D + 0
2A = D + 1D
2A = 0 + 2A
35 = B + 2A
7C = 47 + 35
83 = 7 + 7C
83 = 0 + 83
DD = 83 ^ 5E
1 = (6F >> 0) & 1
2 = 1 * 2
1 = (6F >> 1) & 1
5 = 1 * 5
1 = (6F >> 2) & 1
7 = 1 * 7
1 = (6F >> 3) & 1
B = 1 * B
0 = (6F >> 4) & 1
0 = 0 * D
1 = (6F >> 5) & 1
4F = 1 * 4F
1 = (6F >> 6) & 1
2F = 1 * 2F
0 = (6F >> 7) & 1
0 = 0 * 53
2F = 2F + 0
7E = 4F + 2F
7E = 0 + 7E
89 = B + 7E
90 = 7 + 89
95 = 5 + 90
97 = 2 + 95
C2 = 97 ^ 55
0 = (70 >> 0) & 1
0 = 0 * 3
0 = (70 >> 1) & 1
0 = 0 * 43
0 = (70 >> 2) & 1
0 = 0 * 25
0 = (70 >> 3) & 1
0 = 0 * 5
1 = (70 >> 4) & 1
49 = 1 * 49
1 = (70 >> 5) & 1
B = 1 * B
1 = (70 >> 6) & 1
D = 1 * D
0 = (70 >> 7) & 1
0 = 0 * 3D
D = D + 0
18 = B + D
61 = 49 + 18
61 = 0 + 61
61 = 0 + 61
61 = 0 + 61
61 = 0 + 61
23 = 61 ^ 42
1 = (71 >> 0) & 1
2 = 1 * 2
0 = (71 >> 1) & 1
0 = 0 * 43
0 = (71 >> 2) & 1
0 = 0 * 5
0 = (71 >> 3) & 1
0 = 0 * 7
1 = (71 >> 4) & 1
47 = 1 * 47
1 = (71 >> 5) & 1
B = 1 * B
1 = (71 >> 6) & 1
D = 1 * D
0 = (71 >> 7) & 1
0 = 0 * 3D
D = D + 0
18 = B + D
5F = 47 + 18
5F = 0 + 5F
5F = 0 + 5F
5F = 0 + 5F
61 = 2 + 5F
40 = 61 ^ 21
0 = (72 >> 0) & 1
0 = 0 * 43
1 = (72 >> 1) & 1
3 = 1 * 3
0 = (72 >> 2) & 1
0 = 0 * 5
0 = (72 >> 3) & 1
0 = 0 * 25
1 = (72 >> 4) & 1
2B = 1 * 2B
1 = (72 >> 5) & 1
B = 1 * B
1 = (72 >> 6) & 1
D = 1 * D
0 = (72 >> 7) & 1
0 = 0 * 3D
D = D + 0
18 = B + D
43 = 2B + 18
43 = 0 + 43
43 = 0 + 43
46 = 3 + 43
46 = 0 + 46
3 = 46 ^ 45
1 = (73 >> 0) & 1
2 = 1 * 2
1 = (73 >> 1) & 1
3 = 1 * 3
0 = (73 >> 2) & 1
0 = 0 * 25
0 = (73 >> 3) & 1
0 = 0 * 7
1 = (73 >> 4) & 1
47 = 1 * 47
1 = (73 >> 5) & 1
29 = 1 * 29
1 = (73 >> 6) & 1
B = 1 * B
0 = (73 >> 7) & 1
0 = 0 * 1D
B = B + 0
34 = 29 + B
7B = 47 + 34
7B = 0 + 7B
7B = 0 + 7B
7E = 3 + 7B
80 = 2 + 7E
C0 = 80 ^ 40
0 = (74 >> 0) & 1
0 = 0 * 3
0 = (74 >> 1) & 1
0 = 0 * 5
1 = (74 >> 2) & 1
29 = 1 * 29
0 = (74 >> 3) & 1
0 = 0 * B
1 = (74 >> 4) & 1
2B = 1 * 2B
1 = (74 >> 5) & 1
2F = 1 * 2F
1 = (74 >> 6) & 1
35 = 1 * 35
0 = (74 >> 7) & 1
0 = 0 * 1D
35 = 35 + 0
64 = 2F + 35
8F = 2B + 64
8F = 0 + 8F
B8 = 29 + 8F
B8 = 0 + B8
B8 = 0 + B8
DA = B8 ^ 62
1 = (75 >> 0) & 1
2 = 1 * 2
0 = (75 >> 1) & 1
0 = 0 * 3
1 = (75 >> 2) & 1
7 = 1 * 7
0 = (75 >> 3) & 1
0 = 0 * 47
1 = (75 >> 4) & 1
2B = 1 * 2B
1 = (75 >> 5) & 1
D = 1 * D
1 = (75 >> 6) & 1
2F = 1 * 2F
0 = (75 >> 7) & 1
0 = 0 * 4F
2F = 2F + 0
3C = D + 2F
67 = 2B + 3C
67 = 0 + 67
6E = 7 + 67
6E = 0 + 6E
70 = 2 + 6E
33 = 70 ^ 43
0 = (76 >> 0) & 1
0 = 0 * 2
1 = (76 >> 1) & 1
3 = 1 * 3
1 = (76 >> 2) & 1
5 = 1 * 5
0 = (76 >> 3) & 1
0 = 0 * 25
1 = (76 >> 4) & 1
B = 1 * B
1 = (76 >> 5) & 1
2B = 1 * 2B
1 = (76 >> 6) & 1
D = 1 * D
0 = (76 >> 7) & 1
0 = 0 * 4F
D = D + 0
38 = 2B + D
43 = B + 38
43 = 0 + 43
48 = 5 + 43
4B = 3 + 48
4B = 0 + 4B
C = 4B ^ 47
1 = (77 >> 0) & 1
61 = 1 * 61
1 = (77 >> 1) & 1
43 = 1 * 43
1 = (77 >> 2) & 1
5 = 1 * 5
0 = (77 >> 3) & 1
0 = 0 * 25
1 = (77 >> 4) & 1
7 = 1 * 7
1 = (77 >> 5) & 1
29 = 1 * 29
1 = (77 >> 6) & 1
B = 1 * B
0 = (77 >> 7) & 1
0 = 0 * 3D
B = B + 0
34 = 29 + B
3B = 7 + 34
3B = 0 + 3B
40 = 5 + 3B
83 = 43 + 40
E4 = 61 + 83
BA = E4 ^ 5E
0 = (78 >> 0) & 1
0 = 0 * 3
0 = (78 >> 1) & 1
0 = 0 * 47
0 = (78 >> 2) & 1
0 = 0 * 7
1 = (78 >> 3) & 1
2B = 1 * 2B
1 = (78 >> 4) & 1
B = 1 * B
1 = (78 >> 5) & 1
4F = 1 * 4F
1 = (78 >> 6) & 1
35 = 1 * 35
0 = (78 >> 7) & 1
0 = 0 * 3D
35 = 35 + 0
84 = 4F + 35
8F = B + 84
BA = 2B + 8F
BA = 0 + BA
BA = 0 + BA
BA = 0 + BA
E7 = BA ^ 5D
1 = (79 >> 0) & 1
2 = 1 * 2
0 = (79 >> 1) & 1
0 = 0 * 3
0 = (79 >> 2) & 1
0 = 0 * 47
1 = (79 >> 3) & 1
49 = 1 * 49
1 = (79 >> 4) & 1
B = 1 * B
1 = (79 >> 5) & 1
D = 1 * D
1 = (79 >> 6) & 1
3D = 1 * 3D
0 = (79 >> 7) & 1
0 = 0 * 1F
3D = 3D + 0
4A = D + 3D
55 = B + 4A
9E = 49 + 55
9E = 0 + 9E
9E = 0 + 9E
A0 = 2 + 9E
FA = A0 ^ 5A
0 = (7A >> 0) & 1
0 = 0 * 61
1 = (7A >> 1) & 1
2 = 1 * 2
0 = (7A >> 2) & 1
0 = 0 * 3
1 = (7A >> 3) & 1
43 = 1 * 43
1 = (7A >> 4) & 1
5 = 1 * 5
1 = (7A >> 5) & 1
B = 1 * B
1 = (7A >> 6) & 1
D = 1 * D
0 = (7A >> 7) & 1
0 = 0 * 53
D = D + 0
18 = B + D
1D = 5 + 18
60 = 43 + 1D
60 = 0 + 60
62 = 2 + 60
62 = 0 + 62
42 = 62 ^ 20
1 = (41 >> 0) & 1
2 = 1 * 2
0 = (41 >> 1) & 1
0 = 0 * 3
0 = (41 >> 2) & 1
0 = 0 * 5
0 = (41 >> 3) & 1
0 = 0 * 25
0 = (41 >> 4) & 1
0 = 0 * 7
0 = (41 >> 5) & 1
0 = 0 * 29
1 = (41 >> 6) & 1
B = 1 * B
0 = (41 >> 7) & 1
0 = 0 * 35
B = B + 0
B = 0 + B
B = 0 + B
B = 0 + B
B = 0 + B
B = 0 + B
D = 2 + B
4C = D ^ 41
0 = (42 >> 0) & 1
0 = 0 * 2
1 = (42 >> 1) & 1
3 = 1 * 3
0 = (42 >> 2) & 1
0 = 0 * 49
0 = (42 >> 3) & 1
0 = 0 * 2B
0 = (42 >> 4) & 1
0 = 0 * B
0 = (42 >> 5) & 1
0 = 0 * D
1 = (42 >> 6) & 1
35 = 1 * 35
0 = (42 >> 7) & 1
0 = 0 * 3D
35 = 35 + 0
35 = 0 + 35
35 = 0 + 35
35 = 0 + 35
35 = 0 + 35
38 = 3 + 35
38 = 0 + 38
6A = 38 ^ 52
1 = (43 >> 0) & 1
2 = 1 * 2
1 = (43 >> 1) & 1
43 = 1 * 43
0 = (43 >> 2) & 1
0 = 0 * 3
0 = (43 >> 3) & 1
0 = 0 * 25
0 = (43 >> 4) & 1
0 = 0 * 7
0 = (43 >> 5) & 1
0 = 0 * B
1 = (43 >> 6) & 1
2F = 1 * 2F
0 = (43 >> 7) & 1
0 = 0 * 3B
2F = 2F + 0
2F = 0 + 2F
2F = 0 + 2F
2F = 0 + 2F
2F = 0 + 2F
72 = 43 + 2F
74 = 2 + 72
30 = 74 ^ 44
0 = (44 >> 0) & 1
0 = 0 * 2
0 = (44 >> 1) & 1
0 = 0 * 25
1 = (44 >> 2) & 1
5 = 1 * 5
0 = (44 >> 3) & 1
0 = 0 * 49
0 = (44 >> 4) & 1
0 = 0 * D
0 = (44 >> 5) & 1
0 = 0 * 2F
1 = (44 >> 6) & 1
35 = 1 * 35
0 = (44 >> 7) & 1
0 = 0 * 3B
35 = 35 + 0
35 = 0 + 35
35 = 0 + 35
35 = 0 + 35
3A = 5 + 35
3A = 0 + 3A
3A = 0 + 3A
7B = 3A ^ 41
1 = (45 >> 0) & 1
2 = 1 * 2
0 = (45 >> 1) & 1
0 = 0 * 43
1 = (45 >> 2) & 1
47 = 1 * 47
0 = (45 >> 3) & 1
0 = 0 * 49
0 = (45 >> 4) & 1
0 = 0 * 29
0 = (45 >> 5) & 1
0 = 0 * B
1 = (45 >> 6) & 1
D = 1 * D
0 = (45 >> 7) & 1
0 = 0 * 59
D = D + 0
D = 0 + D
D = 0 + D
D = 0 + D
54 = 47 + D
54 = 0 + 54
56 = 2 + 54
B = 56 ^ 5D
0 = (46 >> 0) & 1
0 = 0 * 2
1 = (46 >> 1) & 1
3 = 1 * 3
1 = (46 >> 2) & 1
43 = 1 * 43
0 = (46 >> 3) & 1
0 = 0 * 25
0 = (46 >> 4) & 1
0 = 0 * 49
0 = (46 >> 5) & 1
0 = 0 * B
1 = (46 >> 6) & 1
2B = 1 * 2B
0 = (46 >> 7) & 1
0 = 0 * 3B
2B = 2B + 0
2B = 0 + 2B
2B = 0 + 2B
2B = 0 + 2B
6E = 43 + 2B
71 = 3 + 6E
71 = 0 + 71
11 = 71 ^ 60
1C = B + 11
97 = 7B + 1C
C7 = 30 + 97
131 = 6A + C7
17D = 4C + 131
1BF = 42 + 17D
2B9 = FA + 1BF
3A0 = E7 + 2B9
45A = BA + 3A0
466 = C + 45A
499 = 33 + 466
573 = DA + 499
633 = C0 + 573
636 = 3 + 633
676 = 40 + 636
699 = 23 + 676
75B = C2 + 699
838 = DD + 75B
8CD = 95 + 838
9B0 = E3 + 8CD
9D2 = 22 + 9B0
9F5 = 23 + 9D2
AAB = B6 + 9F5
B90 = E5 + AAB
C55 = C5 + B90
D29 = D4 + C55
E13 = EA + D29
E39 = 26 + E13
E54 = 1B + E39
EAB = 57 + E54
F07 = 5C + EAB
INT3 breakpoint at secret_box.00007FF77B182055!

显然是对于每一个输入的东西,由于是8位的,按照位拆开,每个位分别是0或者1,然后乘以一个const,得到的结果是本位的加密后结果,然后这个结果会异或一个东西得到enc[i],然后程序将计算他们的和,从而得到最后的结果

0 = S = \sum{(bits[i]_0 * c_0 + bits[i]_1 * c_1 + bits[i]_2 * c_2 + bits[i]_3 * c_3 + bits[i]_4 * c_4 + bits[i]_5 * c_5 + bits[i]_6 * c_6 + bits[i]_7 * c_7) \oplus CONST[i] }

由于程序约束S == 0,则
Exp:

enc = [0x46, 0x38, 0x46, 0x4D, 0x4A, 0x5A, 0x57, 0x52, 0x3C, 0x43, 0x56, 0x5F, 0x40, 0x5E, 0x55, 0x42, 0x21, 0x45, 0x40, 0x62, 0x43, 0x47, 0x5E, 0x5D, 0x5A, 0x20, 0x41, 0x52, 0x44, 0x41, 0x5D, 0x60]
muls = []
muls.append([0x2,0x3,0x43,0x25,0x29,0xB,0xD,0x59]   )
muls.append([0x2,0x3,0x43,0x5,0x7,0x2F,0x3D,0x1D]   )
muls.append([0x2,0x43,0x25,0x7,0x2B,0xB,0xD,0x1F]   )
muls.append([0x61,0x3,0x29,0x49,0xB,0xD,0x35,0x1D]  )
muls.append([0x61,0x43,0x3,0xB,0x2B,0xD,0x2F,0x53]  )
muls.append([0x43,0x5,0x25,0x47,0x7,0xB,0x59,0x1D]  )
muls.append([0x2,0x3,0x5,0xB,0xD,0x53,0x35,0x3D]    )
muls.append([0x2,0x3,0x7,0x47,0x2B,0x53,0x1D,0x1F]  )
muls.append([0x7,0x49,0xB,0xD,0x35,0x59,0x1D,0x1F]  )
muls.append([0x2,0x3,0x5,0x25,0x7,0x2B,0xD,0x3D]    )
muls.append([0x2,0x5,0x7,0x2B,0xB,0xD,0x35,0x59]    )
muls.append([0x5,0x7,0x49,0x2B,0xB,0xD,0x3B,0x1F]   )
muls.append([0x3,0x5,0x49,0x29,0x2B,0xD,0x53,0x59]  )
muls.append([0x2,0x7,0x47,0xB,0x2B,0xD,0x1D,0x3D]   )
muls.append([0x2,0x5,0x7,0xB,0xD,0x4F,0x2F,0x53]    )
muls.append([0x3,0x43,0x25,0x5,0x49,0xB,0xD,0x3D]   )
muls.append([0x2,0x43,0x5,0x7,0x47,0xB,0xD,0x3D]    )
muls.append([0x43,0x3,0x5,0x25,0x2B,0xB,0xD,0x3D]   )
muls.append([0x2,0x3,0x25,0x7,0x47,0x29,0xB,0x1D]   )
muls.append([0x3,0x5,0x29,0xB,0x2B,0x2F,0x35,0x1D]  )
muls.append([0x2,0x3,0x7,0x47,0x2B,0xD,0x2F,0x4F]   )
muls.append([0x2,0x3,0x5,0x25,0xB,0x2B,0xD,0x4F]    )
muls.append([0x61,0x43,0x5,0x25,0x7,0x29,0xB,0x3D]  )
muls.append([0x3,0x47,0x7,0x2B,0xB,0x4F,0x35,0x3D]  )
muls.append([0x2,0x3,0x47,0x49,0xB,0xD,0x3D,0x1F]   )
muls.append([0x61,0x2,0x3,0x43,0x5,0xB,0xD,0x53]    )
muls.append([0x2,0x3,0x5,0x25,0x7,0x29,0xB,0x35]    )
muls.append([0x2,0x3,0x49,0x2B,0xB,0xD,0x35,0x3D]   )
muls.append([0x2,0x43,0x3,0x25,0x7,0xB,0x2F,0x3B]   )
muls.append([0x2,0x25,0x5,0x49,0xD,0x2F,0x35,0x3B]  )
muls.append([0x2,0x43,0x47,0x49,0x29,0xB,0xD,0x59]  )
muls.append([0x2,0x3,0x43,0x25,0x49,0xB,0x2B,0x3B]  )
ans = bytearray()
for rin range(32):
    # BruteForce Ascii
    for i in range(0x20, 0x7f):
        a0 = ((i >> 0) & 1) * muls[r][0]
        a1 = ((i >> 1) & 1) * muls[r][8]
        a2 = ((i >> 2) & 1) * muls[r][9]
        a3 = ((i >> 3) & 1) * muls[r][10]
        a4 = ((i >> 4) & 1) * muls[r][11]
        a5 = ((i >> 5) & 1) * muls[r][12]
        a6 = ((i >> 6) & 1) * muls[r][13]
        a7 = ((i >> 7) & 1) * muls[r][14] 
        s1 = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7
        if s1 == enc[r]:
            ans.append(i)
            break
print(ans)
# bytearray(b's1mpl3_VM_us3s_link3d_l1st_st4ck')

然后把这个输入程序就能解出真flag了

C:\Users\Administrator\Desktop\S1mpLeVM_6d429db3ceeba8f95131c477020ee899>secret_box.exe quest
Enter ur passcode: s1mpl3_VM_us3s_link3d_l1st_st4ck115
Thank for providing passcode, my ultimate secret box is checking...
Cracked...
flag{s1mpl3_VM_us1ng_st4ck_th4t_1mpl3m3nt_by_l1nk3d_l1st_^3^_!!}

unsafeFile

小Y玩游戏很菜,于是他找了个神秘人要了一个修改器文件,在开启功能后,发现他的一个重要文件居然被加密了,你能想办法帮他恢复吗
请不要在物理机上运行题目中的任何文件,主办方对由此造成的任何损失不承担任何责任,如有需要请在虚拟机内进行运行和调试,解压密码2024qwbfinal

Cheat Engine 脚本,用于注入PlantsVsZombies.exe实现修改
ce的库函数 decodefuction()解码成函数
使用Github上的这个工具来提取encodeFunction的内容。
2024-12-06T06:16:44.png

下面是反编译后的重要内容。

// 远程代码注入
L2_1 = "injectDLL"
L2_1 = _ENV[L2_1]
L3_1 = "C:\\system.dll"
L2_1(L3_1)
L2_1 = "sleep"
L2_1 = _ENV[L2_1]
L3_1 = 5
L2_1(L3_1)
L2_1 = [[
alloc(newmem,256)
label(returnhere)
label(originalcode)
label(exit)
// 远程代码注入
newmem:

originalcode:
xor eax,5A

mov ecx, eax
shr eax, 4
shl ecx, 4
or eax, ecx

mov ecx,[ebp-1C]

exit:
jmp returnhere

"system.dll"+25C6:
jmp newmem
nop
returnhere:

]]
L3_1 = "autoAssemble"
L3_1 = _ENV[L3_1]
L4_1 = L2_1
L3_1(L4_1)
L3_1 = "writeByte"
L3_1 = _ENV[L3_1]
L4_1 = "system.dll+C6DC"
L5_1 = 1
L3_1(L4_1, L5_1)
L3_1 = "activateProtection"
L3_1 = _ENV[L3_1]
L3_1()
L3_1 = "enableDRM"
L3_1 = _ENV[L3_1]
L3_1()

可以看出是导出了一个system.dll
我们直接在ce里面运行这个脚本,由于经过我们分析,只要没有pvz.exe的运行,这个dll就不会被注入,但是无论如何这个dll都会被释放到C盘根目录,这样我们就可以导出system.dll。
分析System.dll,发现AES

2024-12-06T06:17:11.png

AES-CBC
2024-12-06T06:17:20.png
文件遍历
2024-12-06T06:17:29.png
加密,然后弄成.yr结尾的
2024-12-06T06:17:37.png
加密文件
2024-12-06T06:17:44.png
xdbg动态调试,在DeleteFile上下断点防止程序把本机的正常文件删掉。随后断KEY_Expansion,发现是随机的key,然后断这里,就可以拿到iv(v39)。
2024-12-06T06:17:51.png
发现Iv也是随机的,由于题目肯定能解,所以猜测key和iv都写进了文件
分析手动加密的.yr,发现多了32字节,对应key和iv,key被xor了0x5a,iv直接放进去的。

newmem:

originalcode:
xor eax,5A

mov ecx, eax
shr eax, 4
shl ecx, 4
or eax, ecx

mov ecx,[ebp-1C]

exit:
jmp returnhere

"system.dll"+25C6:
jmp newmem
nop
returnhere:

注意到上面,把xor eax, 5a后面加上了ror 4
所以我们有EXP

from regadgets import *
enc = open('secret.pdf.yr', 'rb').read()
iv = enc[-16:]
key = enc[-32:-16]
key = bytes([ror8(i, 4) for i in key])
key = bxor_cycle(key, 0x5a)
print("iv", iv.hex())
print("key", key.hex())
enc = enc[:-32]
dec = AES_cbc_decrypt(enc, key, iv)
open('secret.pdf', 'wb').write(dec)

2024-12-06T06:18:17.png
flag{7he_Che47_En9INe_74BLE_I5_N07_54fE#cf17565a3d91fdbf}

没报名,赛后问朋友要的题,看了看。

loser (Nononono!.exe)

赛中2解
该程序实现了一个类似Base64的算法和一个标准TEA解密算法,用来对输入数据进行编码和加密,并与加密后的结果进行比较,由于程序使用C++,结构体众多,逆向难度中等偏上。

首先是一个类似Base64的编码算法,开始做的时候测试了几个数据,看着很像base64但是其实并不是,算法是以3个字节为一组,每一个字节分别按位与 0x3f 用以获取低6位,然后第2个和第三个and后的数据是要换位置的,第四个字节是前面三个字节的高2位,所以没有加密只是编码,在下面Exp可以看如何解码。

其次是一个TEA解密,拿到key后我们只需要写一个TEA加密,就可以“解密”了。值得注意的是在我们加密前,需要对l和r两个参数进行xor ord('S')即可。
最后是enc了,我们搜索字符串常量right
2024-11-17T12:43:52.png
可以看出 unk_140031520 大概率就是enc了,我们双击进去进行X-Ref,发现它在下面的函数进行了初始化。
2024-11-17T12:44:33.png
copy下来,就可以写exp了。
一个特别小的注意点就是,enc是DWORD big-endian。

Exp:

from regadgets import *
from z3 import *
def decrypt(enc):
    assert len(enc) % 4 == 0
    table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    result = []
    for i in range(0, len(enc), 4):
        a1 = table.index(enc[i + 0])
        a2 = table.index(enc[i + 2])
        a3 = table.index(enc[i + 1])
        a4 = table.index(enc[i + 3])
        result.append(a1 | ((a4 & 0b110000) << 2))
        result.append(a2 | ((a4 & 0b001100) << 4))
        result.append(a3 | ((a4 & 0b000011) << 6))
    return bytes(result)

v4 = [0] * 48
v4[0] = 165
v4[1] = 100
v4[2] = 159
v4[3] = 4
v4[4] = 57
v4[5] = 183
v4[6] = 166
v4[7] = 23
v4[8] = 34
v4[9] = 205
v4[10] = 38
v4[11] = 77
v4[12] = 125
v4[13] = 16
v4[14] = 130
v4[15] = 219
v4[16] = 133
v4[17] = 219
v4[18] = 39
v4[19] = 57
v4[20] = 66
v4[21] = 60
v4[22] = 30
v4[23] = 165
v4[24] = 34
v4[25] = 205
v4[26] = 38
v4[27] = 77
v4[28] = 125
v4[29] = 16
v4[30] = 130
v4[31] = 219
v4[32] = 214
v4[33] = 55
v4[34] = 104
v4[35] = 128
v4[36] = 177
v4[37] = 249
v4[38] = 21
v4[39] = 25
v4[40] = 68
v4[41] = 24
v4[42] = 66
v4[43] = 36
v4[44] = 143
v4[45] = 120
v4[46] = 162
v4[47] = 44
print(len(v4))
v4 = byte2dword(v4, endian='big')
v4 = [i ^ ord('S') for i in v4]

dec = tea_encrypt(v4, key=[ord('L'), ord('Z'), ord('S'), ord('D')])
print(decrypt(dec.decode()))
# 48
# b'LZSDS{how_how_how_how_how_ow_ow_ow!}'

minire

有个elf的upx,随便找了个脱壳教程
https://blog.csdn.net/m0_49936845/article/details/119976496

main函数
2024-11-09T14:18:27.png

下面的else是假的,你需要手动传第一个参数是root才会进第一个条件。(顺便提一下,fake的flag是fksdde7039,MD5爆破出的)

然后去real里面,是一个真正让你输入的地方,不过只是输出了input:,真正的逻辑在下面那个函数。
但是核心函数基本无法直接反编译,我们直接看汇编吧。
2024-11-09T14:19:56.png

经典的VM(Handler + Dispatcher)
2024-11-09T14:20:26.png
我们可以找到一个getchar sub_402907然后就可以不断进行硬件断点跟数据了

注意这一块
2024-11-09T14:21:30.png

稍微分析一下
2024-11-09T14:22:16.png
2024-11-09T14:22:41.png
2024-11-09T14:22:59.png

然后我们下断点
2024-11-09T14:23:19.png
进行条件断点,打印值
2024-11-09T14:23:25.png

这样我们就trace了vm

x[0]^=4
x[0]+=12
x[0]^=11
x[0]^=12
x[0]-=2
x[0]-=1
x[0]^=6
x[1]+=10
x[1]^=12
x[1]+=5
x[2]+=4
x[2]+=14
x[3]-=10
x[3]-=3
x[3]+=13
x[3]+=7
x[3]-=9
x[3]^=14
x[4]-=7
x[4]-=15
x[5]^=14
x[6]^=2
x[6]+=0
x[6]^=2
x[6]+=9
x[6]+=3
x[6]-=2
x[6]+=13
x[6]^=1
x[7]+=8
x[7]+=12
x[7]^=15
x[7]+=5
x[7]^=3
x[7]+=8
x[8]+=8
x[8]+=2
x[8]^=8
x[8]-=12
x[8]+=11
x[8]-=3
x[8]^=9
x[8]-=2
x[8]+=8
x[9]-=0
x[9]-=2
x[10]+=11
x[11]-=2
x[11]^=7
x[11]-=1
x[11]-=5
x[12]+=1
x[12]-=13
x[12]+=12
x[13]-=2
x[13]-=14
x[13]-=9
x[13]^=14
x[13]+=1
x[13]+=10
x[13]-=7
x[13]-=1
x[13]+=9
x[14]-=0
x[14]-=11
x[14]^=4
x[14]+=9
x[15]^=14
x[15]+=5
x[15]-=12
x[15]-=4
x[15]-=4
x[15]+=15
x[15]+=14
x[15]-=4
x[15]^=5
x[15]-=12
x[16]^=11
x[16]+=13
x[16]-=11
x[16]^=4
x[16]+=10
x[16]-=8
x[17]+=10
x[17]+=15
x[17]+=2
x[17]-=6
x[17]-=9
x[17]-=9
x[17]+=3
x[17]+=5
x[17]-=15
x[17]+=2
x[18]-=14
x[18]-=13
x[19]^=7
x[19]-=15
x[19]-=1
x[19]^=3
x[19]-=3
x[19]+=11
x[19]+=10
x[19]+=10
x[20]+=8
x[20]-=6
x[20]-=7
x[20]^=4
x[20]-=1
x[20]^=3
x[21]+=5
x[21]+=2
x[21]+=10
x[21]^=0
x[22]-=7
x[22]+=0
x[22]+=8
x[22]+=1
x[22]+=1
x[22]^=10
x[22]-=14
x[22]^=15
x[22]-=7
x[22]^=8
x[23]^=4
x[23]-=9
x[23]+=15
x[24]+=12
x[24]^=2
x[24]^=4
x[24]-=7
x[24]+=1
x[25]+=0
x[25]+=9
x[25]^=2
x[25]+=14
x[25]^=11
x[25]^=1
x[25]+=2
x[25]+=9
x[25]-=9
x[26]+=6
x[27]^=10
x[27]-=4
x[27]-=13
x[27]^=8
x[27]-=14
x[27]+=14
x[27]^=14
x[28]+=1
x[28]^=4
x[28]-=9
x[28]+=9
x[28]-=5
x[28]+=13
x[28]+=1
x[28]^=10
x[29]^=9
x[30]+=14
x[30]+=12
x[30]^=0
x[30]-=0
x[30]-=15
x[30]^=11
x[30]-=11
x[30]+=8
x[31]+=11
x[31]+=6
x[31]+=1
x[31]^=12
x[31]-=6
x[31]-=14
x[32]-=11
x[32]^=13
x[32]+=5
x[32]^=2
x[32]-=2
x[33]+=13
x[33]^=6
x[33]+=15
x[33]^=0
x[33]-=3
x[33]-=12
x[33]-=15
x[33]^=11
x[34]+=9
x[34]+=10
x[34]+=10
x[34]^=10
x[35]-=13
x[36]^=7
x[36]-=0
x[37]-=11
x[37]+=14
x[37]-=8
x[37]+=4
x[37]+=3
x[37]+=13
x[37]^=3
x[37]^=10

在这之后,我们需要寻找enc(标准加密值)
我们在vm_readByte处下断,然后我们就可以看到enc不断浮现在我们眼前。
最后脚本一把梭

from regadgets import *
from z3 import *
from copy import deepcopy
x = [BitVec(f"x{i}", 8) for i in range(38)]
y = deepcopy(x)

x[0]^=4
x[0]+=12
x[0]^=11
x[0]^=12
x[0]-=2
x[0]-=1
x[0]^=6
x[1]+=10
x[1]^=12
x[1]+=5
x[2]+=4
x[2]+=14
x[3]-=10
x[3]-=3
x[3]+=13
x[3]+=7
x[3]-=9
x[3]^=14
x[4]-=7
x[4]-=15
x[5]^=14
x[6]^=2
x[6]+=0
x[6]^=2
x[6]+=9
x[6]+=3
x[6]-=2
x[6]+=13
x[6]^=1
x[7]+=8
x[7]+=12
x[7]^=15
x[7]+=5
x[7]^=3
x[7]+=8
x[8]+=8
x[8]+=2
x[8]^=8
x[8]-=12
x[8]+=11
x[8]-=3
x[8]^=9
x[8]-=2
x[8]+=8
x[9]-=0
x[9]-=2
x[10]+=11
x[11]-=2
x[11]^=7
x[11]-=1
x[11]-=5
x[12]+=1
x[12]-=13
x[12]+=12
x[13]-=2
x[13]-=14
x[13]-=9
x[13]^=14
x[13]+=1
x[13]+=10
x[13]-=7
x[13]-=1
x[13]+=9
x[14]-=0
x[14]-=11
x[14]^=4
x[14]+=9
x[15]^=14
x[15]+=5
x[15]-=12
x[15]-=4
x[15]-=4
x[15]+=15
x[15]+=14
x[15]-=4
x[15]^=5
x[15]-=12
x[16]^=11
x[16]+=13
x[16]-=11
x[16]^=4
x[16]+=10
x[16]-=8
x[17]+=10
x[17]+=15
x[17]+=2
x[17]-=6
x[17]-=9
x[17]-=9
x[17]+=3
x[17]+=5
x[17]-=15
x[17]+=2
x[18]-=14
x[18]-=13
x[19]^=7
x[19]-=15
x[19]-=1
x[19]^=3
x[19]-=3
x[19]+=11
x[19]+=10
x[19]+=10
x[20]+=8
x[20]-=6
x[20]-=7
x[20]^=4
x[20]-=1
x[20]^=3
x[21]+=5
x[21]+=2
x[21]+=10
x[21]^=0
x[22]-=7
x[22]+=0
x[22]+=8
x[22]+=1
x[22]+=1
x[22]^=10
x[22]-=14
x[22]^=15
x[22]-=7
x[22]^=8
x[23]^=4
x[23]-=9
x[23]+=15
x[24]+=12
x[24]^=2
x[24]^=4
x[24]-=7
x[24]+=1
x[25]+=0
x[25]+=9
x[25]^=2
x[25]+=14
x[25]^=11
x[25]^=1
x[25]+=2
x[25]+=9
x[25]-=9
x[26]+=6
x[27]^=10
x[27]-=4
x[27]-=13
x[27]^=8
x[27]-=14
x[27]+=14
x[27]^=14
x[28]+=1
x[28]^=4
x[28]-=9
x[28]+=9
x[28]-=5
x[28]+=13
x[28]+=1
x[28]^=10
x[29]^=9
x[30]+=14
x[30]+=12
x[30]^=0
x[30]-=0
x[30]-=15
x[30]^=11
x[30]-=11
x[30]+=8
x[31]+=11
x[31]+=6
x[31]+=1
x[31]^=12
x[31]-=6
x[31]-=14
x[32]-=11
x[32]^=13
x[32]+=5
x[32]^=2
x[32]-=2
x[33]+=13
x[33]^=6
x[33]+=15
x[33]^=0
x[33]-=3
x[33]-=12
x[33]-=15
x[33]^=11
x[34]+=9
x[34]+=10
x[34]+=10
x[34]^=10
x[35]-=13
x[36]^=7
x[36]-=0
x[37]-=11
x[37]+=14
x[37]-=8
x[37]+=4
x[37]+=3
x[37]+=13
x[37]^=3
x[37]^=10

s = Solver()
enc = [0x60, 0x7F, 0x73, 0x6B, 0x65, 0x4F, 0x80, 0x5D, 0x64, 0x50, 0x64, 0x2C, 0x37, 0x33, 0x5C, 0x74, 0x45, 0x65, 0x55, 0x60, 0x4A, 0x84, 0x6E, 0x50, 0x7F, 0x58, 0x5F, 0x27, 0x7F, 0x5A, 0x8C, 0x6B, 0x62, 0x60, 0x59, 0x59, 0x45, 0x85]

for i in range(len(x)):
    s.add(enc[i] == x[i])
for m in z3_get_models(s):
    print(m)
    for i in y:
        print(chr(m[i].as_long()), end='')
    print('')
# flag{AjJIRY77BbuNgpPSswNwCY8gSyawo6fB}

joyVBS

纯送分题
https://www.onlinegdb.com/online_vb_compiler
print出来代码

assembly 'a, Version=0.0, Culture=neutral, PublicKeyToken=null' saved successfully to '/home/a.out'.
Compilation successful
Compilation took 00:00:00.7942080
MsgBox "VBScript, often abbreviated as VBS, is an event-driven programming language developed by Microsoft, primarily used for scripting in the Windows environment."
MsgBox "It is based on the Visual Basic programming language and is designed to be simple and easy to use, especially for those familiar with the BASIC programming language."
MsgBox "And for me, it is the first programming language that I've leart"
MsgBox "Hackers! Have fun with this VBS challenge!"
flag = InputBox("Enter the FLAG:", "Hack for fun")
wefbuwiue = "NalvN3hKExBtALBtInPtNHTnKJ80L3JtqxTboRA/MbF3LnT0L2zHL2SlqnPtJLAnFbIlL2SnFT8lpzFzA2JHrRTiNmT9"

qwfe = 9+2+2+1

Function Base64Decode(base64EncodedString)
    Dim xml, elem
    Set xml = CreateObject("MSXML2.DOMDocument")
    Set elem = xml.createElement("tmp")
    elem.dataType = "bin.base64" 
    elem.text = base64EncodedString 
    Dim stream
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1 'Binary
    stream.Open
    stream.Write elem.nodeTypedValue 
    stream.Position = 0
    stream.Type = 2 'Text
    stream.Charset = "utf-8"
    Base64Decode = stream.ReadText
    stream.Close
End Function
Function Caesar(str,offset)
        Dim length,char,i
        Caesar = ""
        length = Len(str)
        For i = 1 To length
                char = Mid(str,i,1)
                If char >= "A" And char <= "Z" Then
                        char = Asc("A") + (Asc(char) - Asc("A") + offset) Mod 26
                        Caesar = Caesar & Chr(char)
                ElseIf char >= "a" And char <= "z" Then
                        char = Asc("a") + (Asc(char) - Asc("a") + offset) Mod 26
                        Caesar = Caesar & Chr(char)
                Else
                        Caesar = Caesar & char
                End If
        Next
End Function

If flag = Base64Decode(Caesar(wefbuwiue, 26-qwfe)) Then
    MsgBox "Congratulations! Correct  FLAG!"
Else
    MsgBox "Wrong flag."
End If

凯撒加密+base64
2024-11-09T14:26:36.png
flag{VB3_1s_S0_e1sY_4_u_r1gh3?btw_1t_iS_a1s0_Us3Fu1_a3D_1nTe3eSt1ng!}

exec

Python Function Hook

import base64
hook_exec = exec
def my_exec(x):
    print('myexec', x)
    hook_exec(x)
exec = my_exec
...

这样就能拿到每次exec的代码,从而得到


a=True
len=len
G=list
g=range
s=next
R=bytes
o=input
Y=print
def l(S):
 i=0
 j=0
 while a:
  i=(i+1)%256
  j=(j+S[i])%256
  S[i],S[j]=S[j],S[i]
  K=S[(S[i]+S[j])%256]
  yield K
def N(key,O):
 I=len(key)
 S=G(g(256))
 j=0
 for i in g(256):
  j=(j+S[i]+key[i%I])%256
  S[i],S[j]=S[j],S[i]
 z=l(S)
 n=[]
 for k in O:
  n.append(s(z)+2)
 return bytes(n).hex()
def E(s,parts_num):
 Q=len(s.decode())
 S=Q//parts_num
 u=Q%parts_num
 W=[]
 j=0
 for i in g(parts_num):
  T=j+S
  if u>0:
   T+=1
   u-=1
  W.append(s[j:T])
  j=T
 return W
if __name__=='__main__':
 L=o('input the flag: >>> ').encode()
 assert len(L)%2==0,'flag length should be even'
 t=b'v3ry_s3cr3t_p@ssw0rd'
 O=E(L,2)
 U=[]
 for i in O:
  U.append(N(t,i))
 print(U)
 if U==['1796972c348bc4fe7a1930b833ff10a80ab281627731ab705dacacfef2e2804d74ab6bc19f60','2ea999141a8cc9e47975269340c177c726a8aa732953a66a6af183bcd9cec8464a']:
  Y('Congratulations! You got the flag!')
 else:
  Y('Wrong flag!')

无法直接运行是因为U的第二个少了个',补上就行,上面代码我稍微改了一下,输出魔改rc4的keystream
然后直接解就行
2024-11-09T14:27:19.png
flag{thEn_I_Ca5_BE_YoUR_Onl7_ExeCUti6n_So_Use_m3_t0_R0n_tH17_Ex3Cuti0n}

RE5

异常处理改了tea的key,每一轮的sum值是由srand(0),每次取随机数相加得到的,然后直接解标准tea即可。

from regadgets import *
from typing import List, Tuple, Union
from ctypes import c_uint32
rng = WindowsRand(0)
def tea_decrypt_plus(
    src: Union[Tuple[int, int], bytes, List[int]], key: Union[List[int], bytes], delta: int = 0x9E3779B9, rounds: int = 32
) -> Union[Tuple[int, int], bytes, List[int]]:
    if type(src) == bytes:
        result = b''
        for i in pack_dword(byte2dword(src)):
            result += dword2byte(tea_decrypt_plus(i, key, delta, rounds))
        return result
    elif type(src) == list:
        result = b''
        for i in pack_dword(src):
            result += dword2byte(tea_decrypt_plus(i, key, delta, rounds))
        return result
    elif type(src) != tuple:
        raise "wrong src type"
    # For bytes key
    _rands = rng.rands(32)
    if type(key) == bytes:
        key = byte2dword(key)
    elif type(key) != list:
        raise "wrong key type"
    l, r = c_uint32(src[0]), c_uint32(src[1])
    _sum = c_uint32(sum(_rands))
    k = [c_uint32(i) for i in key]
    for i in range(rounds):
        r.value -= (
            ((l.value << 4) + k[2].value)
            ^ (l.value + _sum.value)
            ^ ((l.value >> 5) + k[3].value)
        )
        l.value -= (
            ((r.value << 4) + k[0].value)
            ^ (r.value + _sum.value)
            ^ ((r.value >> 5) + k[1].value)
        )
        _sum.value -= _rands[rounds - i - 1]
    return (l.value, r.value)

enc = b"\xF8\x63\x20\xEA\x52\xF2\x66\x8F\xEF\x72\x2A\x90\x74\xDA\x1F\x41\x4D\x0D\x59\x19\x17\x43\xE7\xCA\x3F\x0F\x87\x63\x61\xAE\x53\xD7\x22\x3D\x43\x4D\xDD\xC2\xBC\xB2\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x2F\x00\x00\x00\x01\x00\x00\x00\x66\x6C\x61\x67\x7B\x31\x32\x33\x31\x34\x31\x32\x33\x34\x31\x32\x34\x31\x32\x34\x32\x31\x33\x34\x31\x32\x33\x34\x31\x32\x33\x31\x32\x34\x33\x32\x33\x7D\x00\x00\x39\xDC\xE1\x2E\xF1\xEA\xD6\x40\x9A\x76\x29\x5E\x17\xB6\xF4\x38\xD0\x14\xF5\x8C\xA2\x7E\xEB\xBE\xD5\xFA\xBD\x18\xBF\x05\x97\x49"
# enc = b"\x9A\x76\x29\x5E\x17\xB6\xF4\x38"
# enc = b"\x39\xDC\xE1\x2E\xF1\xEA\xD6\x40"
enc = byte2dword(enc)

# print(tea_decrypt(enc, key=[2,2,3,4]))
print(tea_decrypt_plus(enc, key=[2,2,3,3]))

flag{d555ce75ec293c8ed232d83dffb0ff82} 三血

BigTea

唯一的一血,全程黑箱trace+猜的,控制流混淆太恶心了
Xor Trace,有小数字(0~3的xor),对应xxtea的key[(p & 3) ^ e] ^ z,所以直接认为是xxtea

1287150135 = 858927483 ^ 2139777868
3 = 3 ^ 0
3083858674 = 2100375857 ^ 3405693891
3475065957 = 3435709932 ^ 65636745
3581236543 = 3541242640 ^ 107365935
2686381197 = 76041513 ^ 2761335204
1270372984 = 875704628 ^ 2139777868
2 = 3 ^ 1
.....
2296010693 = 1761772981 ^ 3789083248
3006293146 = 1572571602 ^ 4002147656
0 = 2 ^ 2
1724993655 = 425409339 ^ 2139777868
1982135953 = 1995319112 ^ 13294041
2651112074 = 2511582128 ^ 196571450
237532170 = 436319505 ^ 338280731
3939128127 = 71417463 ^ 4002147656
1 = 2 ^ 3
2522458527 = 141479974 ^ 2654435769
289771357 = 285669852 ^ 4421249
2254779822 = 2263679584 ^ 8927182
378091989 = 2166619358 ^ 2544551179

我们慢慢分析,XXTEA的key,可以从Trace里面盯出来,前面异或算出来的是索引值,所以我们很容易就能拿到四个key,然后我们输入11112222作为待加密数据,由于xxtea的特性,z==y,那么我们很方便的可以看到下面四个值在trace中的样子,然后可以倒推出delta = 0x70D7D4CC

Ly = y.value << 2
Ry = y.value >> 3
Lz = z.value << 4
Rz = z.value >> 5 
keys
0x7f8a6b4c
0x9e3779b9
0xdeafbeef
0xcafec3c3

2024-11-09T14:28:46.png
然后,我们可以使用自己的xxtea加密数据,发现我们的加密数据只在trace的中间,而不是最后,说明加密可能不只一轮或者是xxtea魔改轮数,经过测试是后者,通过fuzz,我们可以知道魔改是 6 + 52//n -> 32 + 52 // n,我们抄出来就行了,最后至于找enc,是通过在最后一轮对于密文下断,然后在程序内存中搜索第一个加密的,进行硬件断点,然后跑,就可以找到cmp。
2024-11-09T14:29:18.png
然后
2024-11-09T14:29:27.png
我们可以观察到下面对cl进行的操作,cl如果不为0则两段密文不一样,我们每次运行打断点手动置0,然后输入很长的input,就可以拿到所有的对比值

cmp 673017408,   1214171175
cmp 3365566770,  3066933611
cmp 1583712898,  4062421290
cmp 1719532837,  3922368852
cmp 2253378100,  2540993788
cmp 1994934834,  1332676358
cmp 4110442914,  22469667
cmp 4185531028,  3633624522
cmp 1279845426,  2241914041
cmp 1481920662,  3542748258
cmp 725179328,   1546291565

最后,使用regadgets库(由于还在开发,小范围测试,所以把库内的代码都复制了出来)进行解密。即可。

from typing import List, Union
from ctypes import c_uint32

def xxtea_std_shift(z, y, sum, k, p, debug = False):
    if debug:
        print("-----------------XXTEA_STD_SHIFT-----------------")
    e = (sum.value >> 2) & 3
    PE = (p & 3) ^ e
    Ly = y.value << 2
    Ry = y.value >> 3
    Lz = z.value << 4
    Rz = z.value >> 5 

    LzRy = Rz ^ Ly
    LyRz = Ry ^ Lz
    SY = sum.value ^ y.value
    K = k[PE].value
    KZ = K ^ z.value
    result = (LzRy + LyRz) ^ (KZ + SY)
    if debug:
        print("sum = ", hex(sum.value))
        print("e   = ", hex(e))
        print("PE  = ", hex(PE))
        print("SY  = ", hex(SY))
        print("z   = ", hex(z.value))
        print("y   = ", hex(y.value))
        print("Ly  = ", hex(Ly))
        print("Ry  = ", hex(Ry))
        print("Lz  = ", hex(Lz))
        print("Rz  = ", hex(Rz))
        print("LzRy= ", hex(LzRy & 0xffffffff))
        print("LyRz= ", hex(LyRz & 0xffffffff))
        print("K   = ", hex(K))
        print("KZ  = ", hex(KZ))
        print("ret = ", hex(result & 0xffffffff))
        print("-----------------XXTEA_STD_SHIFT-----------------")
    return result

def xxtea_decrypt(
    src: Union[List[int], bytes],
    key: List[int],
    delta: int = 0x9E3779B9,
    round_base: int = 6,
    round_addi: int = 52,
    shift_func=xxtea_std_shift,
    debug=False,
) -> Union[List[int], bytes]:
    in_bytes = False
    if type(src) == bytes:
        src = byte2dword(src)
        in_bytes = True
    if type(key) == bytes:
        key = byte2dword(key)
    if in_bytes:
        return dword2byte(xxtea_decrypt(src, key, delta, round_base, round_addi, shift_func, debug))
    src = [c_uint32(i) for i in src]
    key = [c_uint32(i) for i in key]
    sum, e, y = c_uint32(0), c_uint32(0), c_uint32(0)
    delta = c_uint32(delta)
    n = len(src)
    rounds = round_base + round_addi // n
    sum.value = rounds * delta.value
    y = src[0]
    for _ in range(rounds):
        for p in range(n - 1, 0, -1):
            z = src[p - 1]
            shift_result = shift_func(z, y, sum, key, p, debug)
            src[p].value -= shift_result 
            y = src[p]
        p -= 1
        z = src[n - 1]
        shift_result = shift_func(z, y, sum, key, p, debug)
        src[0].value -= shift_result
        y = src[0]
        sum.value -= delta.value
    return [i.value for i in src]


enc = [1214171175,3066933611,4062421290,3922368852,2540993788,1332676358,22469667,3633624522,2241914041,3542748258,1546291565]
enc = xxtea_decrypt(enc, key=[0x7f8a6b4c, 0x9e3779b9, 0xdeafbeef, 0xcafec3c3],delta=0x7f8a6b4c, round_base=32)
print(dword2byte(enc))
# b'flag{9aad3962-8ad5-48d0-83dc-1e60a81439a1}\x00\x00'

Rafflesia

动态调试,有反调试,直接用ScyllaHide过掉。
base64换表,base64稍微改了一下:最后xor了0x18
最后在memcmp下断拿密文就行
2024-11-09T14:30:14.png

FlvtterM

Blutter逆向
然后就没时间做了,看到个换表base58,前面有一个x[i+1] ^= x[i]和一个换位置,但是最前面还有一个SBox相关的操作,SBox这个没看出来是什么。