铁三决赛

PREFACE:最后是赛中做了两个 re,靠队友稳住取证拿了二等奖,渗透没做到,总的来说非常不爽~

这里除了 wp 还写点狡辩

# kernel

签到题,隔壁 pwn 手也能做

image-20240527092307307

#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

硬调,赛中花了很多时间

首先梳理流程:

image-20240527092553990

简单来说,输入 a 和 b 做中间操作,输入 - 则当前节点值做异或,然后存取下一个节点(链表)

这里的判断有大用,不能忽略:

image-20240527092659991

这里会检查你的输入长度是否为 571,以及对链表依次检查:

image-20240527092738932

链表检查:(这里 ida 识别废了,自己调汇编即可)

image-20240527092821621

输入对了以后把输入做 sha256 来输出,这里没啥好说的

然后就是找规律了,要 1 如何把序列求出来

我们会发现,如果每个计算结果为奇数,那么它一定来源于 b ,否则来源为 a

image-20240527093353197

那么我们就可以拿到脚本:

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

image-20240527093641126

但赛中紧张了,一直尝试修了好几个地方都没搞对(中间那段看起来真的很脏字节!)

尝试使用工具的话,会发现缺少 PE 字段的情况下,工具都根本无法辨认这是一个 pe 文件,更别提辨认文件头的错误点,运行也运行不起来,真的有些…

修好可以运行以后,这里很明显就是一个 upx 壳,特征抹掉的不多,修回来 upx -d 即可,里面就送分了

image-20240527093946987

#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 是没有调用解密的

image-20240527094434512

那我们手动调用一下看看:

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

image-20240527094600615

这里拿最后两位做了一个校验位做检查:

image-20240527094643532

好,密文呢?

密文呢?

密文呢?

赛后:mumu 模拟器里藏东西了~

接下来就是赛后的事情了…

首先你需要这样:

image-20240527095727002

注意到:

image-20240527095822416

发现:

image-20240527095858256

image-20240527095925815

拿出来看看:

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()

数据库里面是:

image-20240527100004208

那就是这个文件 wcmm5ukk 了

然后 rc4 解不出来,然后又是?