DASCTF 2024金秋十月赛ezAndroid 安卓加载lua
字数 756 2025-08-22 12:23:30
Android Lua脚本加密与解密实战教学
一、题目背景分析
-
文件结构
- APK解压后存在
assets/lua目录,内含加密的Lua脚本(如pz.lua) - 动态库
libluajava.so负责Lua脚本加载,关键函数:luaL_loadbuffer
- APK解压后存在
-
加密特征
- Assets中的Lua文件被加密,需通过逆向分析解密逻辑
- 使用魔改XTEA算法(含自定义常数和异或操作)
二、解密流程详解
-
提取加密脚本
# 从assets直接提取加密的pz.lua with open("pz.lua", 'rb') as f: encrypted_data = f.read() -
逆向解密算法
- 密钥生成函数
def key(t): t1 = t t2 = (0xFFFFFFFF80808081 * t1) >> 32 t3 = (t2 + t1) >> 7 t4 = 1 if (t2 + t1) < 0 else 0 return (t + t3 + t4) & 0xFF - 逐字节解密
def decrypt(s): out = bytearray(len(s)) out[0] = 27 # 固定首字节 t = 0 for i in range(1, len(s)): t += len(s) out[i] = s[i] ^ key(t) return bytes(out)
- 密钥生成函数
-
执行解密
decrypted_data = decrypt(encrypted_data) with open("pz_decrypted.lua", 'wb') as f: f.write(decrypted_data)
三、Lua脚本逆向分析
-
关键函数解析
- 填充函数
ddddddddddddd
确保输入长度为8的倍数,补\0function ddddddddddddd(str) return str .. string.rep("\0", 8 - #str % 8) end - 魔改XTEA加密
aijusbndbv- 使用动态生成的常数(如
114514的变形) - 38轮加密,最终异或
14和17
function aijusbndbv(v, k) local sum = 0 for i = 1, 38 do sum = (sum + delta) & 0xFFFFFFFF v[1] = (v[1] + (((v[2] << 4) ~ (v[2] >> 5)) + v[2] ~ sum + k[(sum & 3) + 1])) & 0xFFFFFFFF v[2] = (v[2] + (((v[1] << 4) ~ (v[1] >> 5)) + v[1] ~ sum + k[(sum >> 11 & 3) + 1])) & 0xFFFFFFFF end return {v[1] ~ 14, v[2] ~ 17} end - 使用动态生成的常数(如
- 填充函数
-
加密验证逻辑
- 输入格式:
flag{...} - 解密后数据与硬编码值
oianxasdavsdvasd比对
- 输入格式:
四、解密脚本开发(C语言)
#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t *v, uint32_t *k) {
uint32_t v0 = v[0] ^ 14, v1 = v[1] ^ 17;
uint32_t sum = 38 * 0x80E7D99B; // 2161537835 * 38
for (int i = 0; i < 38; i++) {
v1 -= (k[(sum >> 11) & 3] + sum) ^ (v0 + ((v0 >> 5) ^ (v0 << 4)));
v0 -= (k[sum & 3] + sum) ^ (v1 + ((v1 >> 5) ^ (v1 << 4)));
sum -= 0x80E7D99B;
}
v[0] = v0; v[1] = v1;
}
int main() {
uint32_t encrypted[] = {863918170, 366827450, 2944604520, ...};
uint32_t key[] = {5976, 40857, 3298229483, 1500946329};
for (int i = 0; i < 10; i += 2) {
decrypt(&encrypted[i], key);
printf("%08x%08x", encrypted[i], encrypted[i+1]);
}
// 输出拼接后得到flag
return 0;
}
五、关键知识点总结
-
Lua加密套路
- 常见于
luaL_loadbuffer拦截或assets文件加密 - 识别特征:首字节固定值、异或/加减操作、动态密钥生成
- 常见于
-
魔改算法技巧
- 修改XTEA的轮数(38轮)、delta值(0x80E7D99B)
- 最终异或操作(14/17)和自定义大端序处理
-
动态分析技巧
- 使用Frida Hook
luaL_loadbuffer获取解密后脚本 - IDA逆向
libluajava.so定位加密逻辑
- 使用Frida Hook
六、Flag获取
执行解密脚本后输出:
flag{7a5e-55e45-1671e-df3b7-cd7a1-6f1e-27fc}
注:实际操作时需注意字节序(大端序)和Lua与C的数据类型转换,建议配合Unluac工具反编译验证逻辑。