0%

re1

re1

好久没整博客了,因为博客的文件被我不小心手欠删了,但一直有写,后面有时间就传上去!中间打了很多比赛,也被虐的很惨,稍微复现几道题。

Destdog3的几道题

1、go

这个题目就看出来是一个go语言的逆向,go语言的逆向首先看字符串是否恢复,如果没恢复就要用到某些插件了,其次找main_main这个函数,这个函数的入口如果直接能搜到,那就很好,没搜到也没关系,我们自己写个程序从start跟到main_main来看一看。

如果没有任何修改的话,我们进入程序直接f5是这个场面,一直跟进函数

跟到下图:

我们进入runtime_mainPC函数

在.rdata段,通过交叉引用找到.text段的,找到main_main入口

这个题也是这样,不过这个程序被处理了,代码并没有变成汇编,我们找到对应地方后,点c点p给他整成函数就行

image-20220629234427308

我们用findcrypt很轻松的查出来有两个加密,第一个是tea,第二个是aes加密

看着看着发现这玩意不能动态调试,应该是有反调试,但静态也能猜出来,我们先看看tea加密

很显然v17为key,v16位data,直接写脚本

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
#include <stdio.h>
#include <stdint.h>

//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}

int main()
{
uint32_t v[2]={1,2},k[4]={2,2,3,4};
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为432位无符号整数,即密钥长度为128
printf("加密前原始数据:%x %x\n",v[0],v[1]);
encrypt(v, k);
printf("加密后的数据:%x %x\n",v[0],v[1]);
decrypt(v, k);
printf("解密后的数据:%x %x\n",v[0],v[1]);
return 0;
}

发现hint是see_sbox。。。。。。那不就是aes吗。

找了个js脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const data = [
0x34, 0xC9, 0x05, 0xB3, 0x67, 0x81, 0xC8, 0xAD, 0x20, 0xC2, 0x2F, 0x07,
0x93, 0x03, 0xD6, 0x65, 0x7A, 0x2E, 0xBA, 0xF4, 0x7C, 0x71, 0x0B, 0xEC,
0xC4, 0x81, 0x34, 0xDA, 0xDC, 0xE9, 0x7E, 0xEE, 0x05, 0xCF, 0x21, 0xC7,
0xD9, 0x76, 0xE1, 0x76, 0x84, 0x82, 0xDE, 0xD9, 0xCB, 0x77, 0x5E, 0xA0
];

console.log(data)
const crypto = require('crypto')
let keyiv = Buffer.from('12fe32ba87654321')
console.log(keyiv)

const deci = crypto.createDecipheriv('aes-128-cbc', keyiv, keyiv)
let dec = deci.update(Buffer.from(data))
dec += deci.final()
console.log(dec)

还有c的脚本

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
/****************************************************************************************************************/
typedef enum {
AES_CYPHER_128,
AES_CYPHER_192,
AES_CYPHER_256,
} AES_CYPHER_T;
/****************************************************************************************************************/
/*
* Encryption Rounds
*/
int g_aes_key_bits[] = {
/* AES_CYPHER_128 */ 128,
/* AES_CYPHER_192 */ 192,
/* AES_CYPHER_256 */ 256,
};
int g_aes_rounds[] = {
/* AES_CYPHER_128 */ 10,
/* AES_CYPHER_192 */ 12,
/* AES_CYPHER_256 */ 14,
};
int g_aes_nk[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 6,
/* AES_CYPHER_256 */ 8,
};
int g_aes_nb[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 4,
/* AES_CYPHER_256 */ 4,
};
/****************************************************************************************************************/
/*
* aes Rcon:
*
* WARNING: Rcon is designed starting from 1 to 15, not 0 to 14.
* FIPS-197 Page 9: "note that i starts at 1, not 0"
*
* i | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
* -----+------------------------------------------------------------------------------------------
* | [01] [02] [04] [08] [10] [20] [40] [80] [1b] [36] [6c] [d8] [ab] [4d] [9a]
* RCON | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
*/
static const uint32_t g_aes_rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0xed000000, 0x9a000000
};
/****************************************************************************************************************/
/*
* aes sbox and invert-sbox
*/
static const uint8_t g_aes_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static const uint8_t g_inv_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
/****************************************************************************************************************/
uint8_t aes_sub_sbox(uint8_t val)
{
return g_aes_sbox[val];
}
/****************************************************************************************************************/
uint32_t aes_sub_dword(uint32_t val)
{
uint32_t tmp = 0;

tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 0) & 0xFF))) << 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 8) & 0xFF))) << 8;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 16) & 0xFF))) << 16;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 24) & 0xFF))) << 24;

return tmp;
}
/****************************************************************************************************************/
uint32_t aes_rot_dword(uint32_t val)
{
uint32_t tmp = val;

return (val >> 8) | ((tmp & 0xFF) << 24);
}
/****************************************************************************************************************/
uint32_t aes_swap_dword(uint32_t val)
{
return (((val & 0x000000FF) << 24) |
((val & 0x0000FF00) << 8) |
((val & 0x00FF0000) >> 8) |
((val & 0xFF000000) >> 24));
}
/****************************************************************************************************************/
/*
* nr: number of rounds
* nb: number of columns comprising the state, nb = 4 dwords (16 bytes)
* nk: number of 32-bit words comprising cipher key, nk = 4, 6, 8 (KeyLength/(4*8))
*/
void aes_key_expansion(AES_CYPHER_T mode, uint8_t *key, uint8_t *round)
{
uint32_t *w = (uint32_t *)round;
uint32_t t;
int i = 0;

do {
w[i] = *((uint32_t *)&key[i * 4 + 0]);
} while (++i < g_aes_nk[mode]);

do {
if ((i % g_aes_nk[mode]) == 0) {
t = aes_rot_dword(w[i - 1]);
t = aes_sub_dword(t);
t = t ^ aes_swap_dword(g_aes_rcon[i / g_aes_nk[mode] - 1]);
}
else if (g_aes_nk[mode] > 6 && (i % g_aes_nk[mode]) == 4) {
t = aes_sub_dword(w[i - 1]);
}
else {
t = w[i - 1];
}
w[i] = w[i - g_aes_nk[mode]] ^ t;
} while (++i < g_aes_nb[mode] * (g_aes_rounds[mode] + 1));
}
/****************************************************************************************************************/
void aes_add_round_key(AES_CYPHER_T mode, uint8_t *state,
uint8_t *round, int nr)
{
uint32_t *w = (uint32_t *)round;
uint32_t *s = (uint32_t *)state;
int i;

for (i = 0; i < g_aes_nb[mode]; i++) {
s[i] ^= w[nr * g_aes_nb[mode] + i];
}
}
/****************************************************************************************************************/
void aes_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;

