CTF之多元线性方程
字数 1304 2025-08-22 18:37:22

CTF之多元线性方程解析与实战教学

1. 应用初步分析

1.1 应用结构分析

  • 应用入口:com.example.assemgogogo.MainActivity
  • 关键组件:
    • WebView组件(占据整个界面,可见)
    • 隐藏的EditText(输入框)
    • 隐藏的Button(检查按钮)
    • 隐藏的TextView(结果显示)

1.2 关键逻辑流程

  1. 加载本地库gogogoSystem.loadLibrary("gogogo")
  2. 调用sayHello方法获取URL
  3. WebView加载获取的URL
  4. 点击按钮时调用check_key方法验证输入

2. URL探索

2.1 关键方法定位

  • sayHello方法位于native库中
  • 使用IDA分析armeabi-v7a/libgogogo.so

2.2 IDC脚本解密URL

#include <idc.idc>
static main() {
    auto addr = 0x2d28;
    auto i;
    for(i = 0; i != 21; ++i) {
        Message("%c", Byte(addr + i) ^ 0x66);
    }
}

解密结果:http://127.0.0.1:8000

3. 服务端处理函数分析

3.1 JNI_OnLoad分析

  • 初始化时对data段中34291字节数据进行异或解密(key=0x67)
  • 创建线程监听socket连接
  • 收到连接后发送解密后的HTTP响应数据包

3.2 IDC脚本解密数据

#include <idc.idc>
static main() {
    auto addr = 0x4004;
    auto i = 34291;
    while(i) {
        --i;
        Message("%c", Byte(addr++) ^ 0x67);
    }
}

解密结果为HTML页面,包含WebAssembly代码

4. WebAssembly分析

4.1 关键逻辑

  1. 输入必须为32位长度
  2. 调用set_input_flag_len设置长度
  3. 调用set_input_flag逐个设置字符
  4. 调用check_key验证输入

4.2 提取WebAssembly二进制

import array, struct
hexstring = "\x00\x61\x73\x6D\x01\x00\x00\x00\x01\x1B\x05\x60\x00\x00\x60\x04\x7F\x7F\x7F\x7F\x01\x7F\x60\x02\x7F\x7F\x01\x7F\x60\x01\x7F\x01\x7F\x60\x00\x01\x7F...\x6C\x61\x67\x0A\x12\x73\x65\x74\x5F\x69\x6E\x70\x75\x74\x5F\x66\x6C\x61\x67\x5F\x6C\x65\x6E\x0B\x09\x63\x68\x65\x63\x6B\x5F\x6B\x65\x79\x0C\x03\x78\x78\x78"
f = open('data.bin', 'wb')
f.write(hexstring)
f.close()

4.3 转换为C代码

使用wasm2c工具:

wasm2c.exe data.bin -o test.c

4.4 编译为可分析对象

gcc -c test.c -o test.o

5. 核心验证逻辑分析

5.1 双重加密流程

  1. 第一重加密:对输入字符进行异或处理
  2. 第二重验证:32元线性方程组验证

5.2 32元线性方程组解法

使用Z3求解器解决:

from z3 import *

# 定义32个变量
v5 = Int('m53')
v6 = Int('m52')
v7 = Int('m51')
v8 = Int('m50')
[...省略部分变量定义...]
v36 = Int('m54')

# 创建求解器
s = Solver()

# 添加方程约束
s.add(And(
    45*v5 + 248*v6 + 20*v7 + 67*v8 + 90*v9 + 135*v10 + 106*v11 + 112*v12 + 40*v13 + 231*v14 + 153*v15 + 233*v16 + 19*v17 + 188*v18 + 232*v19 + 127*v20 + 15*v21 + 67*v22 + 50*v23 + 161*v24 + 103*v25 + 144*v26 + 81*v27 + 126*v28 + 240*v29 + 124*v30 + 194*v31 + 92*v32 + 108*v33 + 111*v34 + 174*v35 + 48*v36 == 359512,
    [...省略其他方程...]
    244*v5 + 196*v6 + 30*v7 + 100*v8 + 168*v9 + 7*v10 + 249*v11 + 84*v12 + 252*v13 + 171*v14 + 210*v15 + 206*v16 + 108*v17 + 153*v18 + 67*v19 + 189*v20 + 141*v21 + 239*v22 + 177*v23 + 10*v24 + 15*v25 + 164*v26 + 142*v27 + 97*v28 + 27*v29 + 173*v30 + 146*v31 + 133*v33 + 105*v34 + 75*(v32+v35) + 197*v36 == 393331
))

# 检查并输出结果
if s.check() == sat:
    m = s.model()
    [...处理结果...]
    print("".join(t))
