前言

2023-12-18创建的文件夹,搁到现在才上传,忘了,麻麻了

rev === 强ollvm杯

babyre

Tls附加dbg

过掉

把程序运行,在这儿附加

img

静态密文,key都是假的

img

动调起来得到真的

密文

img

Key

img

这是delta

img

调到跳出循环,得到sum

img

img

Exp

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
#include <iostream>
#include <cstdint>
void XTEA_decrypt(uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
unsigned int sum = 0xd192c263;
uint32_t v0 = v[0], v1 = v[1];
for (int j = 0; j < 4; j++) {
for (i = 0; i < 33; i++) {
sum -= 0x88408067;
v1 -= (key[(sum >> 11) & 3] + sum) ^ (v0 + ((v0 >> 4) ^ (v0 << 5)));
v0 -= (key[sum & 3] + sum) ^ sum ^ (v1 + ((v1 >> 4) ^ (v1 << 5)));

}
}
v[0] = v0;
v[1] = v1;
//std::cout << (v[0] & 0xFF) << ((v[0] >> 8) & 0xFF)
// << ((v[0] >> 16) & 0xFF) << ((v[0] >> 24) & 0xFF);
//std::cout << (v[1] & 0xFF) << ((v[1] >> 8) & 0xFF)
// << ((v[1] >> 16) & 0xFF) << ((v[1] >> 24) & 0xFF);
std::cout << (char)(v[0] & 0xFF) << (char)((v[0] >> 8) & 0xFF)
<< (char)((v[0] >> 16) & 0xFF) << (char)((v[0] >> 24) & 0xFF);
std::cout << (char)(v[1] & 0xFF) << (char)((v[1] >> 8) & 0xFF)
<< (char)((v[1] >> 16) & 0xFF) << (char)((v[1] >> 24) & 0xFF);
}
int main() {
uint32_t enc[] = { 0x9523F2E0, 0x8ED8C293, 0x8668C393, 0xDDF250BC, 0x510E4499, 0x8C60BD44, 0x34DCABF2, 0xC10FD260 };
uint32_t key[4] = { 0x62, 0x6F, 0x6D, 0x62 }; // bomb
for (int i = 0; i < 8; i += 2) {
uint32_t tmp[2];
tmp[0] = enc[i];
tmp[1] = enc[i + 1];
XTEA_decrypt(tmp, key);
}

return 0;
}

flag{W31com3_2_Th3_QwbS7_4nd_H4v3_Fun}

ezre

ida打开D810去ollvm混淆,start!

D810是插件 搜到直接用 前提:angr要装好

img

main函数无有用信息

img

SM4加密

img

img

也可以搜固定的数组

img

img

密文和密钥在这

img

Key :

0123456789ABCDEF0123456789ABCDEF

Cipher:

067519471663887C8B6655FF3F7D0D4AF5D24E383FE9C2DEDB7C7F6F74B11F3C

Flag:

flag{h3kk0_w0rld_sur3_3n0ugh}

cyberchef解

img