for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = aes_sub_sbox(state[i * 4 + j]);
}
}
}
/****************************************************************************************************************/
void aes_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;

for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < i; j++) {
uint8_t tmp = s[i];
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
/****************************************************************************************************************/
uint8_t aes_xtime(uint8_t x)
{
return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
}
/****************************************************************************************************************/
uint8_t aes_xtimes(uint8_t x, int ts)
{
while (ts-- > 0) {
x = aes_xtime(x);
}

return x;
}
/****************************************************************************************************************/
uint8_t aes_mul(uint8_t x, uint8_t y)
{
/*
* encrypt: y has only 2 bits: can be 1, 2 or 3
* decrypt: y could be any value of 9, b, d, or e
*/

return ((((y >> 0) & 1) * aes_xtimes(x, 0)) ^
(((y >> 1) & 1) * aes_xtimes(x, 1)) ^
(((y >> 2) & 1) * aes_xtimes(x, 2)) ^
(((y >> 3) & 1) * aes_xtimes(x, 3)) ^
(((y >> 4) & 1) * aes_xtimes(x, 4)) ^
(((y >> 5) & 1) * aes_xtimes(x, 5)) ^
(((y >> 6) & 1) * aes_xtimes(x, 6)) ^
(((y >> 7) & 1) * aes_xtimes(x, 7)));
}
/****************************************************************************************************************/
void aes_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2 };
uint8_t s[4];
int i, j, r;

for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
/****************************************************************************************************************/
int aes_encrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */

int nr, i, j;

/* key expansion */
aes_key_expansion(mode, key, w);

/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {

/* init state from user buffer (plaintext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];

/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {

if (nr > 0) {

/* do SubBytes */
aes_sub_bytes(mode, s);

/* do ShiftRows */
aes_shift_rows(mode, s);

if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}

/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
}

/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
}

return 0;
}
/****************************************************************************************************************/
int aes_encrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_encrypt(mode, data, len, key);
}
/****************************************************************************************************************/
int aes_encrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */

int nr, i, j;


/* key expansion */
aes_key_expansion(mode, key, w);

memcpy(v, iv, sizeof(v));

/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {

/* init state from user buffer (plaintext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j] ^ v[j];

/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {

if (nr > 0) {

/* do SubBytes */
aes_sub_bytes(mode, s);

/* do ShiftRows */
aes_shift_rows(mode, s);

if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}

/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
}

/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = v[j] = s[j];
}

return 0;
}
/****************************************************************************************************************/
void inv_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;

for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < g_aes_nb[mode] - i; j++) {
uint8_t tmp = s[i];
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
/****************************************************************************************************************/
uint8_t inv_sub_sbox(uint8_t val)
{
return g_inv_sbox[val];
}
/****************************************************************************************************************/
void inv_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;

for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = inv_sub_sbox(state[i * 4 + j]);
}
}
}
/****************************************************************************************************************/
void inv_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 0x0e, 0x0b, 0x0d, 0x09, 0x09, 0x0e, 0x0b, 0x0d,
0x0d, 0x09, 0x0e, 0x0b, 0x0b, 0x0d, 0x09, 0x0e };
uint8_t s[4];
int i, j, r;

for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
/****************************************************************************************************************/
int aes_decrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */

int nr, i, j;

/* key expansion */
aes_key_expansion(mode, key, w);

/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {

/* init state from user buffer (cyphertext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];

/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {

/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);

if (nr > 0) {

if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}

/* do ShiftRows */
inv_shift_rows(mode, s);

/* do SubBytes */
inv_sub_bytes(mode, s);
}
}

/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
}

return 0;
}
/****************************************************************************************************************/
int aes_decrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_decrypt(mode, data, len, key);
}
/****************************************************************************************************************/
int aes_decrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */


int nr, i, j;

/* key expansion */
aes_key_expansion(mode, key, w);

memcpy(v, iv, sizeof(v));

/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {


/* init state from user buffer (cyphertext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];

/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {

/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);

if (nr > 0) {

if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}

/* do ShiftRows */
inv_shift_rows(mode, s);

/* do SubBytes */
inv_sub_bytes(mode, s);
}
}

/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++) {
uint8_t p = s[j] ^ v[j];
v[j] = data[i + j];
data[i + j] = p;
}
}

return 0;
}
/****************************************************************************************************************/
void aes_cypher_128_test()
{
#if 1
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
#else
uint8_t buf[] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d,
0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 };
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
#endif

aes_encrypt(AES_CYPHER_128, buf, sizeof(buf), key);

aes_decrypt(AES_CYPHER_128, buf, sizeof(buf), key);
}
/****************************************************************************************************************/
void aes_cypher_192_test()
{
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };

aes_encrypt(AES_CYPHER_192, buf, sizeof(buf), key);

aes_decrypt(AES_CYPHER_192, buf, sizeof(buf), key);
}
/****************************************************************************************************************/
void aes_cypher_256_test()
{
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };

