BeginCTF2024 RE WP 剩下的复现

2024-02-18 01:44
文章标签 复现 wp re 剩下 beginctf2024

本文主要是介绍BeginCTF2024 RE WP 剩下的复现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

12. goforfun(寄)

前面是一些无关紧要的初始化

下面看到疑似rc4

虽然函数支离破碎,但可以看到rc4的结构,异或的部分做了魔改

后面似乎是base64换表,但脚本跑不出来,这里的算法没搞懂,只能贴一下别的dalao的

先逆后面的不明加密

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
unsigned char findPos(const unsigned char* base64_map, unsigned char c)//查找下标所在位置
{for (int i = 0; i < strlen((const char*)base64_map); i++){if (base64_map[i] == c)return i;}
}
unsigned char* base64_decode(const unsigned char* code0)
{unsigned char* code = (unsigned char*)code0;unsigned char base64_map[65] = "8G+cazk2jqb7w01CtoKH4FsrgR3vVmQ9pPhXLAleOd/nB6DfIxMWYiUZ5SEJyNuT";long len, str_len, flag = 0;unsigned char* res;len = strlen((const char*)code);if (code[len - 1] == '='){if (code[len - 2] == '='){flag = 1;str_len = len / 4 * 3 - 2;}else{flag = 2;str_len = len / 4 * 3 - 1;}}elsestr_len = len / 4 * 3;res = (unsigned char*)malloc(sizeof(unsigned char) * str_len + 1);unsigned char a[4] = { 0 };for (int i = 0, j = 0; j < str_len - flag; j += 3, i += 4){a[0] = findPos(base64_map, code[i]);		//code[]每一个字符对应base64表中的位置,用位置值反推原始数据值a[1] = findPos(base64_map, code[i + 1]);a[2] = findPos(base64_map, code[i + 2]);a[3] = findPos(base64_map, code[i + 3]);res[j] = a[0] | ((a[1] & 0x3) << 6);//第一个字符对应res[j + 1] = ((a[1] & 0x3c) >> 2) | ((a[2] & 0xf) << 4);res[j + 2] = ((a[3] & 0x3f) << 2) | ((a[2] & 0x30) >> 4);}switch (flag){case 0:break;case 1:{a[0] = findPos(base64_map, code[len - 4]);a[1] = findPos(base64_map, code[len - 3]);res[str_len - 1] = a[0] | ((a[1] & 0x3) << 6);break;}case 2: {a[0] = findPos(base64_map, code[len - 4]);a[1] = findPos(base64_map, code[len - 3]);a[2] = findPos(base64_map, code[len - 2]);res[str_len - 2] = a[0] | ((a[1] & 0x3) << 6);//第一个字符对应res[str_len - 1] = ((a[1] & 0x3c) >> 2) | ((a[2] & 0xf) << 4);break;}}res[str_len] = '\0';return res;
}
int main() {unsigned char BaseData[] = "HZ0sMJXqxHgUb2b9RNg+1xw=";unsigned char* result = base64_decode(BaseData);//魔改basefor (int i = 0; i < 17; i++)printf("%#x,", result[i]);return 0;
}
//0xd3,0xdd,0x58,0xf2,0x3e,0x26,0xf1,0x84,0xd9,0xca,0xa1,0x7c,0x59,0x8f,0x9,0x4e,0xcc,

之后rc4比较好还原一点

#goforfun wp
enc = "HZ0sMJXqxHgUb2b9RNg+1xw"
#enc = [0x48,0x5a,0x30,0x73,0x4d,0x4a,0x58,0x71,0x78,0x48,0x67,0x55,0x62,0x32,0x62,0x39,0x52,0x4e,0x67,0x2b,0x31,0x78,0x77]
key = 'happynewyear'
basemap = "8G+cazk2jqb7w01CtoKH4FsrgR3vVmQ9pPhXLAleOd/nB6DfIxMWYiUZ5SEJyNuT"
enc1=[0xd3,0xdd,0x58,0xf2,0x3e,0x26,0xf1,0x84,0xd9,0xca,0xa1,0x7c,0x59,0x8f,0x9,0x4e,0xcc]
enc2 = enc1[::-1]
#魔改rc4
s_box = [0]*256
for i in range(255,-1,-1):s_box[i] = - 1 - i
#print(s_box)
v8 = 0
v9 = 0
while ( v8 < 256 ):v10 = s_box[v8]v11 = v8v12 = v8 - 12 * (((2863311531 * v8) >> 32) >> 3)v9 += ord(key[v12%len(key)]) + v10v9 %= 256s_box[v11] = s_box[v9]s_box[v9] = v10                     v8 = v11 + 1
#S盒初始化
#print(s_box)
v4 = 0
v5 = 0
v6 = 0 
for i in range(len(enc2)):v7 = s_box[v5 + 1]%256v8 = (v7 + v6)%256s_box[v5 + 1] = s_box[v8]s_box[v8] = v7enc2[v4] ^= s_box[(v7 + s_box[v5 + 1])%256]  ^ 0x2Fenc2[v4] &= 0xFFv4 += 1v5 += 1v6 = v8
flag = ''
for i in range(len(enc2)):flag += chr(enc2[i])
print(flag)
#go_a_nice_journey
13. 出题人的密码是什么

修花指令得到主逻辑,反调试也patch掉

然后下面有一堆函数需要找加密在哪里,只能慢慢来找,可以把翻过的函数改名字减少重复劳动

中间__rdtsc函数部分是检测时间的函数,调试的时候跳过就行

__rdtsc 是一个在 x86 和 x86-64 架构上的内建函数,它读取当前的时间戳计数器(Time Stamp Counter, TSC)。时间戳计数器是一个由 CPU 提供的 64 位寄存器,它以一种非常高的频率(通常是 CPU 的主频)自增。由于其递增的频率非常高,它常被用作一个高精度的时间源,尤其是在需要测量代码执行时间等场景中。

最后发现两个加密部分

类似CRC的部分需要动调获得key的值,虽然是随机生成的但是其值不变

修改标志寄存器SF的跳过检验

key=0x33077D

从二进制角度理解更容易逆向

和0比较实际上是比较最高位(标志位)是0还是1:

  • 如果是1(负数),就左移一位(*2)与key异或

由于key最后一位是1,v6左移一位最后一位是0,异或结果最后一位必然是1。因此逆向的时候,如果一次加密后最后一位是1,这次加密前它肯定是负数

  • 如果是0(正数),就左移一位,最后一位就变成0。同理,最后一位是0的本次加密前一定是正数。

由此可以构建逆向脚本。

简单的异或

提一下密文就可以逆了

#出题人密码
crypto = [0xB4, 0xBB, 0xD8, 0xEB, 0xD0, 0x6E, 0xAB, 0xCA, 0x65, 0x8E, 0x4B, 0xE9, 0x4D, 0xD4, 0x4A, 0xF3, 0x7D, 0x29, 0xC2, 0xF9, 0x95, 0x89, 0xA4, 0x85, 0x9D, 0xCD, 0xDF, 0x77, 0xFD, 0x45, 0xCB, 0x5D, 0x7D, 0xFD, 0x93, 0x4B, 0xBC, 0xF6, 0x7C, 0xF3, 0x24, 0x42, 0xF5, 0xD2, 0xDD, 0xE3, 0x56, 0xAE]
#异或部分逆向
enc2 = [0]*len(crypto)
for i in range(len(crypto)):enc2[i] = ((crypto[i] ^ 0x25) - 5) & 0xff #这边要多加括号和限制位数,不然结果会有问题
print(enc2)
key = 0x33077D
#CRC部分逆向
def decrc(value, key):for i in range(64):if value & 1: #最后一位是1,加密前肯定是负数value = (value ^ key) >> 1value |= 0x8000000000000000  #还原最高位else: #最后一位是0,加密前必为正数value = value >> 1return valueflag = b''
for i in range(0, len(enc2), 8):enc1 = int.from_bytes(enc2[i: i + 8], 'little')flag += decrc(enc1, key).to_bytes(8, 'little')
print(flag)
'''
[140, 153, 248, 201, 240, 70, 137, 234, 59, 166, 105, 199, 99, 236, 106, 209, 83, 7, 226, 215, 171, 167, 124, 155, 179, 227, 245, 77, 211, 91, 233, 115, 83, 211, 177, 105, 148, 206, 84, 209, 252, 98, 203, 242, 243, 193, 110, 134]
b'begin{Th1s_reverse_pr0blem_may_t@ke_some_time#!}'
'''

14. ezvm

前面有一堆内存分配也不到有啥用

flag长度为32

34行 进去一大堆数据,猜测是opcode操作码

37行 可以看到最后的密文

35、36行很奇怪,动调后可以发现是虚拟机的初始化和分发函数

似乎是形成一个结构体存储opcode里的内容

修一修数据类型得到dispatcher部分的逻辑

根据不同的操作码调用不同偏移地址的函数(有些我已经改了名字先不管)

然后分析各个函数模拟的操作(我也不会分析……只是对着官方wp稍微理解一下)

提一下opcode打印指令,好在不是所有的函数都被用到了

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{unsigned char opcode[] ={0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x73, 0x00, 0x7A,0x73, 0x10, 0x67, 0x01, 0x7B, 0x74, 0x00, 0x7A, 0x75, 0x0B,0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x7B, 0x75, 0x01,0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x73, 0x10, 0x7A,0x73, 0x00, 0x6D, 0x01, 0x74, 0x00, 0x75, 0x09, 0x66};for (int i = 0; i < 49; i++){if ((opcode[i] >= 0x66 && opcode[i] <= 0x7C) && (opcode[i - 1] >= 0x66 && opcode[i - 1] <= 0x7C)){printf("\n");}switch (opcode[i]){case 0x66:printf("nop  ");continue;case 0x67:printf("add  ");continue;case 0x68:printf("sub  ");continue;case 0x69:printf("mul  ");continue;case 0x6A:printf("div  ");continue;case 0x6B:printf("inc  ");continue;case 0x6C:printf("dec  ");continue;case 0x6D:printf("xor  ");continue;case 0x6E:printf("and  ");continue;case 0x6F:printf("push  ");continue;case 0x70:printf("pushd  ");continue;case 0x71:printf("pop  ");continue;case 0x72:printf("mov  ");continue;case 0x73:printf("movd  ");continue;case 0x74:printf("move2d  ");continue;case 0x75:printf("loop  ");continue;case 0x76:printf("cmp  ");continue;case 0x77:printf("jl  ");continue;case 0x78:printf("jg  ");continue;case 0x79:printf("jz  ");continue;case 0x7A:printf("incd  ");continue;case 0x7B:printf("decd  ");continue;case 0x7C:printf("xor_ops  ");continue;default:if (opcode[i + 1] >= 0x66 && opcode[i + 1] <= 0x7C){printf("%#x\n", opcode[i]);}else {printf("%#x, ", opcode[i]);}continue;}}return 0;
}
/*
pushd  0, 0, 0, 0x1e
pop  0x30
movd  0
incd
movd  0x10
add  0x1
decd
move2d  0
incd
loop  0xb
pushd  0, 0, 0, 0x1e
pop  0x30
decd
loop  0x1
pushd  0, 0, 0, 0x1e
pop  0x30
movd  0x10
incd
movd  0
xor  0x1
move2d  0
loop  0x9
nop
*/

然后看不懂一点,贴一下官方wp

PUSHD,  0x00, 0x00, 0x00, 0x1E, //flag length-2
POP,    0x30,         //r3 = 0x2f
MOVD,   0x00,   //loop begin r0=dd
INCD,
// d[i]+=d[i+1]
MOVD,        0x10,   // r1 = d[i]
ADD,        0x01,        // r0 += r1
DECD,        //i--
MOV2D,        0x00,
INCD,        // d[i] = r0
LOOP,        0x0B,        //loop
//i=0
PUSHD,  0x00, 0x00, 0x00, 0x1E,//flag length-2
POP,         0x30,DECD,                        //loop begin
LOOP,        0x01,PUSHD,  0x00, 0x00, 0x00, 0x1E,//flag length-2
POP,         0x30,// d[i]^=d[i-1]
MOVD,        0x10,        //loop begin
INCD,
MOVD,        0x00,
XOR,        0x01,
MOV2D,        0x00,
LOOP,        0x09,        //loop
END
data = [0xC7, 0x0B, 0xDB, 0x0C, 0xE5, 0x08, 0xAD, 0xDE, 0xAF, 0xCD, 0x67, 0xBF, 0x1F, 0xBF, 0x1E, 0x68, 0xFE, 0x25, 0xFD, 0x6F, 0x08, 0x50, 0xCD, 0x15, 0xB0, 0x21, 0x8B, 0x3E, 0xFD, 0x73, 0xED, 0x90]
for i in range(len(data)-1,0,-1):data[i]^=data[i-1]
for i in range(len(data)-2,-1,-1):data[i]-=data[i+1]
print(bytes(data))
#b'begin{r3@11y_A_B4by_34$y_FK_Vm!}'
15. babyvm(寄)

完全学不懂,存一份脚本吧

opcode=[]
with open('opcode.vm','rb') as file:content=file.read()for i in range(0,len(content),4):opcode1=int.from_bytes(content[i:i+4],byteorder='little',signed=True)opcode.append(opcode1)
memory=[]
with open('memory.vm','rb') as file:content=file.read()for i in range(0,len(content),4):memory1=int.from_bytes(content[i:i+4],byteorder='little',signed=True)memory.append(memory1)
opcode_key = {1:'{} add {} {}',2:'{} sub {} {}',3:'{} mul {} {}',4:'{} div {} {}',5:'{} in_pointer 0',6:'{} out_pointer 0',7:'{} push flag',8:'{} pop output',9:'{} scanf flag',10:'{} show flag',11:'{} jmp {}',12:'{} njmp ',13:'{} len',
}
def get_eip(eip):return '_' + str(eip) + ':'
v16=opcode
i=0
disam=''
while i>=0 and i< len(opcode):x=v16[i]if x == 1:disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'memory[v16[i + 1]] = memory[v16[i + 2]] + memory[v16[i + 2 + 1]]i += 3 + 1continueif x == 2:disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2 + 1)]], memory[v16[(i + 2)]]) + '\n'memory[v16[i + 1]] =  memory[v16[i + 2]] + memory[v16[i + 2 + 1]]#print(memory[v16[i + 1]])+'\n')i += 3 + 1continueif x == 3:disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'memory[v16[i + 1]] = memory[v16[i + 2]] * memory[v16[i + 2 + 1]]print(memory[v16[i + 1 +2]])print(',')i += 3 + 1continueif x == 4:disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'memory[v16[i + 1]] = memory[v16[i + 2]] / memory[v16[i + 2 + 1]]i += 3 + 1continueif x == 5:disam += opcode_key[x].format(get_eip(i)) + '\n'v5 = 0i += v5 + 1continueif x == 6:disam += opcode_key[x].format(get_eip(i)) + '\n'v6 = 0i += v6 + 1continueif x == 7:disam += opcode_key[x].format(get_eip(i)) + '\n'v7 = 2i += v7 + 1continueif x == 8:disam += opcode_key[x].format(get_eip(i)) + '\n'v8 = 2i += v8 + 1continueif x == 9:disam += opcode_key[x].format(get_eip(i)) + '\n'buf = 1i += buf + 1continueif x == 10:disam += opcode_key[x].format(get_eip(i)) + '\n'v10 = 1i += v10 + 1continueif x == 11:disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 1)]]) + '\n'v11 = 2i += v11 + 1continueif x == 12:disam += opcode_key[x].format(get_eip(i)) + '\n'v12 = 2i += v12 + 1continueif x == 13:disam += opcode_key[x].format(get_eip(i)) + '\n'v13 = 2i += v13 + 1continuedisam+='exit(0)\n'i += 1continue
#print(disam)
from z3 import *
flag = []
key = [115
,
26
,
128
,
200
,
21
,
234
,
172
,
152
,
39
,
71
,
55
,
28
,
105
,
42
,
75
,
63
,
114
,
205
,
2
,
222
,
212
,
148
,
17
,
74
,
87
,
253
,
250
,
136
,
89
,
211
,
49
,
26
,
115
,
88
,
181
,
195
,
237
,
10
,
119
,
121
,
229
,
172
,
230
,
123
,
245
,
127
,
119
,
157
,
208
,
159
,
37
,
32
,
5
,
207
,
145
,
75
,
251
,
60
,
135
,
125
,
181
,
83
,
66
,
43
,
85
,
198
,
89
,
205
,
114
,
221
,
105
,
145
,
155
,
91
,
123
,
48
,
76
,
64
,
141
,
22
,
211
,
225
,
204
,
55
,
107
,
76
,
7
,
39
,
199
,
84
,
167
,
62
,
219
,
54
,
6
,
144
,
55
,
98
,
186
,
116
,
149
,
163
,
127
,
186
,
46
,
118
,
247
,
194
,
9
,
165
,
169
,
224
,
68
,
129
,
54
,
15
,
134
,
39
,
185
,
248
,
245
,
159
,
64
,
241
,
163
,
116
,
4
,
15
,
126
,
170
,
10
,
110
,
251
,
169
,
252
,
99
,
199
,
188
,
149
,
72
,
233
,
38
,
197
,
105
,
202
,
2
,
22
,
225
,
189
,
166
,
239
,
220
,
70
,
98
,
194
,
129
,
27
,
236
,
159
,
62
,
152
,
67
,
72
,
35
,
12
,
55
,
139
,
4
,
169
,
142
,
135
,
122
,
3
,
166
,
139
,
62
,
23
,
92
,
11
,
136
,
96
,
141
,
38
,
124
,
139
,
43
,
15
,
119
,
30
,
252
,
255
,
123
,
223
,
200
,
21
,
117
,
231
,
9
,
239
,
222
,
249
,
91
,
66
,
21
,
121
,
146
,
5
,
180
,
6
,
80
,
112
,
255
,
239
,
17
,
39
,
254
,
153
,
118
,
47
,
217
,
84
,
96
,
190
,
188
,
255
,
181
,
188
,
124
,
47
,
70
,
201
,
160
,
126
,
210
,
236
,
22
,
120
,
181
,
197
,
69
,
51
,
173
,
216
,
143
,
41
,
174
,
184
,
189
,
111
,
133
,
79
,
36
,
99
,
140
,
120
,
144
,
80
,
231
,
187
,
107
,
173
,
39
,
151
,
161
,
139
,
233
,
143
,
205
,
170
,
125
,
209
,
54
,
128
,
134
,
55
,
246
,
157
,
57
,
42
,
195
,
5
,
49
,
235
,
8
,
84
,
9
,
219
,
90
,
109
,
164
,
38
,
159
,
218
,
214
,
22
,
205
,
7
,
57
,
210
,
131
,
107
,
67
,
107
,
141
,
129
,
250
,
97
,
3
,
26
,
215
,
119
,
213
,
255
,
183
,
229
,
1
,
27
,
9
,
88
,
59
,
57
,
72
,
91
,
96
,
125
,
105
,
94
,
235
,
138
,
39
,
145
,
130
,
126
,
147
,
254
,
179
,
181
,
183
,
216
,
211
,
164
,
205
,
28
,
160
,
233
,
70
,
109
,
51
,
0
,
71
,
99
,
163
,
37
,
98
,
46
,
44
,
138
,
135
,
191
,
144
,
13
,
240
,
143
,
53
,
75
,
23
,
26
,
224
,
31
,
199
,
182
,
220
,
130
,
61
,
170
,
130
,
253
,
240
,
182
,
9
,
245
,
96
,
170
,
79
,
249
,
16
,
121
,
6
,
7
,
69
,
212
,
133
,
52
,
20
,
225
,
102
,
228
,
121
,
56
,
208
]
v = [217114,270581,291585,234325,240502,277604,286168,290450,179355,272487,249816,305636,276217,294166,237236,242008,289929,221788,268459,247407]
for i in range(20):flag.append(BitVec('%d' % i, 8))    #char型
s = Solver()
s.add(flag[0]*key[0]+flag[1]*key[1]+flag[2]*key[2]+flag[3]*key[3]+flag[4]*key[4]+flag[5]*key[5]+flag[6]*key[6]+flag[7]*key[7]+flag[8]*key[8]+flag[9]*key[9]+flag[10]*key[10]+flag[11]*key[11]+flag[12]*key[12]+flag[13]*key[13]+flag[14]*key[14]+flag[15]*key[15]+flag[16]*key[16]+flag[17]*key[17]+flag[18]*key[18]+flag[19]*key[19]==v[0])
s.add(flag[0]*key[20]+flag[1]*key[21]+flag[2]*key[22]+flag[3]*key[23]+flag[4]*key[24]+flag[5]*key[25]+flag[6]*key[26]+flag[7]*key[27]+flag[8]*key[28]+flag[9]*key[29]+flag[10]*key[30]+flag[11]*key[31]+flag[12]*key[32]+flag[13]*key[33]+flag[14]*key[34]+flag[15]*key[35]+flag[16]*key[36]+flag[17]*key[37]+flag[18]*key[38]+flag[19]*key[39]==v[1])
s.add(flag[0]*key[40]+flag[1]*key[41]+flag[2]*key[42]+flag[3]*key[43]+flag[4]*key[44]+flag[5]*key[45]+flag[6]*key[46]+flag[7]*key[47]+flag[8]*key[48]+flag[9]*key[49]+flag[10]*key[50]+flag[11]*key[51]+flag[12]*key[52]+flag[13]*key[53]+flag[14]*key[54]+flag[15]*key[55]+flag[16]*key[56]+flag[17]*key[57]+flag[18]*key[58]+flag[19]*key[59]==v[2])
s.add(flag[0]*key[60]+flag[1]*key[61]+flag[2]*key[62]+flag[3]*key[63]+flag[4]*key[64]+flag[5]*key[65]+flag[6]*key[66]+flag[7]*key[67]+flag[8]*key[68]+flag[9]*key[69]+flag[10]*key[70]+flag[11]*key[71]+flag[12]*key[72]+flag[13]*key[73]+flag[14]*key[74]+flag[15]*key[75]+flag[16]*key[76]+flag[17]*key[77]+flag[18]*key[78]+flag[19]*key[79]==v[3])
s.add(flag[0]*key[80]+flag[1]*key[81]+flag[2]*key[82]+flag[3]*key[83]+flag[4]*key[84]+flag[5]*key[85]+flag[6]*key[86]+flag[7]*key[87]+flag[8]*key[88]+flag[9]*key[89]+flag[10]*key[90]+flag[11]*key[91]+flag[12]*key[92]+flag[13]*key[93]+flag[14]*key[94]+flag[15]*key[95]+flag[16]*key[96]+flag[17]*key[97]+flag[18]*key[98]+flag[19]*key[99]==v[4])
s.add(flag[0]*key[100]+flag[1]*key[101]+flag[2]*key[102]+flag[3]*key[103]+flag[4]*key[104]+flag[5]*key[105]+flag[6]*key[106]+flag[7]*key[107]+flag[8]*key[108]+flag[9]*key[109]+flag[10]*key[110]+flag[11]*key[111]+flag[12]*key[112]+flag[13]*key[113]+flag[14]*key[114]+flag[15]*key[115]+flag[16]*key[116]+flag[17]*key[117]+flag[18]*key[118]+flag[19]*key[119]==v[5])
s.add(flag[0]*key[120]+flag[1]*key[121]+flag[2]*key[122]+flag[3]*key[123]+flag[4]*key[124]+flag[5]*key[125]+flag[6]*key[126]+flag[7]*key[127]+flag[8]*key[128]+flag[9]*key[129]+flag[10]*key[130]+flag[11]*key[131]+flag[12]*key[132]+flag[13]*key[133]+flag[14]*key[134]+flag[15]*key[135]+flag[16]*key[136]+flag[17]*key[137]+flag[18]*key[138]+flag[19]*key[139]==v[6])
s.add(flag[0]*key[140]+flag[1]*key[141]+flag[2]*key[142]+flag[3]*key[143]+flag[4]*key[144]+flag[5]*key[145]+flag[6]*key[146]+flag[7]*key[147]+flag[8]*key[148]+flag[9]*key[149]+flag[10]*key[150]+flag[11]*key[151]+flag[12]*key[152]+flag[13]*key[153]+flag[14]*key[154]+flag[15]*key[155]+flag[16]*key[156]+flag[17]*key[157]+flag[18]*key[158]+flag[19]*key[159]==v[7])
s.add(flag[0]*key[160]+flag[1]*key[161]+flag[2]*key[162]+flag[3]*key[163]+flag[4]*key[164]+flag[5]*key[165]+flag[6]*key[166]+flag[7]*key[167]+flag[8]*key[168]+flag[9]*key[169]+flag[10]*key[170]+flag[11]*key[171]+flag[12]*key[172]+flag[13]*key[173]+flag[14]*key[174]+flag[15]*key[175]+flag[16]*key[176]+flag[17]*key[177]+flag[18]*key[178]+flag[19]*key[179]==v[8])
s.add(flag[0]*key[180]+flag[1]*key[181]+flag[2]*key[182]+flag[3]*key[183]+flag[4]*key[184]+flag[5]*key[185]+flag[6]*key[186]+flag[7]*key[187]+flag[8]*key[188]+flag[9]*key[189]+flag[10]*key[190]+flag[11]*key[191]+flag[12]*key[192]+flag[13]*key[193]+flag[14]*key[194]+flag[15]*key[195]+flag[16]*key[196]+flag[17]*key[197]+flag[18]*key[198]+flag[19]*key[199]==v[9])
s.add(flag[0]*key[200]+flag[1]*key[201]+flag[2]*key[202]+flag[3]*key[203]+flag[4]*key[204]+flag[5]*key[205]+flag[6]*key[206]+flag[7]*key[207]+flag[8]*key[208]+flag[9]*key[209]+flag[10]*key[210]+flag[11]*key[211]+flag[12]*key[212]+flag[13]*key[213]+flag[14]*key[214]+flag[15]*key[215]+flag[16]*key[216]+flag[17]*key[217]+flag[18]*key[218]+flag[19]*key[219]==v[10])
s.add(flag[0]*key[220]+flag[1]*key[221]+flag[2]*key[222]+flag[3]*key[223]+flag[4]*key[224]+flag[5]*key[225]+flag[6]*key[226]+flag[7]*key[227]+flag[8]*key[228]+flag[9]*key[229]+flag[10]*key[230]+flag[11]*key[231]+flag[12]*key[232]+flag[13]*key[233]+flag[14]*key[234]+flag[15]*key[235]+flag[16]*key[236]+flag[17]*key[237]+flag[18]*key[238]+flag[19]*key[239]==v[11])
s.add(flag[0]*key[240]+flag[1]*key[241]+flag[2]*key[242]+flag[3]*key[243]+flag[4]*key[244]+flag[5]*key[245]+flag[6]*key[246]+flag[7]*key[247]+flag[8]*key[248]+flag[9]*key[249]+flag[10]*key[250]+flag[11]*key[251]+flag[12]*key[252]+flag[13]*key[253]+flag[14]*key[254]+flag[15]*key[255]+flag[16]*key[256]+flag[17]*key[257]+flag[18]*key[258]+flag[19]*key[259]==v[12])
s.add(flag[0]*key[260]+flag[1]*key[261]+flag[2]*key[262]+flag[3]*key[263]+flag[4]*key[264]+flag[5]*key[265]+flag[6]*key[266]+flag[7]*key[267]+flag[8]*key[268]+flag[9]*key[269]+flag[10]*key[270]+flag[11]*key[271]+flag[12]*key[272]+flag[13]*key[273]+flag[14]*key[274]+flag[15]*key[275]+flag[16]*key[276]+flag[17]*key[277]+flag[18]*key[278]+flag[19]*key[279]==v[13])
s.add(flag[0]*key[280]+flag[1]*key[281]+flag[2]*key[282]+flag[3]*key[283]+flag[4]*key[284]+flag[5]*key[285]+flag[6]*key[286]+flag[7]*key[287]+flag[8]*key[288]+flag[9]*key[289]+flag[10]*key[290]+flag[11]*key[291]+flag[12]*key[292]+flag[13]*key[293]+flag[14]*key[294]+flag[15]*key[295]+flag[16]*key[296]+flag[17]*key[297]+flag[18]*key[298]+flag[19]*key[299]==v[14])
s.add(flag[0]*key[300]+flag[1]*key[301]+flag[2]*key[302]+flag[3]*key[303]+flag[4]*key[304]+flag[5]*key[305]+flag[6]*key[306]+flag[7]*key[307]+flag[8]*key[308]+flag[9]*key[309]+flag[10]*key[310]+flag[11]*key[311]+flag[12]*key[312]+flag[13]*key[313]+flag[14]*key[314]+flag[15]*key[315]+flag[16]*key[316]+flag[17]*key[317]+flag[18]*key[318]+flag[19]*key[319]==v[15])
s.add(flag[0]*key[320]+flag[1]*key[321]+flag[2]*key[322]+flag[3]*key[323]+flag[4]*key[324]+flag[5]*key[325]+flag[6]*key[326]+flag[7]*key[327]+flag[8]*key[328]+flag[9]*key[329]+flag[10]*key[330]+flag[11]*key[331]+flag[12]*key[332]+flag[13]*key[333]+flag[14]*key[334]+flag[15]*key[335]+flag[16]*key[336]+flag[17]*key[337]+flag[18]*key[338]+flag[19]*key[339]==v[16])
s.add(flag[0]*key[340]+flag[1]*key[341]+flag[2]*key[342]+flag[3]*key[343]+flag[4]*key[344]+flag[5]*key[345]+flag[6]*key[346]+flag[7]*key[347]+flag[8]*key[348]+flag[9]*key[349]+flag[10]*key[350]+flag[11]*key[351]+flag[12]*key[352]+flag[13]*key[353]+flag[14]*key[354]+flag[15]*key[355]+flag[16]*key[356]+flag[17]*key[357]+flag[18]*key[358]+flag[19]*key[359]==v[17])
s.add(flag[0]*key[360]+flag[1]*key[361]+flag[2]*key[362]+flag[3]*key[363]+flag[4]*key[364]+flag[5]*key[365]+flag[6]*key[366]+flag[7]*key[367]+flag[8]*key[368]+flag[9]*key[369]+flag[10]*key[370]+flag[11]*key[371]+flag[12]*key[372]+flag[13]*key[373]+flag[14]*key[374]+flag[15]*key[375]+flag[16]*key[376]+flag[17]*key[377]+flag[18]*key[378]+flag[19]*key[379]==v[18])
s.add(flag[0]*key[380]+flag[1]*key[381]+flag[2]*key[382]+flag[3]*key[383]+flag[4]*key[384]+flag[5]*key[385]+flag[6]*key[386]+flag[7]*key[387]+flag[8]*key[388]+flag[9]*key[389]+flag[10]*key[390]+flag[11]*key[391]+flag[12]*key[392]+flag[13]*key[393]+flag[14]*key[394]+flag[15]*key[395]+flag[16]*key[396]+flag[17]*key[397]+flag[18]*key[398]+flag[19]*key[399]==v[19])
if s.check() == sat:print(s.model())end={18 : 97,2 : 118, 12 : 118,13 : 109,3 : 101, 10 : 110,15 : 104,17 : 104,7 : 110,16 : 97,5 : 102,14 : 95,9 : 105,6 : 117,11 : 95,1 : 97,19 : 97,8 : 95,0 : 104,4 : 95}
flag=''
for i in range(20):flag+=chr(end[i])
print(flag)
16. 真龙之力

尝试安装失败,是因为xml被改了

可以用MT管理器或者AndroidKiller修改AndroidManifest.xml

调用者不被允许测试的测试程序-CSDN博客文章浏览阅读2.3k次。报错:调用者不被允许测试的测试程序原因:未对测试功能加以限制(直接从Android Studio调试运行应该默认是开了调试模式)解决方法: 在application标签里面添加android:testOnly="false"属性即可..._调用者不被允许测试的测试程序https://blog.csdn.net/kicinio/article/details/117232493#:~:text=%E6%8A%A5%E9%94%99%EF%BC%9A%E8%B0%83%E7%94%A8%E8%80%85%E4%B8%8D%E8%A2%AB%E5%85%81%E8%AE%B8%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A8%8B%E5%BA%8F%E5%8E%9F%E5%9B%A0%EF%BC%9A%E6%9C%AA%E5%AF%B9%E6%B5%8B%E8%AF%95%E5%8A%9F%E8%83%BD%E5%8A%A0%E4%BB%A5%E9%99%90%E5%88%B6%EF%BC%88%E7%9B%B4%E6%8E%A5%E4%BB%8EAndroid%20Studio%E8%B0%83%E8%AF%95%E8%BF%90%E8%A1%8C%E5%BA%94%E8%AF%A5%E9%BB%98%E8%AE%A4%E6%98%AF%E5%BC%80%E4%BA%86%E8%B0%83%E8%AF%95%E6%A8%A1%E5%BC%8F%EF%BC%89%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%9A,%3Capplication...%20android%3AtestOnly%3D%22false%22...%20%3C%2Fapplication%3E%E5%9C%A8application%E6%A0%87%E7%AD%BE%E9%87%8C%E9%9D%A2%E6%B7%BB%E5%8A%A0android%3AtestOnly%3D%22false%22%E5%B1%9E%E6%80%A7%E5%8D%B3%E5%8F%AF..._%E8%B0%83%E7%94%A8%E8%80%85%E4%B8%8D%E8%A2%AB%E5%85%81%E8%AE%B8%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A8%8B%E5%BA%8F

MT管理器

改一下即可

AndroidKiller方便一点

安装后需要key和ID

jadx看一下源码

第一个按钮做了加密

具体逻辑在lib的libdragon.so里面

第二个按钮也进行了一些加密

进行了类似于RC4初始化的打乱,但没有异或操作,也就是说只是改变了顺序,可以用索引还原。

解压apk用IDA分析libdragon.so

应该是以v43作为xtea的key,把v42加密了,加密后的KEY(v42)应该在这

解一下KEY

#include<stdio.h>
#include<string.h>
int main()
{unsigned int __cdecl xtea_decryption(unsigned int* a1, const unsigned int* a2);//unsigned int teakey[4] = { 0x76543210 , 0xFEDCBA98 , 0x89ABCDEF, 0x1234567 };unsigned int teakey[4] = { 0x1234567, 0x89ABCDEF , 0xFEDCBA98 , 0x76543210 };unsigned int enc[4] = { 0x1b253544,0xfcc56bb0 };xtea_decryption(enc, teakey);printf("%x\n", enc);printf("%s", enc);return 0;
}
unsigned int __cdecl xtea_decryption(unsigned int* a1, const unsigned int* a2)
{unsigned int result; // eaxint i; // [esp+0h] [ebp-18h]unsigned int sum; // [esp+8h] [ebp-10h]unsigned int v5; // [esp+Ch] [ebp-Ch]unsigned int v6; // [esp+10h] [ebp-8h]v6 = *a1;v5 = a1[1];sum = 0x9E3779B9 *32;for (i = 0; i < 32; ++i){v5 -= (a2[(sum >> 11) & 3] + sum) ^ (v6 + ((v6 >> 4) ^ (32 * v6)));sum -= 0x9E3779B9;v6 -= (a2[sum & 3] + sum) ^ (v5 + ((v5 >> 4) ^ (32 * v5)));}*a1 = v6;result = v5;a1[1] = v5;return result;
}
//e4aff8a8
//4202SDYY

端序问题跑出来是反的 YYDS2024

打乱的密文 i{biecfuialflnlv_eegieo}Ntt

长度为27,我们输入一串长度27的字符串来查索引

输出vfaxnwtidyzulemjrqbckhs0gop

#dragonindex exp
table = "abcdefghijklmnopqrstuvwxyz0"
back = "vfaxnwtidyzulemjrqbckhs0gop"
enc = "i{biecfuialflnlv_eegieo}Ntt"
for i in table:print(enc[back.index(i)],end="")
#begin{Neuvillette_official}

这篇关于BeginCTF2024 RE WP 剩下的复现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719651

相关文章

剑指offer(C++)--孩子们的游戏(圆圈中最后剩下的数)

题目 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去

【漏洞复现】畅捷通T+ keyEdit.aspx SQL漏洞

0x01 产品简介 畅捷通 T+ 是一款灵动,智慧,时尚的基于互联网时代开发的管理软件,主要针对中小型工贸与商贸企业,尤其适合有异地多组织机构(多工厂,多仓库,多办事处,多经销商)的企业,涵盖了财务,业务,生产等领域的应用,产品应用功能包括: 采购管理、库存管理、销售管理、生产管理、分销管理、零售管理、往来管理、现金银行管理、总账、移动应用等,融入了社交化、移动化、电子商务、互联网信息订阅等元素

【论文复现|智能算法改进】一种基于多策略改进的鲸鱼算法

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 SCI二区|鲸鱼优化算法(WOA)原理及实现【附完整Matlab代码】 2.改进点 混沌反向学习策略 将混沌映射和反向学习策略结合,形成混沌反向学习方法,通过该方 法生成鲸鱼算法的初始种群。混沌序列采用 Tent 混沌映射: x i + 1 = { δ x i 0 < x i < 0.5

2024 WaniCTF repwn 部分wp

lambda   文本编辑器打开附件 稍微格式化一下 结合gpt理解题目意思。 脚本 home   附件拖入ida 简单的检查环境和反调试,进构造flag的函数 简单的ollvm,用d810嗦一下 下断点调试,通过修改eip跳过反调试。查看dest内容,需要稍微向下翻一下,程序故意把flag藏在后面  gates

【华东南AWDP】第十七届全国大学生信息安全竞赛 CISCN 2024 创新实践能力赛区域赛 部分题解WP

前言:这次区域赛AWDP安恒作为支持,赛制风格遵循安恒,一小时check一次。室温35°在室内坐了8小时,午饭是藿香正气水拌冰水。这场总体下来中规中矩吧。 WEB-welcome-BREAK Ctrl+U拿到flag WEB-submit-BREAK 文件上传,简单绕过 绕过就两个,一个MIMA头,一个等号换php(短标签) WEB-submit-FIX 修两个点,一个是

Python武器库开发-武器库篇之ThinkPHP 5.0.23-RCE 漏洞复现(六十四)

Python武器库开发-武器库篇之ThinkPHP 5.0.23-RCE 漏洞复现(六十四) 漏洞环境搭建 这里我们使用Kali虚拟机安装docker并搭建vulhub靶场来进行ThinkPHP漏洞环境的安装,我们进入 ThinkPHP漏洞环境,可以 cd ThinkPHP,然后通过 ls 查看可以搭建的靶场,目前 vulhub关于 ThinkPHP漏洞。可以搭建的靶场有五个。我们拿 5.0.

【漏洞复现】AJ-Report开源数据大屏 verification;swagger-ui RCE漏洞

0x01 产品简介 AJ-Report是一个完全开源的B平台,酷炫大屏展示,能随时随地掌控业务动态,让每个决策都有数据支撑。多数据源支持,内置mysql、elasticsearch、kudu等多种驱动,支持自定义数据集省去数据接口开发,支持17+种大屏组件,不会开发,照着设计稿也可以制作大屏。三步轻松完成大屏设计:配置数据源–>写SQL配置数据集->拖拽配置大屏->保存发布。欢迎体验。 0x0

玄机——第五章 Windows 实战-evtx 文件分析 wp

文章目录 一、前言二、概览简化 三、参考文章四、步骤(解析)步骤#11.将黑客成功登录系统所使用的IP地址作为Flag值提交;拓展1.1 步骤#22.黑客成功登录系统后修改了登录用户的用户名,将修改后的用户名作为Flag值提交;拓展1.2拓展1.3 步骤#33.黑客成功登录系统后成功访问了一个关键位置的文件,将该文件名称(文件名称不包含后缀)作为Flag值提交;拓展1.4拓展1.5 步

【完全复现】基于改进粒子群算法的微电网多目标优化调度(含matlab代码)

目录 主要内容      部分代码      结果一览    下载链接 主要内容    程序完全复现文献模型《基于改进粒子群算法的微电网多目标优化调度》,以微电网系统运行成本和环境保护成本为目标函数,建立了并网方式下的微网多目标优化调度模型,通过改进粒子群算法和原始粒子群算法进行对比,验证改进方法的优越性。虽然标题是多目标优化算法,实质指的是权值多目标,即通过不同目标权值相

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《含氢综合能源系统多目标最优折中分布鲁棒低碳调度》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源程序擅长文章解读,论文与完整源程序,等方面的知识,电网论文源程序关注python