RE
BabyAndroid
拿到了一个apk文件,和一段流量文件,先去jadx把apk反编译然后搜索流量的域名(yuanshen.com)
找到关键的加密函数
理一下加密逻辑,收首先从Sex.jpg中加载了一个类,先去看看怎么加载的
找到loadData函数
发现是通过rc4解密得到的,并且给了解密的密钥,用大厨去解密一下
得到了dex文件,用jadx再去反编译一下,简单介绍一下dex的文件
dex(Dalvik Executable)是Android平台源代码文件(java,kotlin)经过编译、重构、重排、压缩、混淆后的字节码文件,是对传统的class 文件再处理。
得到了加密的函数,我们再回到apk看逻辑
发现在加密之前还做了对数据的处理操作,我们仅需追踪
发现这样的一个函数,我们判断是用来.so文件里的加密的操作,将apk直接当成zip进行解压缩得到.so文件,放入ida7.7x64进行解密
找到了加密的函数,发现是(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(); } } }
|
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
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_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]
decrypted_data = inverse_dct(dct_coefficients)
decrypted_data_rounded = np.round(decrypted_data).astype(int) cipher=np.ndarray.tolist(decrypted_data_rounded)
flag="" for i in range(len(cipher)): flag+=chr(cipher[i]) print(flag)
|
Dossnake
先用ida看一下exe的汇编语言,发现是dos操作系统的exe文件可能是位的,ida32解密不了,但是我们找到了关键的加密逻辑
发现就是对密文的循环异或,shift+f12找到密文
直接上脚本
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)
|
MISC
png-master
首先打开下发的附件png文件,发现最后多出来信息
去b64解密一下,发现第一部分的flag
flag1:DASCTF{2fd9e9ff-e27
lsb隐写
得到第二部分的flag
d-5405-c5f5-
发现倒数第二块idat块还没满65536就有下一个idat块,看起来不正常,比赛的时候想着把不正常的idat块删了但是从没想过只留下不正常的。只留下倒数第二块idat看一下,进行宽高爆破
爆破发现500x500是正确的
三部分拼起来DASCTF{2fd9e9ff-e27d-5405-c5f5-a19131f86216}