aes_encrypt(AES_CYPHER_256, buf, sizeof(buf), key);

aes_decrypt(AES_CYPHER_256, buf, sizeof(buf), key);
}
/****************************************************************************************************************/
void main()
{
//数据
uint8_t buf[] = { 0x34, 0xC9, 0x05, 0xB3, 0x67, 0x81, 0xC8, 0xAD, 0x20, 0xC2, 0x2F, 0x07,
0x93, 0x03, 0xD6, 0x65, 0x7A, 0x2E, 0xBA, 0xF4, 0x7C, 0x71, 0x0B, 0xEC,
0xC4, 0x81, 0x34, 0xDA, 0xDC, 0xE9, 0x7E, 0xEE, 0x05, 0xCF, 0x21, 0xC7,
0xD9, 0x76, 0xE1, 0x76, 0x84, 0x82, 0xDE, 0xD9, 0xCB, 0x77, 0x5E, 0xA0};
//密钥
uint8_t key[] = { 49, 50, 102, 101, 51, 50, 98, 97, 56, 55, 54, 53, 52, 51, 50, 49 };
//向量
uint8_t iv[] = {49, 50, 102, 101, 51, 50, 98, 97, 56, 55, 54, 53, 52, 51, 50, 49};
switch (sizeof(key))
{
//ECB
/*
case 16:aes_decrypt(AES_CYPHER_128, buf, sizeof(buf), key); break;
case 24:aes_decrypt(AES_CYPHER_192, buf, sizeof(buf), key); break;
case 32:aes_decrypt(AES_CYPHER_256, buf, sizeof(buf), key); break;
//CBC
*/
case 16:aes_decrypt_cbc(AES_CYPHER_128, buf, sizeof(buf), key, iv); break;
case 24:aes_decrypt_cbc(AES_CYPHER_192, buf, sizeof(buf), key, iv); break;
case 32:aes_decrypt_cbc(AES_CYPHER_256, buf, sizeof(buf), key, iv); break;

}
for (int i = 0; i < sizeof(buf); i++)
{
printf("%c", buf[i] & 0xFF);
}
printf("\n");
return;
}

跑出来是一样的:Dest0g3{4a9ff880-ea23-5016-b1aa-2ee3bf985533}

一点都没魔改的aes。

2、ttttea

这题就是个魔改的xxtea,本来以为很简单,但跑出来的脚本总是不对,才发现有TLS回调函数,里面改了delta

发现key是delta,这个还魔改了一个右移6

我们直接到exports里看tls回调函数:

先改了delta,然后又异或了一下

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
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x74746561
#define MX (((z>>6^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
{
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}


int main()
{
uint32_t v[]= {0x2F222303, 0x43FD8836, 0x655BE821, 0xA63B1E31, 0x88DCB84B, 0x6F841980, 0x26217297, 0xBBEE64AD, 0x064D0488, 0x6BE5262F, 0x73F54B81};
uint32_t const k[4]= {0x61,0x65,0x74,0x74};
int n= 11; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("beforecode:%x %x\n",v[0],v[1]);
//btea(v, n, k);
//printf("encode:%x %x\n",v[0],v[1]);
btea(v, -n, k);
printf("decode:%x %x\n",v[0],v[1]);
printf("decode:%x %x\n",v[2],v[3]);
printf("decode:%x %x\n",v[4],v[5]);
printf("decode:%x %x\n",v[6],v[7]);
printf("decode:%x %x\n",v[8],v[9]);
printf("decode:%x",v[10]);
return 0;
}

结果小端序就对了。

鹏城杯的re

分最少的re反而是最难的,属实难崩

maze

其实这个题逻辑和迷宫都很清晰,就是一棵树,有链表连成的树,脚本比较难写,其他还好。

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
__int64 sub_40500A()
{
__int64 end; // rbp
char input; // [rsp+Fh] [rbp-29h] BYREF
__int64 start; // [rsp+10h] [rbp-28h] BYREF
unsigned __int64 v4; // [rsp+18h] [rbp-20h]

v4 = __readfsqword(0x28u);
initmap(); // 生成地图
end = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(qword_5D3680 + 8) + 8LL) + 8LL);// 终点节点
start = *(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(qword_5D36A0 + 8) + 8LL) + 8LL) + 8LL);// 最初节点
*(_BYTE *)(start + 27) = 1;
printf(&unk_5D45C0, "Welcome to Hexagonal maze\nplz enter the foot print\n");
input = 0;
do
{
sub_46D9D0(&unk_5D45C0, "> ", 2LL);
sub_452070(&unk_5D46E0, &input);
main_func(&start, (unsigned int)input);//对输入进行验证
}
while ( start != end );
sub_46D9D0(&unk_5D45C0, "flag is md5 your input", 22LL);
sub_46D7E0(&unk_5D45C0);
if ( __readfsqword(0x28u) != v4 )
sub_52CB40();
return 0LL;
}

查看main_func函数

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
_QWORD *__fastcall sub_404BF5(_QWORD **a1, char a2)
{
_QWORD *v2; // rax
_QWORD *v3; // rax
_QWORD *result; // rax
_QWORD *v5; // rax

switch ( a2 )
{
case 'l':
if ( *((_BYTE *)*a1 + 24) || (v3 = (_QWORD *)**a1) == 0LL )
exit(0LL);
*a1 = v3;
break;
case 'r':
if ( *((_BYTE *)*a1 + 25) || (v5 = (_QWORD *)(*a1)[1]) == 0LL )
exit(0LL);
*a1 = v5;
break;
case 't':
if ( *((_BYTE *)*a1 + 26) || (v2 = (_QWORD *)(*a1)[2]) == 0LL )
exit(0LL);
*a1 = v2;
break;
default:
exit(0LL);
}
result = *a1;
if ( *((_BYTE *)*a1 + 27) )
exit(0LL);
*((_BYTE *)result + 27) = 1;
return result;
}

