August 2, 2022

DSCTF2022-FFunction & CatchMe

咕了好久.jpg

CatchMe

0x00 Daily Shell Check

无壳apk

image-20220801233830335

0x01 Find Check

拉近jadx发现check函数在native层

image-20220801234410709

直接解压找so文件

image-20220801234440330

0x02 Check Function

Shift + F12 看字符串看到个码表,发现个Base64加密,一路往上翻找到这里,发现了疑似比较密文的地方,尝试解密.jpg

image-20220801235317335

需要注意的是密文和AES的key都经过了异或混淆,在key和密文上按x找下可知道这个地方

image-20220801235740240

0x03 GetFlag

找到要异或的值,阅读AES源码发现是ECB模式,再得知这个base64是换了表的,解密即可

translate 方法示例

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
import base64
from Crypto.Cipher import AES

enflag = [0x4F, 0x1C, 0x36, 0x49, 0x09, 0x3A, 0x3F, 0x07, 0x4D, 0x3D, 0x22, 0x39, 0x00, 0x0A, 0x22, 0x25, 0x06, 0x09, 0x01, 0x20, 0x4A, 0x1B, 0x51, 0x51]
key = [0x24, 0x3C, 0x3D, 0x37, 0x36, 0x21, 0x35, 0x26, 0x3F, 0x37, 0x32, 0x2A, 0x72, 0x72, 0x72, 0x72]

for i in range(len(enflag)):
enflag[i] ^= 0x6C

for i in range(len(key)):
key[i] ^= 0x53

# print(bytes(enflag))
# print(bytes(key))
# b'#pZ%eVSk!QNUlfNIjemL&w=='
# b'wonderfulday!!!!'

now_table = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()+/"
ori_table = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

dec_str = base64.b64decode(bytes.translate(bytes(enflag), bytes.maketrans(now_table, ori_table)))

cipher = AES.new(bytes(key), AES.MODE_ECB)
flag = cipher.decrypt(bytes(dec_str))

print(flag)

GetFlag!

image-20220802001319357

FFunction

0x00 Daily Shell Check

无壳64位,不过这架构…梦回DAS五月赛

image-20220802002637888

0x01 f

主程序无思路,直接找dll,于是在f_function发现函数f

image-20220802002931223

一眼丁真TEA,正常程序能这样写吗,肯定是主程序调用dll进行密文检查

0x02 debugger f

x64dbg

先让程序跑起来再开启dll入口断点

image-20220802003219127

输入30个字符,再按Confirm,系统就会断到my_plugin.dll

image-20220802003849011

拉到最上面就是我们的加密函数了

IDA