else:
    print("failed")

5.3 第二重解密

unsigned char c[33] = "S0m3time_l1tt1e_c0de_1s_us3ful33";
unsigned char in[33] = {0};

in[0] = c[0] ^ 0x18;
in[1] = c[1] ^ 0x9;
in[2] = c[2] ^ 0x3;
[...省略部分异或操作...]
in[31] = c[31];

printf((const char*)in);

6. 关键知识点总结

  1. WebAssembly逆向

    • wasm二进制提取
    • wasm2c转换
    • 编译为可分析对象
  2. 多元线性方程求解

    • Z3求解器使用
    • 变量定义与约束添加
    • 结果提取与处理
  3. Native层分析

    • JNI_OnLoad分析
    • IDA静态分析
    • IDC脚本编写
  4. 加密算法分析

    • 异或加密识别
    • 多层加密处理
    • 加密顺序还原

7. 完整解题流程

  1. 分析Android应用结构,定位关键native方法
  2. 解密获取WebView加载的URL
  3. 分析JNI_OnLoad解密服务端响应
  4. 提取WebAssembly二进制代码
  5. 转换为C代码并分析核心验证逻辑
  6. 使用Z3求解32元线性方程组
  7. 对结果进行二次解密得到最终flag

8. 工具链

  1. 逆向工具

    • IDA Pro
    • Jadx
    • wasm2c
  2. 求解工具

    • Z3求解器
    • Python科学计算栈
  3. 开发工具

    • GCC编译器
    • IDC脚本环境

9. 扩展思考

  1. WebAssembly安全

    • 浏览器中执行native代码的安全隐患
    • 逆向保护与混淆技术
  2. 多元方程求解优化

    • 矩阵解法应用
    • 性能优化策略
  3. CTF出题思路

    • 多层加密设计
    • 混合语言编程挑战
    • 非标准加密方案
CTF之多元线性方程解析与实战教学 1. 应用初步分析 1.1 应用结构分析 应用入口: com.example.assemgogogo.MainActivity 关键组件: WebView组件(占据整个界面,可见) 隐藏的EditText(输入框) 隐藏的Button(检查按钮) 隐藏的TextView(结果显示) 1.2 关键逻辑流程 加载本地库 gogogo ( System.loadLibrary("gogogo") ) 调用 sayHello 方法获取URL WebView加载获取的URL 点击按钮时调用 check_key 方法验证输入 2. URL探索 2.1 关键方法定位 sayHello 方法位于native库中 使用IDA分析 armeabi-v7a/libgogogo.so 2.2 IDC脚本解密URL 解密结果: http://127.0.0.1:8000 3. 服务端处理函数分析 3.1 JNI_ OnLoad分析 初始化时对data段中34291字节数据进行异或解密(key=0x67) 创建线程监听socket连接 收到连接后发送解密后的HTTP响应数据包 3.2 IDC脚本解密数据 解密结果为HTML页面,包含WebAssembly代码 4. WebAssembly分析 4.1 关键逻辑 输入必须为32位长度 调用 set_input_flag_len 设置长度 调用 set_input_flag 逐个设置字符 调用 check_key 验证输入 4.2 提取WebAssembly二进制 4.3 转换为C代码 使用wasm2c工具: 4.4 编译为可分析对象 5. 核心验证逻辑分析 5.1 双重加密流程 第一重加密 :对输入字符进行异或处理 第二重验证 :32元线性方程组验证 5.2 32元线性方程组解法 使用Z3求解器解决: 5.3 第二重解密 6. 关键知识点总结 WebAssembly逆向 : wasm二进制提取 wasm2c转换 编译为可分析对象 多元线性方程求解 : Z3求解器使用 变量定义与约束添加 结果提取与处理 Native层分析 : JNI_ OnLoad分析 IDA静态分析 IDC脚本编写 加密算法分析 : 异或加密识别 多层加密处理 加密顺序还原 7. 完整解题流程 分析Android应用结构,定位关键native方法 解密获取WebView加载的URL 分析JNI_ OnLoad解密服务端响应 提取WebAssembly二进制代码 转换为C代码并分析核心验证逻辑 使用Z3求解32元线性方程组 对结果进行二次解密得到最终flag 8. 工具链 逆向工具 : IDA Pro Jadx wasm2c 求解工具 : Z3求解器 Python科学计算栈 开发工具 : GCC编译器 IDC脚本环境 9. 扩展思考 WebAssembly安全 : 浏览器中执行native代码的安全隐患 逆向保护与混淆技术 多元方程求解优化 : 矩阵解法应用 性能优化策略 CTF出题思路 : 多层加密设计 混合语言编程挑战 非标准加密方案