输入就是从“l“,”r”,“t”中选的,如果输入是l,那么对这棵树进行判断,判断其标志位是否是0,是0可通过,是1不可通过

image-20220705152407696

查看这个链表组成的结构体,偏移为0x0处是代表l,偏移为0x8代表r,偏移为0x10是代表t,偏移为0x18的数代表是否通行,偏移为0x28的是代表这个节点结束。每个节点的大小是相同的,那么只需要找到地图边界的起点和终点就行。然后idapython写个脚本提取一下

1
2
3
4
5
6
x = [0x00000000019df8f0,0x00000000019E0310] 
maze = []
for i in range(x[0],x[1],8*6):
for k in range(6):
maze.append(get_qword(i+k*8))
print(maze)

整理成二维数组:

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

map_o = [0, 0, 0, 0, 0, 49, 0, 27130192, 27130528, 1, 0, 49, 27130144, 27130240, 0, 65536, 0, 49, 27130192, 27130288, 27130624, 65536, 0, 49, 27130240, 27130336, 0, 256, 0, 49, 27130288, 27130384, 27130720, 65537, 0, 49, 27130336, 27130432, 0, 65536, 0, 49, 27130384, 0, 27130816, 256, 0, 49, 0, 27130528, 27130960, 1, 0, 49, 27130480, 27130576, 27130144, 256, 0, 49, 27130528, 27130624, 27131056, 1, 0, 49, 27130576, 27130672, 27130240, 65536, 0, 49, 27130624, 27130720, 27131152, 65536, 0, 49, 27130672, 27130768, 27130336, 65536, 0, 49, 27130720, 27130816, 27131248, 256, 0, 49, 27130768, 27130864, 27130432, 1, 0, 49, 27130816, 0, 27131344, 256, 0, 49, 0, 27130960, 27131440, 257, 0, 49, 27130912, 27131008, 27130480, 1, 0, 49, 27130960, 27131056, 27131536, 65536, 0, 49, 27131008, 27131104, 27130576, 256, 0, 49, 27131056, 27131152, 27131632, 1, 0, 49, 27131104, 27131200, 27130672, 65536, 0, 49, 27131152, 27131248, 27131728, 256, 0, 49, 27131200, 27131296, 27130768, 1, 0, 49, 27131248, 27131344, 27131824, 256, 0, 49, 27131296, 27131392, 27130864, 1, 0, 49, 27131344, 0, 27131920, 256, 0, 49, 0, 27131488, 27130912, 1, 0, 49, 27131440, 27131536, 27131968, 0, 0, 49, 27131488, 27131584, 27131008, 65536, 0, 49, 27131536, 27131632, 27132064, 65792, 0, 49, 27131584, 27131680, 27131104, 1, 0, 49, 27131632, 27131728, 27132160, 0, 0, 49, 27131680, 27131776, 27131200, 256, 0, 49, 27131728, 27131824, 27132256, 257, 0, 49, 27131776, 27131872, 27131296, 1, 0, 49, 27131824, 27131920, 27132352, 0, 0, 49, 27131872, 0, 27131392, 256, 0, 49, 0, 27132016, 27131488, 1, 0, 49, 27131968, 27132064, 27132400, 256, 0, 49, 27132016, 27132112, 27131584, 65537, 0, 49, 27132064, 27132160, 27132496, 65536, 0, 49, 27132112, 27132208, 27131680, 16777216, 0, 49, 27132160, 27132256, 27132592, 0, 0, 49, 27132208, 27132304, 27131776, 0, 0, 49, 27132256, 27132352, 27132688, 65536, 0, 49, 27132304, 0, 27131872, 256, 0, 49, 0, 27132448, 27132016, 1, 0, 49, 27132400, 27132496, 0, 65536, 0, 49, 27132448, 27132544, 27132112, 65536, 0, 49, 27132496, 27132592, 0, 65536, 0, 49, 27132544, 27132640, 27132208, 0, 0, 49, 27132592, 27132688, 0, 65536, 0, 49]
map = [[0 for i in range(7)] for k in range(54)]
cout = 0
for i in range(0,len(map_o),6):
for k in range(1,7):
map[cout][k] = map_o[i+k-1]
cout += 1
#print(map)
cout = 0
ea = [0x00000000019df8f0,0x00000000019E0310]
for i in range(ea[0],ea[1],6*8):
map[cout][0] = i
cout += 1
print(map)