设置debugger option,然后多按几下Confirm就进来了(雾

image-20220802005735116

0x03 Analyze

程序一进入是这样子的,很明显进行了base64加密,解密后发现我的输入成了这样

org_input: ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^

image-20220802015300495

接着分析程序

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
bool __fastcall f(_BYTE *input, const void *a2)
{
_BYTE *input1; // rbx
__int64 len; // rdi
__int64 div2_len; // r9
__int64 copy_len; // rsi
char *pre_input; // rdx
char *last_input; // r8
char v9; // al
char v10; // cl
_DWORD *v11; // rax
_DWORD *v12; // r14
char *data; // rdx
char t; // cl
int v15; // eax
__int64 i; // r10
unsigned int v0; // edx
int sum; // er9
unsigned int v1; // er8
__int64 round; // r11
bool v21; // r15

input1 = input;
len = -1i64;
do
++len;
while ( input[len] );

if ( (int)len % 8 )
return 0;

div2_len = (int)len / 2;
copy_len = (int)len;
if ( (int)len / 2 > 0 ) // 前后互换
{
pre_input = input;
last_input = &input[(int)len - 1];
do
{
v9 = *last_input--;
v10 = *pre_input;
*pre_input++ = v9;
last_input[1] = v10;
--div2_len;
}
while ( div2_len );
}

v11 = malloc(2i64 * (int)len);
v12 = v11;
if ( (int)len > 0 ) // 将高位和地位分开存储
{
data = (char *)v11;
do
{
data += 2;
t = *input1++ & 0xF0;
*(data - 2) = t;
*(data - 1) = *(input1 - 1) & 0xF;
--copy_len;
}
while ( copy_len );
}

v15 = 2 * (int)len / 8; // 10
if ( v15 > 0 )
{
for ( i = 0i64; i < v15; v12[2 * i++ + 1] = v1 )
{
v0 = v12[2 * i];
sum = 0;
v1 = v12[2 * i + 1];
round = 32i64;
do // v1和v0的位置换了,而且+变成了-
{
sum += 0x79B99E37;
v0 -= (sum + v1) ^ (key[0] + (v1 >> 5)) ^ (key[1] + 16 * v1);
v1 -= (sum + v0) ^ (key[2] + (v0 >> 5)) ^ (key[3] + 16 * v0);
--round;
}
while ( round );
v12[2 * i] = v0;
}
}

v21 = memcmp(v12, a2, 2 * (int)len) == 0;
free(v12);
return v21;
}

0x04 GetFlag

直接逆着来即可

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

static char Base64Code[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/', '='
};

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], i; /* set up */
uint32_t delta=0x79B99E37;
uint32_t sum = delta * 32; /* 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>>5) + k2) ^ (v0 + sum) ^ ((v0<<4) + k3);
v0 += ((v1>>5) + k0) ^ (v1 + sum) ^ ((v1<<4) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}

int main()
{
uint32_t v[]={0x5C15754C, 0xD1D781E7, 0x501BF173, 0xCB4DB222, 0x215D61F5, 0x3FCA9EE7, 0x7C76B5C7, 0xC7DD8CB9,
0x990D23FA, 0x0BAB1AD3, 0x8E12C932, 0xD307BAF2, 0xE52DD123, 0xFBB68F2C, 0xBDD853E3, 0x892E1E4E,
0x39DD66FA, 0x87FEEC65, 0x307C5E60, 0x340C6C00},k[4]={0xDEADBEEF, 0xBABEC0FE, 0xDEADC0DE, 0xFACEB00C};
int i, j;
unsigned char reflag[40] = { 0 };

for ( i = 0; i < 10; i++ )
{
decrypt(v + i * 2, k);
printf("%X, %X ", v[i * 2], v[i * 2 + 1]);
unsigned char * p = (unsigned char *)(v + i * 2);
for (j = 0; j < 4; j++)
{
reflag[i * 4 + j] = p[j * 2] + p[j * 2 + 1];
printf("%c, ", reflag[i * 4 + j]);
}
puts("\n");
}

for ( i = 0; i < 20; i++ )
{
unsigned char t = reflag[i];
reflag[i] = reflag[39 - i];
reflag[39 - i] = t;
}

for ( i = 0; i < 40; i++ )
{
for ( j = 0; j < 64; j++ )
{
if ( reflag[i] == Base64Code[j] )
{
reflag[i] = j;
// printf("0x%-2X, ", reflag[i]);
break;
}
}
}
unsigned char flag[30] = { 0 };
for ( i = 0, j = 0; j < 40; i += 3, j +=4 )
{
flag[i] = (reflag[j] << 2) | ((reflag[j + 1] & 0x30) >> 4);
flag[i + 1] = ((reflag[j + 1] & 0xF) << 4) | ((reflag[j + 2] & 0x3C) >> 2);
flag[i + 2] = ((reflag[j + 2] & 0x3) << 6) | reflag[j + 3] ;
// printf("%x %x %x ", flag[i], flag[i + 1], flag[i + 2]);
}

for ( i = 0; i < 15; i++ )
printf("%c", flag[i * 2]);
for ( i = 0; i < 15; i++ )
printf("%c", flag[29 - i * 2]);


return 0;
}
# flag{Emp0wer_F1utter_w1th_C!!}

GetFlag!

image-20220802015853213

Nothing

又是异常处理时间,不过这次设计了DWARF字节码 XD 看心情复现

DASCTF X SU
🍬
HFCTF2022
🍪

About this Post

This post is written by P.Z, licensed under CC BY-NC 4.0.