也可以脚本,贴一个自己去研究

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
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <iostream>
using namespace std;
typedef long long ll;
#define Rotl(_x,_y) ((_x)<<(_y)|(_x)>>(32-(_y)))
#define SboxTrans(_A) (Sbox[(_A)>>24&0xFF]<<24|Sbox[(_A)>>16&0xFF]<<16|Sbox[(_A)>>8&0xFF]<<8|Sbox[(_A)&0xFF])
#define L1(x) ((x)^Rotl(x,2)^Rotl(x,10)^Rotl(x,18)^Rotl(x,24))
#define L2(x) ((x)^Rotl(x,13)^Rotl(x,23))
const unsigned int CK[32] = {
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
const unsigned int RK[4] = { 0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC };
const unsigned char Sbox[256] = {
0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,
0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,
0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,
0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,
0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,
0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,
0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,
0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,
0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,
0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,
0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,
0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,
0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,
0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,
0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
};
//const unsigned int Rotl(unsigned int n,int b){ return n<<b|n>>(32-b); }
unsigned int xx[32];
void SM4KeyExt(unsigned int* key, unsigned int* rk, unsigned int CryptFlag) {//秘钥扩展算法,flag为1代表解密
unsigned int r, tmp, k[4];
for (int i = 0; i < 4; i++) k[i] = key[i] ^ RK[i];
for (int i = 0; i < 32; i += 4) {
for (int j = 0; j < 4; j++) {
k[j] ^= L2((unsigned int)SboxTrans(k[(j + 1) % 4] ^ k[(j + 2) % 4] ^ k[(j + 3) % 4] ^ CK[i + j]));
rk[i + j] = k[j];
}
}
if (CryptFlag == 1) for (r = 0; r < 16; r++) swap(rk[r], rk[31 - r]);

}

void SM4Crypt(unsigned int* Input, unsigned int* Output, unsigned int* rk) {
unsigned int tmp, x[4], * y;
y = (unsigned int*)Input;
for (int i = 0; i < 4; i++) x[i] = y[i];
for (int i = 0; i < 32; i += 4) {
for (int j = 0; j < 4; j++) {
x[j] ^= L1((unsigned int)SboxTrans(x[(j + 1) % 4] ^ x[(j + 2) % 4] ^ x[(j + 3) % 4] ^ rk[i + j]));
xx[i + j] = x[j];
}
}
y = (unsigned int*)Output;
for (int i = 0; i < 4; i++) y[i] = x[3 - i];
}

unsigned int key[4] = { 0x01234567,0x89abcdef,0x01234567,0x89abcdef, };
unsigned int miwen[4] = { 0x067519471663887C,0x8B6655FF3F7D0D4A,0xF5D24E383FE9C2DE,0xDB7C7F6F74B11F3C };
unsigned int mingwen[4] = { 0x01234567,0x89abcdef,0xfedcba98,0x76543210 };
unsigned int rk[32];
unsigned int output[4] = {};
void solve1() {
printf("题目1:\n");
SM4KeyExt(key, rk, 0);
printf("rk数组:\n");
for (int i = 0; i < 32; i++) printf("%08x\n", rk[i]);
printf("\n");
printf("x数组:\n");
SM4Crypt(mingwen, output, rk);
for (int i = 0; i < 32; i++) printf("%08x\n", xx[i]);
printf("结果:\n");
for (int i = 0; i < 4; i++) printf("%08x ", output[i]);
printf("\n");
}
void solve2() {
printf("题目2:\n");
SM4KeyExt(key, rk, 0);
for (int i = 0; i < 1000000; i++) {
SM4Crypt(mingwen, mingwen, rk);
}
for (int i = 0; i < 4; i++) cout << hex << mingwen[i] << " ";
cout << "\n";
}
int main() {
//freopen("out.txt","w",stdout);
solve1();
solve2();
return 0;
}

ezre-强网先锋

打开题目发现是ollvm平坦化混淆。img

可以使用插件D810去控制流平坦化

使用前提:angr要装好

img

也可以使用OLLVM去除 https://github.com/cq674350529/deflat 中的混淆。

可以使用以下Python命令进行操作:python deflat.py -f ezre –addr 0xxxxxxxx。

去完混淆分析代码,发现就是经过5次bas加解密,问题在于密文

交叉引用,有个反调试

审计发现,如果赋值为1,则修改密文

img

那么我们可以动调,在main函数把base的table取出

通过异或得到密文

然后复现加密流程,经过5次加解密得到flag

这个是main函数中调用的Base加密函数

img

这个是动调出来的base的table

From base64

plxXOZtaiUneJIhk7qSYEjD1Km94o0FTu52VQgNL3vCBH8zsA/b+dycGPRMwWfr6

To base64

pnHQwlAveo4DhGg1jE3SsIqJ2mrzxCiNb+Mf0YVd5L8c97/WkOTtuKFZyRBUPX6a

From base64

Hc0xwuZmy3DpQnSgj2LhUtrlVvNYks+BX/MOoETaKqR4eb9WF8ICGzf6id1P75JA

To base64

FGseVD3ibtHWR1czhLnUfJK6SEZ2OyPAIpQoqgY0w49u+7rad5CxljMXvNTBkm/8

From base64

l+USN4J5Rfj0TaVOcnzXiPGZIBpoAExuQtHyKD692hwmqe7/Mgk8v1sdCW3bYFLr

这是反解密文的脚本

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
k=[109,76,22,73,110,77,74,78,16,98,22,109,16,126,78,109,76,22,73,110,77,74,78,16,98,22,109,16,126,78,109,76,22,73,110,77,74,78,16,98,22,109,16,126,78,109,76,0]

enc=[0x3A,0x2C,0x4B,0x51,0x68,0x46,0x59,0x63,0x24,0x04,

0x5E,0x5f,0x00,0x0C,0x2B,0x03,0x29,0x5C,0x74,0x70,

0x6A,0x62,0x7F,0x3D,0x2C,0x4E,0x6F,0x13,0x06,0x0D,

0x06,0x0C,0x4D,0x56,0x0f,0x28,0x4D,0x51,0x76,0x70,

0x2B,0x05,0x51,0x68,0x48,0x55,0x24,0x19]

enc2=[0x3A,0x2C,0x4B,0x51,0x68,0x46,0x59,0x63,0x24,0x04,

0x5E,0x5f,0x00,0x0C,0x2B,0x03,0x29,0x5C,0x74,0x70,

0x6A,0x62,0x7F,0x3D,0x2C,0x4E,0x6F,0x13,0x06,0x0D,

0x06,0x0C,0x4D,0x56,0x0f,0x28,0x4D,0x51,0x76,0x70,

0x2B,0x05,0x51,0x68,0x48,0x55,0x24,0x19]

tmp=''



for i in range(len(enc)-1):

enc[i + 1]=enc[i +1]^enc2[i]

enc[i]=enc[i]^k[i]

print(hex(enc[i]),end=',')

enc[-1]=enc2[-1]^enc2[-2]

print(hex(enc[-1]))

得出密文

img

0x57,0x3d

0x5a,0x3d

0x71,0x3d

0x53,0x3d

0x57,0x3d

0x63,0x3d

0x55,0x3d

0x74,0x3d

0x57,0x3d

0x42,0x3d

0x4c,0x3d

0x6c,0x3d

0x4f,0x3d

0x72,0x3d

0x69,0x3d

0x45,0x3d

0x66,0x3d

0x63,0x3d

0x61,0x3d

0x6a,0x3d

0x57,0x3d

0x42,0x3d

0x53,0x3d

0x52,0x3d

0x73,0x3d

0x74,0x3d

0x4c,0x3d

0x6c,0x3d

0x6b,0x3d

0x45,0x3d

0x66,0x3d

0x46,0x3d

0x57,0x3d

0x52,0x3d

0x37,0x3d

0x6a,0x3d

0x2f,0x3d

0x52,0x3d

0x37,0x3d

0x64,0x3d

0x4d,0x3d

0x43,0x3d

0x44,0x3d

0x47,0x3d

0x6e,0x3d

0x70,0x3d

0x3d,0x3d

img

flag{3ea590ccwxehg715264fzxnzepqz}

dotdot

还是可以学到东西的

因为前期尝试手动解密,对加密的流程有了很深刻理解(

白盒技术

白盒密码技术是一项能够抵抗白盒攻击的密码技术。

白盒攻击是指攻击者对设备终端拥有完全的控制能力,能够观测和更改程序运行时的内部数据。

这种攻击环境称为白盒攻击环境。大多智能终端环境(Android、iOS等)在很多情况下就是一个白

盒攻击环境。

大概就是这样

image-20240627145653200

image-20240627145717595

主要还是 AAA -> AES白盒加密

image-20240627145735745

前期铺垫

将复杂的加密修改成简单的步骤

当没有chang_index函数时,加密就变成了4字节为单位进行加密了。

下面是我将题目给的代码,进行了修改,然后整理如下:

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
from data import *
#input = [i for i in range(97, 97 + 16)]
input=[1, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102]
def AAA():
global input
for i in range(9):
for j in range(4):
#16个 字符
num = table1[i][4 * j][input[4 * j]]
num2 = table1[i][4 * j + 1][input[4 * j + 1]]
num3 = table1[i][4 * j + 2][input[4 * j + 2]]
num4 = table1[i][4 * j + 3][input[4 * j + 3]]
num5 = table2[i][24 * j][(num >> 28 & 15)][(num2 >> 28 & 15)]
num6 = table2[i][24 * j + 1][(num3 >> 28 & 15)][(num4 >> 28 & 15)]
num7 = table2[i][24 * j + 2][(num >> 24 & 15)][(num2 >> 24 & 15)]
num8 = table2[i][24 * j + 3][(num3 >> 24 & 15)][(num4 >> 24 & 15)]
input[4 * j] = (table2[i][24 * j + 4][num5][num6] << 4 | table2[i][24
* j + 5][num7][num8])
num5 = table2[i][24 * j + 6][(num >> 20 & 15)][(num2 >> 20 & 15)]
num6 = table2[i][24 * j + 7][(num3 >> 20 & 15)][(num4 >> 20 & 15)]
num7 = table2[i][24 * j + 8][(num >> 16 & 15)][(num2 >> 16 & 15)]
num8 = table2[i][24 * j + 9][(num3 >> 16 & 15)][(num4 >> 16 & 15)]
input[4 * j + 1] = (table2[i][24 * j + 10][num5][num6] << 4 | table2
[i][24 * j + 11][num7][num8])
num5 = table2[i][24 * j + 12][(num >> 12 & 15)][(num2 >> 12 & 15)]
num6 = table2[i][24 * j + 13][(num3 >> 12 & 15)][(num4 >> 12 & 15)]
num7 = table2[i][24 * j + 14][(num >> 8 & 15)][(num2 >> 8 & 15)]
num8 = table2[i][24 * j + 15][(num3 >> 8 & 15)][(num4 >> 8 & 15)]
input[4 * j + 2] = (table2[i][24 * j + 16][num5][num6] << 4 | table2[i][24 * j + 17][num7][num8])
num5 = table2[i][24 * j + 18][(num >> 4 & 15)][(num2 >> 4 & 15)]
num6 = table2[i][24 * j + 19][(num3 >> 4 & 15)][(num4 >> 4 & 15)]
num7 = table2[i][24 * j + 20][(num & 15)][(num2 & 15)]
num8 = table2[i][24 * j + 21][(num3 & 15)][(num4 & 15)]
input[4 * j + 3] = (table2[i][24 * j + 22][num5][num6] << 4 | table2
[i][24 * j + 23][num7][num8])
AAA()
for i in input:
print(hex(i),end=',')
crypto=[0x4e,0xdc,0x24,0x8f,0x26,0xd2,0xd9,0x1d,0xf1,0xce,0x84,0xfa,0xf1,0x5,0xe,
0x41]

改成这样,就变成了4字节爆破。

发现改变1个字节(4个字节单位)发生变化

image-20240725120303602

1
2
3
4
5
6
7
def change_index():
global input
array2 = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11]
arr = [0] * 16
for i in range(16):
arr[i] = input[array2[i]]
input = arr