for i in range(0,54):
for k in range(7):
print(hex(map[i][k]),end=", ")
print(" ")
{0x19df8f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31},
{0x19df920, 0x0, 0x19df950, 0x19dfaa0, 0x1, 0x0, 0x31},
{0x19df950, 0x19df920, 0x19df980, 0x0, 0x10000, 0x0, 0x31},
{0x19df980, 0x19df950, 0x19df9b0, 0x19dfb00, 0x10000, 0x0, 0x31},
{0x19df9b0, 0x19df980, 0x19df9e0, 0x0, 0x100, 0x0, 0x31},
{0x19df9e0, 0x19df9b0, 0x19dfa10, 0x19dfb60, 0x10001, 0x0, 0x31},
{0x19dfa10, 0x19df9e0, 0x19dfa40, 0x0, 0x10000, 0x0, 0x31},
{0x19dfa40, 0x19dfa10, 0x0, 0x19dfbc0, 0x100, 0x0, 0x31},
{0x19dfa70, 0x0, 0x19dfaa0, 0x19dfc50, 0x1, 0x0, 0x31},
{0x19dfaa0, 0x19dfa70, 0x19dfad0, 0x19df920, 0x100, 0x0, 0x31},
{0x19dfad0, 0x19dfaa0, 0x19dfb00, 0x19dfcb0, 0x1, 0x0, 0x31},
{0x19dfb00, 0x19dfad0, 0x19dfb30, 0x19df980, 0x10000, 0x0, 0x31},
{0x19dfb30, 0x19dfb00, 0x19dfb60, 0x19dfd10, 0x10000, 0x0, 0x31},
{0x19dfb60, 0x19dfb30, 0x19dfb90, 0x19df9e0, 0x10000, 0x0, 0x31},
{0x19dfb90, 0x19dfb60, 0x19dfbc0, 0x19dfd70, 0x100, 0x0, 0x31},
{0x19dfbc0, 0x19dfb90, 0x19dfbf0, 0x19dfa40, 0x1, 0x0, 0x31},
{0x19dfbf0, 0x19dfbc0, 0x0, 0x19dfdd0, 0x100, 0x0, 0x31},
{0x19dfc20, 0x0, 0x19dfc50, 0x19dfe30, 0x101, 0x0, 0x31},
{0x19dfc50, 0x19dfc20, 0x19dfc80, 0x19dfa70, 0x1, 0x0, 0x31},
{0x19dfc80, 0x19dfc50, 0x19dfcb0, 0x19dfe90, 0x10000, 0x0, 0x31},
{0x19dfcb0, 0x19dfc80, 0x19dfce0, 0x19dfad0, 0x100, 0x0, 0x31},
{0x19dfce0, 0x19dfcb0, 0x19dfd10, 0x19dfef0, 0x1, 0x0, 0x31},
{0x19dfd10, 0x19dfce0, 0x19dfd40, 0x19dfb30, 0x10000, 0x0, 0x31},
{0x19dfd40, 0x19dfd10, 0x19dfd70, 0x19dff50, 0x100, 0x0, 0x31},
{0x19dfd70, 0x19dfd40, 0x19dfda0, 0x19dfb90, 0x1, 0x0, 0x31},
{0x19dfda0, 0x19dfd70, 0x19dfdd0, 0x19dffb0, 0x100, 0x0, 0x31},
{0x19dfdd0, 0x19dfda0, 0x19dfe00, 0x19dfbf0, 0x1, 0x0, 0x31},
{0x19dfe00, 0x19dfdd0, 0x0, 0x19e0010, 0x100, 0x0, 0x31},
{0x19dfe30, 0x0, 0x19dfe60, 0x19dfc20, 0x1, 0x0, 0x31},
{0x19dfe60, 0x19dfe30, 0x19dfe90, 0x19e0040, 0x0, 0x0, 0x31},
{0x19dfe90, 0x19dfe60, 0x19dfec0, 0x19dfc80, 0x10000, 0x0, 0x31},
{0x19dfec0, 0x19dfe90, 0x19dfef0, 0x19e00a0, 0x10100, 0x0, 0x31},
{0x19dfef0, 0x19dfec0, 0x19dff20, 0x19dfce0, 0x1, 0x0, 0x31},
{0x19dff20, 0x19dfef0, 0x19dff50, 0x19e0100, 0x0, 0x0, 0x31},
{0x19dff50, 0x19dff20, 0x19dff80, 0x19dfd40, 0x100, 0x0, 0x31},
{0x19dff80, 0x19dff50, 0x19dffb0, 0x19e0160, 0x101, 0x0, 0x31},
{0x19dffb0, 0x19dff80, 0x19dffe0, 0x19dfda0, 0x1, 0x0, 0x31},
{0x19dffe0, 0x19dffb0, 0x19e0010, 0x19e01c0, 0x0, 0x0, 0x31},
{0x19e0010, 0x19dffe0, 0x0, 0x19dfe00, 0x100, 0x0, 0x31},
{0x19e0040, 0x0, 0x19e0070, 0x19dfe60, 0x1, 0x0, 0x31},
{0x19e0070, 0x19e0040, 0x19e00a0, 0x19e01f0, 0x100, 0x0, 0x31},
{0x19e00a0, 0x19e0070, 0x19e00d0, 0x19dfec0, 0x10001, 0x0, 0x31},
{0x19e00d0, 0x19e00a0, 0x19e0100, 0x19e0250, 0x10000, 0x0, 0x31},
{0x19e0100, 0x19e00d0, 0x19e0130, 0x19dff20, 0x1000000, 0x0, 0x31},
{0x19e0130, 0x19e0100, 0x19e0160, 0x19e02b0, 0x0, 0x0, 0x31},
{0x19e0160, 0x19e0130, 0x19e0190, 0x19dff80, 0x0, 0x0, 0x31},
{0x19e0190, 0x19e0160, 0x19e01c0, 0x19e0310, 0x10000, 0x0, 0x31},
{0x19e01c0, 0x19e0190, 0x0, 0x19dffe0, 0x100, 0x0, 0x31},
{0x19e01f0, 0x0, 0x19e0220, 0x19e0070, 0x1, 0x0, 0x31},
{0x19e0220, 0x19e01f0, 0x19e0250, 0x0, 0x10000, 0x0, 0x31},
{0x19e0250, 0x19e0220, 0x19e0280, 0x19e00d0, 0x10000, 0x0, 0x31},
{0x19e0280, 0x19e0250, 0x19e02b0, 0x0, 0x10000, 0x0, 0x31},
{0x19e02b0, 0x19e0280, 0x19e02e0, 0x19e0130, 0x0, 0x0, 0x31},
{0x19e02e0, 0x19e02b0, 0x19e0310, 0x0, 0x10000, 0x0, 0x31},

