DASCTF2024暑期挑战赛

RE

BabyAndroid

拿到了一个apk文件,和一段流量文件,先去jadx把apk反编译然后搜索流量的域名(yuanshen.com)

找到关键的加密函数

image-20240721115349194

理一下加密逻辑,收首先从Sex.jpg中加载了一个类,先去看看怎么加载的

image-20240721115455814

找到loadData函数

image-20240721115521192

发现是通过rc4解密得到的,并且给了解密的密钥,用大厨去解密一下

image-20240721115618237

得到了dex文件,用jadx再去反编译一下,简单介绍一下dex的文件
dex(Dalvik Executable)是Android平台源代码文件(java,kotlin)经过编译、重构、重排、压缩、混淆后的字节码文件,是对传统的class 文件再处理。

image-20240721115823950

得到了加密的函数,我们再回到apk看逻辑

image-20240721115914294

发现在加密之前还做了对数据的处理操作,我们仅需追踪

image-20240721115942975

发现这样的一个函数,我们判断是用来.so文件里的加密的操作,将apk直接当成zip进行解压缩得到.so文件,放入ida7.7x64进行解密

image-20240721120038494

找到了加密的函数,发现是(DCT)加密,所以我们加密的思路已经理清了,首先去aes解密,再去DCT解密

aes解密脚本

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
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class Decrypt {
private static final String KEY = "DSACTF";

private static byte[] customHash(String input) {
byte[] keyBytes = new byte[16];
int[] temp = new int[16];
for (int i = 0; i < input.length(); i++) {
int charVal = input.charAt(i);
for (int j = 0; j < 16; j++) {

temp[j] = ((temp[j] * 31) + charVal) % 251;
}
}
for (int i2 = 0; i2 < 16; i2++) {
keyBytes[i2] = (byte) (temp[i2] % 256);
}
return keyBytes;
}

public static String decrypt(String encryptedData) throws Exception {
byte[] keyBytes = customHash(KEY);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

// 解码 Base64 编码的密文
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);

// 执行解密
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

// 返回解密后的字符串
return new String(decryptedBytes, "UTF-8");
}

public static void main(String[] args) {
try {
String encryptedData = "TwMkYUkg4bYsY0hL99ggYWnVjWyXQrWAdNmToB0eBXbS6wBzL6ktorjNWI9VOroTU4HgIUYyzGLpcHzd1zNGT+bFZZI7IoxJwpcgXfdwW1LSmiNSP+PuSUsqAzNclF1nJ07b4tYyLWg0zTypbzWsLhOIM+6uci3RFZLREUCALafi01M8mS+KMNxX1Pyn8mSP+KKKjQ5S5fasHRSn+L9qBFws0mWavpfI0QEiMgarxv0iGhYU8cfgonWyL70RvoXET5VUDP1vfYWIBLzzzaAqLC0OiMtUK3TTATSU7yijdgXm18OKMcGIke/NZIM6Sr5fL3t6psDOOkw2C/5uYrJVPn+D6U9KTL64bgREppDqMOvhvbhtuf/S3ASW/+rhtPMtoaD8FxDg0wWSLZA53fQfNA=="; // 替换为你的密文
String decryptedData = decrypt(encryptedData);
System.out.println("Decrypted Data: " + decryptedData);
} catch (Exception e) {
e.printStackTrace();
}
}
}

image-20240721120150617

DCT解密脚本

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
import numpy as np
import math


# 逆DCT变换函数
def inverse_dct(dct_coefficients):
N = len(dct_coefficients)
output = np.zeros(N)

for i in range(N):
sum_val = 0.0
for j in range(N):
if j == 0:
scale = math.sqrt(1.0 / N)
else:
scale = math.sqrt(2.0 / N)
sum_val += scale * dct_coefficients[j] * math.cos(((2 * i + 1) * j * math.pi) / (2 * N))
output[i] = sum_val

return output


# 加密的DCT系数
dct_coefficients = [458.853181, -18.325492, -18.251911, -2.097520, -21.198660, -22.304648, 21.103162, -5.786284,
-15.248906, 15.329286, 16.919499, -19.669045, 30.928253, -37.588034, -16.593954, -5.505211,
3.014744, 6.553616, 31.131491, 16.472500, 6.802400, -78.278577, 15.280099, 3.893073, 56.493581,
-34.576344, 30.146729, 4.445671, 6.732204]

# 使用逆DCT变换解密
decrypted_data = inverse_dct(dct_coefficients)

# 四舍五入为整数
decrypted_data_rounded = np.round(decrypted_data).astype(int)
cipher=np.ndarray.tolist(decrypted_data_rounded)
#
# print("Decrypted data (rounded):", decrypted_data_rounded)
flag=""
for i in range(len(cipher)):
flag+=chr(cipher[i])
print(flag)

image-20240721120214162

Dossnake

先用ida看一下exe的汇编语言,发现是dos操作系统的exe文件可能是位的,ida32解密不了,但是我们找到了关键的加密逻辑

image-20240721120440079

发现就是对密文的循环异或,shift+f12找到密文

image-20240721120519221

直接上脚本

1
2
3
4
5
6
7
8
cipher=[0x3F, 0x09, 0x63, 0x34, 0x32, 0x13, 0x2A, 0x2F, 0x2A, 0x37,
0x3C, 0x23, 0x00, 0x2E, 0x20, 0x10, 0x3A, 0x27, 0x2F, 0x24,
0x3A, 0x30, 0x75, 0x67, 0x65, 0x3C]
key="DASCTF"
flag=""
for i in range(len(cipher)):
flag=flag+chr(cipher[i]^ord(key[i%len(key)]))
print(flag)

image-20240721120549447

MISC

png-master

首先打开下发的附件png文件,发现最后多出来信息

image-20240727114957237

去b64解密一下,发现第一部分的flag

image-20240727115032094

flag1:DASCTF{2fd9e9ff-e27

lsb隐写

image-20240727115257576

得到第二部分的flag

d-5405-c5f5-

image-20240727115345388

发现倒数第二块idat块还没满65536就有下一个idat块,看起来不正常,比赛的时候想着把不正常的idat块删了但是从没想过只留下不正常的。只留下倒数第二块idat看一下,进行宽高爆破

image-20240727120058865

爆破发现500x500是正确的

三部分拼起来DASCTF{2fd9e9ff-e27d-5405-c5f5-a19131f86216}


DASCTF2024暑期挑战赛
http://www.qetx.top/posts/15798/
作者
Qetx.Jul.27
发布于
2024年7月21日
许可协议