铁三决赛
PREFACE:最后是赛中做了两个 re,靠队友稳住取证拿了二等奖,渗透没做到,总的来说非常不爽~
这里除了 wp 还写点狡辩
# kernel
签到题,隔壁 pwn 手也能做
#define uint unsigned int | |
#include <stdint.h> | |
#include<stdio.h> | |
#include<bits/stdc++.h> | |
using namespace std; | |
void tea_enc(uint32_t *v, uint32_t *key) | |
{ | |
uint32_t l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9; | |
for (int32_t i = 1; i <= 36; ++i) | |
{ | |
l += (key[sum & 3] + sum) ^ (r + ((r >> 5) ^ (16 * r))); | |
sum += delta; | |
r += (key[(sum >> 11) & 3] + sum) ^ (l + ((l >> 5) ^ (16 * l))); | |
} | |
v[0] = l, v[1] = r; | |
} | |
void tea_dec(uint32_t *v, uint32_t *key) | |
{ | |
uint32_t l = v[0], r = v[1], sum = 0, delta = 0x61CEEEEF; | |
sum = - delta * 33; | |
for (int32_t i = 0; i < 33; ++i) | |
{ | |
r -= (key[(sum >> 11) & 3] + sum) ^ (l + ((l >> 6) ^ (8 * l))); | |
sum += 0x61CEEEEF; | |
l -= (key[sum & 3] + sum) ^ (r + ((r >> 6) ^ (4 * r))); | |
} | |
v[0] = l, v[1] = r; | |
} | |
int main(){ | |
uint32_t v[33]= {0x8CCAF011, 0x835A03B8, 0x6DCC9BAD, 0x0E671FA99, 0x0E6011F35, 0x0E5A56CC8, 0x0D4847CFA, 0x5D8E0B8E}; | |
uint32_t k[4]= {4660,14925,24175,43571}; | |
for (uint32_t i=0;i<8;i+=2){ | |
tea_dec(&v[i],k); | |
} | |
for (int32_t i=0;i<8;i++){ | |
printf("%x ",v[i]); | |
} | |
printf("\n"); | |
uint8_t *c = (uint8_t *)v; | |
for (int8_t i=0;i<32;i+=4){ | |
uint32_t tmp = 0; | |
tmp += c[i] << 24; | |
tmp += c[i+1] << 16; | |
tmp += c[i+2] << 8; | |
tmp += c[i+3]; | |
printf("%x ",tmp); | |
} | |
} |
# puzzle
硬调,赛中花了很多时间
首先梳理流程:
简单来说,输入 a 和 b 做中间操作,输入 - 则当前节点值做异或,然后存取下一个节点(链表)
这里的判断有大用,不能忽略:
这里会检查你的输入长度是否为 571,以及对链表依次检查:
链表检查:(这里 ida 识别废了,自己调汇编即可)
输入对了以后把输入做 sha256 来输出,这里没啥好说的
然后就是找规律了,要 1 如何把序列求出来
我们会发现,如果每个计算结果为奇数,那么它一定来源于 b
,否则来源为 a
那么我们就可以拿到脚本:
enc = [0x49, 0x53, 0x43, 0x43, 0x32, 0x30, 0x32, 0x34] | |
enc_tmp = enc[::-1] | |
# 初始值 sum = 1,输入 a sum *=2 输入 b sum = (sum-1) // 3 | |
# 现在有 sum_final 的值,需要求输入的 ab 序列 | |
for i in range(len(enc)): | |
init = ((enc_tmp[i] ^ 0x8d)-i) | |
h = '' | |
while (init != 1): | |
if (init % 2 == 1): | |
init*=3 | |
init+=1 | |
h += 'b' | |
# elif ((init * 3 + 1) % 2 == 0): | |
# h += 'b' | |
elif (init % 2 == 0): | |
init //= 2 | |
h += 'a' | |
h = h[::-1] | |
print(h,end='') | |
print('-',end='') |
赛中这里其实想了好久,还和队友讨论,确实心态很差,其实之前做过类似的,但一时想不起来了,队友提示是否与奇偶有关,遂出
然后这就是赛中出的唯二题目了…
下面复现以及抱怨一下之所以没出的原因:
# crazyaes
这题要你对个脑电波把这里的 EE
修成 PE
但赛中紧张了,一直尝试修了好几个地方都没搞对(中间那段看起来真的很脏字节!)
尝试使用工具的话,会发现缺少 PE
字段的情况下,工具都根本无法辨认这是一个 pe 文件,更别提辨认文件头的错误点,运行也运行不起来,真的有些…
修好可以运行以后,这里很明显就是一个 upx 壳,特征抹掉的不多,修回来 upx -d
即可,里面就送分了
#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]); | |
state[i * 4 + j] ^= 0xa1; | |
} | |
} | |
} | |
/****************************************************************************************************************/ | |
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]; | |
state[i * 4 + r] ^= 0x54; | |
} | |
} | |
} | |
/****************************************************************************************************************/ | |
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 */ | |
uint8_t v9[24] = {0,1,2,3,1,0,3,2,2,3,0,1,3,2,1,0}; | |
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); | |
for (int32_t m = 0; m < 4 * g_aes_nb[mode];m++){ | |
s[m] ^= v9[m]; | |
} | |
} | |
/* 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] ^= 0xa1; | |
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++) { | |
// state[i * 4 + j] ^= 0x54; | |
s[r] = s[r] ^ aes_mul(state[i * 4 + j] ^ 0x54, 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 */ | |
uint8_t v9[24] = {0,1,2,3,1,0,3,2,2,3,0,1,3,2,1,0}; | |
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--) { | |
for (int32_t m = 0; m < 4 * g_aes_nb[mode];m++){ | |
s[m] ^= v9[m]; | |
} | |
/* 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); | |
} | |
/****************************************************************************************************************/ | |
int main() | |
{ | |
// 数据 | |
uint8_t buf[] = { 0xB4,0x38,0x36,0x30,0x1E,0x68,0x48,0x57,0x51,1, 0xB7, 3, 0x9B, 0x98, 0xE3, 0x7E }; | |
// 密钥 | |
uint8_t key[] = {103,97,104,52,51,106,74,75,103,102,106,71,77,101,65,82}; | |
// 向量 | |
//uint8_t iv[] = {}; | |
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; | |
*/ | |
} | |
// uint8_t buf[] = {48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48}; | |
// uint8_t key[] = {103,97,104,52,51,106,74,75,103,102,106,71,77,101,65,82,128}; | |
// aes_encrypt(AES_CYPHER_128, buf, sizeof(buf), key);; | |
for (int i = 0; i < sizeof(buf); i++) | |
{ | |
printf("%c", buf[i] & 0xFF); | |
} | |
printf("\n"); | |
return 0; | |
} |
不是,你家 400 分的逆向核心考点是对脑电波修 PE 么!!!55555555555555555555555
更想吐槽的一题来了:
# yaodi
这题更是…
首先给了你一个 apk 一个 mumu 模拟器镜像一个 mumu 模拟器,首先赛前有说不能拿测试机,必须虚拟机,镜像里面有文件管理的工具
所以顺理成章的不就该认为,这个只是提供的一个环境么?
线下断网,不会用 mumu(需要手动找端口,adb devices 看不到模拟器的)我就直接用自己的 as 了
然后顺理成章看不懂题了,java 是没有调用解密的
那我们手动调用一下看看:
Java.perform(function() { | |
var MainActivity = Java.use('com.information.app1.MainActivity'); | |
MainActivity.decrypt.overload().implementation = function() { | |
this.decrypt(); | |
console.log('[*]dec happened'); | |
// console.log() | |
}; | |
MainActivity.showToast.overload().implementation = function() { | |
var result = this.showToast(); | |
var tried = this.decrypt(); | |
console.log(tried); | |
console.log('[-]no dec'); | |
return result; | |
}; | |
MainActivity.init.overload().implementation = function() { // 有 init 过,但是哪里调用了 dec 呢? | |
var result = this.init(); | |
console.log('[*]init'); | |
return result; | |
}; | |
}); |
更大的问题来了:
native 的 decrypt 这部分一看就是 rc4
这里拿最后两位做了一个校验位做检查:
好,密文呢?
密文呢?
密文呢?
赛后:mumu 模拟器里藏东西了~
接下来就是赛后的事情了…
首先你需要这样:
注意到:
发现:
拿出来看看:
import sqlite3 | |
conn = sqlite3.connect('information.db') | |
cursor = conn.cursor() | |
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") | |
tables = cursor.fetchall() | |
print("Tables in the database:") | |
for table in tables: | |
print(table[0]) | |
table_name = 'information' | |
cursor.execute(f"SELECT * FROM {table_name};") | |
rows = cursor.fetchall() | |
print(f"\nData in the table '{table_name}':") | |
for row in rows: | |
print(row) | |
cursor.close() | |
conn.close() |
数据库里面是:
那就是这个文件 wcmm5ukk 了
然后 rc4 解不出来,然后又是?