这个二维数组被解释为第一位是节点,第二三四位是l,r,t。第5位是判断位,先给出c++写的脚本:

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include<iostream>
#include<cstdio>
#include<map>
#include<queue>
#include<String>
using namespace std;
const int N=100005;
long long a[1000][10]={
{0x19df8f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31},
{0x19df920, 0x0, 0x19df950, 0x19dfaa0, 0x1, 0x0, 0x31},
{0x19df950, 0x19df920, 0x19df980, 0x0, 0x10000, 0x0, 0x31},
{0x19df980, 0x19df950, 0x19df9b0, 0x19dfb00, 0x10000, 0x0, 0x31},
{0x19df9b0, 0x19df980, 0x19df9e0, 0x0, 0x100, 0x0, 0x31},
{0x19df9e0, 0x19df9b0, 0x19dfa10, 0x19dfb60, 0x10001, 0x0, 0x31},
{0x19dfa10, 0x19df9e0, 0x19dfa40, 0x0, 0x10000, 0x0, 0x31},
{0x19dfa40, 0x19dfa10, 0x0, 0x19dfbc0, 0x100, 0x0, 0x31},
{0x19dfa70, 0x0, 0x19dfaa0, 0x19dfc50, 0x1, 0x0, 0x31},
{0x19dfaa0, 0x19dfa70, 0x19dfad0, 0x19df920, 0x100, 0x0, 0x31},
{0x19dfad0, 0x19dfaa0, 0x19dfb00, 0x19dfcb0, 0x1, 0x0, 0x31},
{0x19dfb00, 0x19dfad0, 0x19dfb30, 0x19df980, 0x10000, 0x0, 0x31},
{0x19dfb30, 0x19dfb00, 0x19dfb60, 0x19dfd10, 0x10000, 0x0, 0x31},
{0x19dfb60, 0x19dfb30, 0x19dfb90, 0x19df9e0, 0x10000, 0x0, 0x31},
{0x19dfb90, 0x19dfb60, 0x19dfbc0, 0x19dfd70, 0x100, 0x0, 0x31},
{0x19dfbc0, 0x19dfb90, 0x19dfbf0, 0x19dfa40, 0x1, 0x0, 0x31},
{0x19dfbf0, 0x19dfbc0, 0x0, 0x19dfdd0, 0x100, 0x0, 0x31},
{0x19dfc20, 0x0, 0x19dfc50, 0x19dfe30, 0x101, 0x0, 0x31},
{0x19dfc50, 0x19dfc20, 0x19dfc80, 0x19dfa70, 0x1, 0x0, 0x31},
{0x19dfc80, 0x19dfc50, 0x19dfcb0, 0x19dfe90, 0x10000, 0x0, 0x31},
{0x19dfcb0, 0x19dfc80, 0x19dfce0, 0x19dfad0, 0x100, 0x0, 0x31},
{0x19dfce0, 0x19dfcb0, 0x19dfd10, 0x19dfef0, 0x1, 0x0, 0x31},
{0x19dfd10, 0x19dfce0, 0x19dfd40, 0x19dfb30, 0x10000, 0x0, 0x31},
{0x19dfd40, 0x19dfd10, 0x19dfd70, 0x19dff50, 0x100, 0x0, 0x31},
{0x19dfd70, 0x19dfd40, 0x19dfda0, 0x19dfb90, 0x1, 0x0, 0x31},
{0x19dfda0, 0x19dfd70, 0x19dfdd0, 0x19dffb0, 0x100, 0x0, 0x31},
{0x19dfdd0, 0x19dfda0, 0x19dfe00, 0x19dfbf0, 0x1, 0x0, 0x31},
{0x19dfe00, 0x19dfdd0, 0x0, 0x19e0010, 0x100, 0x0, 0x31},
{0x19dfe30, 0x0, 0x19dfe60, 0x19dfc20, 0x1, 0x0, 0x31},
{0x19dfe60, 0x19dfe30, 0x19dfe90, 0x19e0040, 0x0, 0x0, 0x31},
{0x19dfe90, 0x19dfe60, 0x19dfec0, 0x19dfc80, 0x10000, 0x0, 0x31},
{0x19dfec0, 0x19dfe90, 0x19dfef0, 0x19e00a0, 0x10100, 0x0, 0x31},
{0x19dfef0, 0x19dfec0, 0x19dff20, 0x19dfce0, 0x1, 0x0, 0x31},
{0x19dff20, 0x19dfef0, 0x19dff50, 0x19e0100, 0x0, 0x0, 0x31},
{0x19dff50, 0x19dff20, 0x19dff80, 0x19dfd40, 0x100, 0x0, 0x31},
{0x19dff80, 0x19dff50, 0x19dffb0, 0x19e0160, 0x101, 0x0, 0x31},
{0x19dffb0, 0x19dff80, 0x19dffe0, 0x19dfda0, 0x1, 0x0, 0x31},
{0x19dffe0, 0x19dffb0, 0x19e0010, 0x19e01c0, 0x0, 0x0, 0x31},
{0x19e0010, 0x19dffe0, 0x0, 0x19dfe00, 0x100, 0x0, 0x31},
{0x19e0040, 0x0, 0x19e0070, 0x19dfe60, 0x1, 0x0, 0x31},
{0x19e0070, 0x19e0040, 0x19e00a0, 0x19e01f0, 0x100, 0x0, 0x31},
{0x19e00a0, 0x19e0070, 0x19e00d0, 0x19dfec0, 0x10001, 0x0, 0x31},
{0x19e00d0, 0x19e00a0, 0x19e0100, 0x19e0250, 0x10000, 0x0, 0x31},
{0x19e0100, 0x19e00d0, 0x19e0130, 0x19dff20, 0x1000000, 0x0, 0x31},
{0x19e0130, 0x19e0100, 0x19e0160, 0x19e02b0, 0x0, 0x0, 0x31},
{0x19e0160, 0x19e0130, 0x19e0190, 0x19dff80, 0x0, 0x0, 0x31},
{0x19e0190, 0x19e0160, 0x19e01c0, 0x19e0310, 0x10000, 0x0, 0x31},
{0x19e01c0, 0x19e0190, 0x0, 0x19dffe0, 0x100, 0x0, 0x31},
{0x19e01f0, 0x0, 0x19e0220, 0x19e0070, 0x1, 0x0, 0x31},
{0x19e0220, 0x19e01f0, 0x19e0250, 0x0, 0x10000, 0x0, 0x31},
{0x19e0250, 0x19e0220, 0x19e0280, 0x19e00d0, 0x10000, 0x0, 0x31},
{0x19e0280, 0x19e0250, 0x19e02b0, 0x0, 0x10000, 0x0, 0x31},
{0x19e02b0, 0x19e0280, 0x19e02e0, 0x19e0130, 0x0, 0x0, 0x31},
{0x19e02e0, 0x19e02b0, 0x19e0310, 0x0, 0x10000, 0x0, 0x31}};


