wp

pic

动调可知,就是一个异或加rc4,需要爆破5位的key

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
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <numeric>

std::vector<int> init_permutation(const std::vector<int>& key) {
std::vector<int> S(256);
std::iota(S.begin(), S.end(), 0);
int j = 0;
for (int i = 0; i < 256; ++i) {
j = (j + S[i] + key[i % key.size()]) % 256;
std::swap(S[i], S[j]);
}
return S;
}


std::vector<unsigned char> read_file(const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::cerr << "无法打开文件!" << std::endl;
exit(1);
}
std::vector<unsigned char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
return buffer;
}
int main() {
const std::string filename = "C:\\工作区\\box\\ctf\\dasctf2024qiu\\re\\pic\\pic\\bak\\flag.png";
auto buf = read_file(filename);
auto bak = buf;
std::vector<int> onkey;

for (char i1 = '0'; i1 <= 'z'; ++i1) {
if (i1 > '9' && i1 < 'a') continue;
for (char i2 = '0'; i2 <= 'z'; ++i2) {
if (i2 > '9' && i2 < 'a') continue;
for (char i3 = '0'; i3 <= 'z'; ++i3) {
if (i3 > '9' && i3 < 'a') continue;
for (char i4 = '0'; i4 <= 'z'; ++i4) {
if (i4 > '9' && i4 < 'a') continue;
for (char i5 = '0'; i5 <= 'z'; ++i5) {
if (i5 > '9' && i5 < 'a') continue;
buf = bak;
std::vector<int> combination = { i1, i2, i3, i4, i5 };
unsigned char xor_num = i2;
std::vector<int> S = init_permutation(combination);
for (int i = 0; i < 4; i++)
{
buf[i] ^= xor_num;
}
int i = 0, j = 0, q = 0;
while (q < 4) {
i = (i + 1) % 256;
j = (S[i] + j) % 256;
std::swap(S[i], S[j]);
buf[q] ^= S[(S[i] + S[j]) % 256] ^ 0x11;
++q;
}
if ((buf[0] == 0x89) && (buf[1] == 0x50) && (buf[2] == 0x4e) && (buf[3] == 0x47)) {
std::cout << i1 << i2 << i3 << i4 << i5 << '\n';
goto A;
}
}
}
}
}
}
A:
std::cout << "finished" << '\n';
return 0;
}

爆出来之后直接解密

你这主函数保真吗

直接调试,然后就是原题

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
#include<vector>
#include<iostream>
void dct3(const std::vector<double>& Y, std::vector<double>& X) {
int N = Y.size();
X.resize(N);

for (int n = 0; n < N; ++n) {
double sum = 0;
for (int k = 0; k < N; ++k) {
if (k == 0)
{
sum += Y[k] * std::cos(3.14159265 * k * (n + 0.5) / N) * std::sqrt(1.0 / N);
}
else
{
sum += Y[k] * std::cos(3.14159265 * k * (n + 0.5) / N) * std::sqrt(2.0 / N);
}

}
X[n] = sum;
}

}
int main(void) {
std::vector<double> res = { 513.355, -37.7986, 8.7316, -10.7832, -1.3097, -20.5779,
6.98641, -29.2989, 15.9422,21.4138,29.4754, -2.77161,
-6.58794, -4.22332, -7.20771, 8.83506, -4.38138, -19.3898,
18.3453, 6.88259, -14.7652, 14.6102, 24.7414, -11.6222,
-9.754759999999999,12.2424,13.4343, -34.9307, -35.735,
-20.0848, 39.689, 21.879, 26.8296 };
std::vector<double> X;
dct3(res, X);
for (double x : X) {
std::cout << x << ",";
}
std::cout << std::endl;

for (int i = 0; i < 33; i++) {
unsigned char chr = (char)std::round(X[i]);
std::cout << chr;
}
}
//最后rot13


doccrack

用7z解压

vbaProject.bin中把DPB改成DPx,然后打开word的宏可以直接得到源代码。

把下面执行的地方删除,运行得到exe,然后直接逆

1
2
3
4
5
6
from prism import *
data = [0x10C0, 0x1180, 0x1500, 0x1100, 0x14C0, 0x1040, 0x1F00, 0x1440, 0x1940, 0x1980, 0x1600, 0x0D80, 0x1D00, 0x1600, 0x18C0, 0x1980, 0x1A40, 0x1800, 0x1880, 0x1D40, 0x1A00, 0x1C80, 0x1D00, 0x0980, 0x0980, 0x0980, 0x1600, 0x1140, 0x0D80, 0x1C00, 0x1980, 0x1D40, 0x1880, 0x1600, 0x0DC0, 0x1840, 0x1600, 0x1280, 0x1980, 0x1900, 0x1D40, 0x0DC0, 0x1600, 0x1440, 0x0D80, 0x1D40, 0x1C80, 0x0C80, 0x1880, 0x1D00, 0x0980, 0x0980, 0x0980, 0x1E80]

for i in range(len(data)):
data[i]>>=6
pxor(data,7)