int n=54,h[N],cnt,tot,st,ed,pr[N];
bool v[N];
map<long long,int>mp;
struct qwe
{
int ne,to;
string va;
}e[N<<2];
void add(int u,int v,string w)
{//cout<<u<<" "<<v<<" "<<w<<endl;
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
e[cnt].va=w;
h[u]=cnt;
}

int main()
{
for(int i=0;i<n;i++)
if(!mp[a[i][0]])
mp[a[i][0]]=++tot;

st=mp[0x19e0100];
ed=mp[0x19df9b0];
// cout<<st<<" "<<ed<<endl;

//lrt
for(int i=0;i<n;i++)
{
if(!(a[i][4]&0x1))//l
add(mp[a[i][0]],mp[a[i][1]],"l");

if(!(a[i][4]&0x100))//r
add(mp[a[i][0]],mp[a[i][2]],"r");

if(!(a[i][4]&0x10000))//t
add(mp[a[i][0]],mp[a[i][3]],"t");
}

queue<pair<int,string> >q;
v[st]=1;
q.push(make_pair(st,""));
while(!q.empty())
{
pair<int,string>u=q.front();
q.pop();
// cout<<u.first<<endl;
if(u.first==ed)
{
cout<<u.second<<endl;
//return 0;
}

for(int i=h[u.first];i;i=e[i].ne)
if(!v[e[i].to])
{
v[e[i].to]=1;
q.push(make_pair(e[i].to,u.second+e[i].va));
}
}
return 0;
}

看别人的wp发现还能用pwntools来搞,学习一下

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
from pwn import *
cmds = ['r','l','t']

def f(cmd_list):
n=0
try:
p = process('./maze')
p.recvuntil('> ')
for i in cmd_list:
p.sendline(i)
rev = p.recvuntil(' ')
n += 1
print(rev)
p.close()
return n
except:
return n
def ff(cmd_list,f1):
cmds = ['r','l','t','x']
for i in cmds:
c = [k for k in cmd_list]
c.append(i)
#print(c)
#print(cmd_list)
if f(c) == len(c):
c = ff(c,f1)
f1.write(str(c))
f1.write('\n')
print(c)
return c
if __name__ == "__main__":
f1= open('1.txt','w')
cmd_list=[]
ff(cmd_list,f1)
f1.close()



respect,很牛的方法,这个方法不需要idapython导出数据,直接程序里进行dfs跑。

HWS的一道逆向

re1

是一道魔改的tea,不过魔改的力度属实有点大。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rcx
__int64 v4; // rdx
__int128 v6[2]; // [rsp+20h] [rbp-38h] BYREF
char v7; // [rsp+40h] [rbp-18h]

memset(v6, 0, sizeof(v6));
v7 = 0;
sub_140001020("I prefer TeaProPlus! can you give me this?\n");
sub_140001020("TeaProPlus code:");
sub_140001080("%32s");
sub_1400010E0(v3, v6);
v4 = 0i64;
while ( *((_BYTE *)v6 + v4) == byte_1400032F0[v4] )
{
if ( (unsigned __int64)++v4 >= 0x20 )
{
sub_140001020("Oh yeah! Good code! flag{(your input)}\n");
return 0;
}
}
puts("oh NO!I want to drink TeaProPlus");
return -1;
}

直接看sub_1400010E0函数:

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
__int64 __fastcall sub_1400010E0(__int64 a1, unsigned int *a2)
{
unsigned int v2; // er9
unsigned int v3; // edi
unsigned int v4; // ebp
unsigned int v5; // esi
unsigned int v6; // er14
unsigned int v7; // er15
unsigned int v8; // er12
unsigned int v9; // er13
_DWORD *v10; // r11
_DWORD *v11; // r10
__int64 v12; // rbx
_DWORD *v13; // r9
__int64 result; // rax
bool v15; // zf
unsigned int v16; // [rsp+40h] [rbp+8h]
int v17; // [rsp+48h] [rbp+10h]
unsigned int v18; // [rsp+50h] [rbp+18h]

v2 = a2[7];
v3 = 0;
v4 = a2[1];
v5 = *a2;
v6 = a2[2];
v7 = a2[3];
v8 = a2[4];
v9 = a2[5];
v16 = a2[6];
v18 = v2;
v17 = 12;
do
{
v3 -= 1640531527;
v10 = &dword_140004038[(v3 >> 2) & 3];
v5 += ((v3 ^ v4) + (*v10 ^ v2)) ^ (((16 * v2) ^ (v4 >> 3)) + ((v2 >> 5) ^ (4 * v4)));
*a2 = v5;
v11 = &dword_140004038[(v3 >> 2) & 3 ^ 1i64];
v4 += ((*v11 ^ v5) + (v3 ^ v6)) ^ (((16 * v5) ^ (v6 >> 3)) + ((v5 >> 5) ^ (4 * v6)));
a2[1] = v4;
v12 = (v3 >> 2) & 3 ^ 3i64;
v13 = &dword_140004038[(v3 >> 2) & 3 ^ 2i64];
v6 += ((v3 ^ v7) + (*v13 ^ v4)) ^ (((16 * v4) ^ (v7 >> 3)) + ((v4 >> 5) ^ (4 * v7)));
a2[2] = v6;
v7 += ((v3 ^ v8) + (dword_140004038[v12] ^ v6)) ^ (((16 * v6) ^ (v8 >> 3)) + ((v6 >> 5) ^ (4 * v8)));
a2[3] = v7;
v8 += ((v3 ^ v9) + (*v10 ^ v7)) ^ (((16 * v7) ^ (v9 >> 3)) + ((v7 >> 5) ^ (4 * v9)));
a2[4] = v8;
v9 += ((*v11 ^ v8) + (v3 ^ v16)) ^ (((16 * v8) ^ (v16 >> 3)) + ((v8 >> 5) ^ (4 * v16)));
a2[5] = v9;
LODWORD(v10) = (((v3 ^ v18) + (*v13 ^ v9)) ^ (((16 * v9) ^ (v18 >> 3)) + ((v9 >> 5) ^ (4 * v18)))) + v16;
a2[6] = (unsigned int)v10;
v16 = (unsigned int)v10;
result = v3 ^ v5;
v18 += (result + (dword_140004038[v12] ^ (unsigned int)v10)) ^ (((16 * (_DWORD)v10) ^ (v5 >> 3))
+ (((unsigned int)v10 >> 5) ^ (4 * v5)));
v15 = v17-- == 1;
v2 = v18;
a2[7] = v18;
}
while ( !v15 );
return result;
}

发现比较恶心,魔改的有点魔鬼,所以先进行恢复加密

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
#include <stdio.h>
#include <stdint.h>


//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1],v2=v[2],v3=v[3],v4=v[4],v5=v[5],v6=v[6],v7=v[7], sum=0x9E3779B9*12, i; /* set up */
uint32_t delta=0x9E3779B9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<12; i++) {
v7-=((sum^v0)+(k[(sum>>2)&3^3]^v6))^(((v6<<4)^(v0>>3))+((v6>>5)^(v0<<2)));
v6-=((sum^v7)+(k[(sum>>2)&3^2]^v5))^(((v5<<4)^(v7>>3))+((v5>>5)^(v7<<2)));
v5-=((sum^v6)+(k[(sum>>2)&3^1]^v4))^(((v4<<4)^(v6>>3))+((v4>>5)^(v6<<2)));
v4-=((sum^v5)+(k[(sum>>2)&3]^v3))^(((v3<<4)^(v5>>3))+((v3>>5)^(v5<<2)));
v3-=((sum^v4)+(k[(sum>>2)&3^3]^v2))^(((v2<<4)^(v4>>3))+((v2>>5)^(v4<<2)));
v2-=((sum^v3)+(k[(sum>>2)&3^2]^v1))^(((v1<<4)^(v3>>3))+((v1>>5)^(v3<<2))); /* basic cycle start */
v1-=((k[(sum>>2)&3^1]^v0)+(sum^v2))^(((v0<<4)^(v2>>3))+((v0>>5)^(v2<<2)));
v0-=((sum^v1)+(k[(sum>>2)&3]^v7))^(((v7<<4)^(v1>>3))+((v7>>5)^(v1<<2)));
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;v[2]=v2;v[3]=v3;v[4]=v4;v[5]=v5;v[6]=v6;v[7]=v7;
}

void encrypt(uint32_t* v, uint32_t* k){
uint32_t v0=v[0], v1=v[1],v2=v[2],v3=v[3],v4=v[4],v5=v[5],v6=v[6],v7=v[7], sum=0, i; /* set up */
uint32_t delta=0x9E3779B9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<12; i++) {
sum += delta;
v0+=((sum^v1)+(k[(sum>>2)&3]^v7))^(((v7<<4)^(v1>>3))+((v7>>5)^(v1<<2)));
v1+=((k[(sum>>2)&3^1]^v0)+(sum^v2))^(((v0<<4)^(v2>>3))+((v0>>5)^(v2<<2)));
v2+=((sum^v3)+(k[(sum>>2)&3^2]^v1))^(((v1<<4)^(v3>>3))+((v1>>5)^(v3<<2)));
v3+=((sum^v4)+(k[(sum>>2)&3^3]^v2))^(((v2<<4)^(v4>>3))+((v2>>5)^(v4<<2)));
v4+=((sum^v5)+(k[(sum>>2)&3]^v3))^(((v3<<4)^(v5>>3))+((v3>>5)^(v5<<2)));
v5+=((sum^v6)+(k[(sum>>2)&3^1]^v4))^(((v4<<4)^(v6>>3))+((v4>>5)^(v6<<2)));
v6+=((sum^v7)+(k[(sum>>2)&3^2]^v5))^(((v5<<4)^(v7>>3))+((v5>>5)^(v7<<2)));
v7+=((sum^v0)+(k[(sum>>2)&3^3]^v6))^(((v6<<4)^(v0>>3))+((v6>>5)^(v0<<2)));
} /* end cycle */
v[0]=v0; v[1]=v1;v[2]=v2;v[3]=v3;v[4]=v4;v[5]=v5;v[6]=v6;v[7]=v7;
}

int main()
{
//测试
//uint32_t v[8]={0x31313131,0x31313131,0x31313131,0x31313131,0x31313131,0x31313131,0x31313131,0x31313131},k[4]={0x1234,0x2345,0x4567,0x6789};
uint32_t v[8]={0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9},k[4]={0x1234,0x2345,0x4567,0x6789};
//encrypt(v, k);
//printf("encode:%x %x %x %x %x %x %x %x\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
decrypt(v, k);
printf("decode:%x %x %x %x %x %x %x %x\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);

return 0;

}

进行恢复加密过后,逆序写解密就行