2025数字中国创新大赛-移动互联网(APP)安全积分争夺赛决赛 Writeup
字数 1639 2025-08-30 06:50:35

2025数字中国创新大赛-移动互联网(APP)安全积分争夺赛决赛Writeup解析

1. crackme题目解析

关键函数分析

定位到关键函数verify_system_password,使用了CCCrypt函数进行AES加密。

AES加密分析

CCCrypt函数原型及相关枚举量:

  • 加密算法:AES
  • 操作模式:CBC模式(根据上下文推断)
  • 填充方式:PKCS7Padding(iOS默认)

解密方法

由于题目使用了标准AES加密,只需获取以下信息即可解密:

  1. 密钥(Key)
  2. 初始化向量(IV)
  3. 加密模式
  4. 填充方式

解密脚本示例(Python):

from Crypto.Cipher import AES
import base64

def decrypt_aes(ciphertext, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    plaintext = cipher.decrypt(ciphertext)
    return plaintext.rstrip(b'\0')  # 去除可能的填充

2. ezapk题目解析

流量包分析

从流量包中提取出APK文件,使用jadx反编译。

验证逻辑

验证逻辑在so文件中,分析发现是魔改的RC4算法。

RC4魔改点

  1. S数组初始化顺序:1→255→0(标准RC4是0→255)
  2. 输入处理:对连续相同字符进行类似长度编码的操作

解密方法

  1. 还原魔改的RC4初始化过程:
def rc4_init(key):
    S = list(range(256))
    # 魔改的初始化顺序
    j = 0
    for i in range(1, 256):  # 从1开始
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]
    # 最后处理0
    i = 0
    j = (j + S[i] + key[i % len(key)]) % 256
    S[i], S[j] = S[j], S[i]
    return S
  1. 处理输入的长度编码:
def decode_input(encoded):
    # 示例:flag{aa_bbb_cccc_dddd_hahahaha}
    # 需要根据实际动调结果编写解码逻辑
    pass

3. Task_get_vip题目解析

DEX释放逻辑

APK运行时会在/data/user/0/com.example.wyy/files/yongye.dex释放一个DEX文件。

验证逻辑

com.example.wyy.ui.play.PlayFragment中找到验证逻辑:

  1. 使用MP3文件的MD5前6位作为RC4密钥
  2. 对数据进行RC4解密

解题步骤

  1. 提取MP3文件
  2. 计算MD5哈希并取前6位作为密钥
  3. 使用标准RC4解密数据

示例代码:

import hashlib

def get_key(mp3_file):
    with open(mp3_file, 'rb') as f:
        data = f.read()
    md5 = hashlib.md5(data).hexdigest()
    return md5[:6].encode()

# 然后使用标准RC4解密

4. taskDB题目解析

数据库加密

使用android-database-sqlcipher组件加密SQLite数据库。

密码生成逻辑

密码为APK签名的MD5值,位于com.example.managepatients.utils.SecureDatabaseHelper类中。

解题步骤

  1. 提取APK签名
  2. 计算MD5得到数据库密码
  3. 使用密码打开SQLite数据库
  4. 修改用户密码为电话号码(需分析密码存储处理逻辑)

密码存储处理逻辑示例:

// 伪代码,需根据实际分析
String storedPassword = md5(phoneNumber + salt);

5. taskdecode题目解析

恶意Service分析

定位到com.example.weather.util.SsService,其中dVar2.o(encrypt)对外发送加密数据。

加密层次

  1. Java层:魔改的Chacha20
  2. Native层:魔改的RC4

Native层RC4魔改点

  1. S数组初始化过程执行两次
  2. j的计算加上了S[j]

解密脚本关键点:

# 魔改的RC4初始化
def modified_rc4_init(key):
    S = list(range(256))
    j = 0
    # 第一次初始化
    for i in range(256):
        j = (j + S[i] + S[j] + key[i % len(key)]) % 256  # 魔改点:加上了S[j]
        S[i], S[j] = S[j], S[i]
    # 第二次初始化
    for i in range(256):
        j = (j + S[i] + S[j] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]
    return S

6. SignalScope题目解析

整体流程

  1. MainActivity启动HttpServer
  2. 对POST数据调用Native的aaa方法加密后对比

Native层加密分析

  1. 获取APK签名
  2. 对签名进行两次SHA256和一次SHA1
  3. 使用结果生成RSA参数(p,q)
  4. 进行RSA加密
  5. 对p,q进行MD5得到AES的key和iv
  6. 使用AES加密数据

解密步骤

  1. 提取APK签名
  2. 计算SHA256和SHA1得到p,q
  3. 计算MD5得到AES密钥和IV
  4. 逆向RSA和AES加密过程

关键代码示例:

import hashlib
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA

# 1. 获取APK签名
signature = get_apk_signature()

# 2. 计算哈希
sha256_1 = hashlib.sha256(signature).digest()
sha256_2 = hashlib.sha256(sha256_1).digest()
sha1 = hashlib.sha1(signature).digest()

# 3. 生成RSA参数
p = int.from_bytes(sha256_1 + sha256_2, 'big')
q = int.from_bytes(sha1, 'big')

# 4. 生成AES参数
md5_p = hashlib.md5(str(p).encode()).digest()
md5_q = hashlib.md5(str(q).encode()).digest()
aes_key = md5_p[:16]
aes_iv = md5_q[:16]

# 5. AES解密
cipher = AES.new(aes_key, AES.MODE_CBC, aes_iv)
plaintext = cipher.decrypt(ciphertext)

通用解题技巧总结

  1. 加密算法识别

    • AES:通常有固定块大小(16字节),可能使用CBC/ECB模式
    • RC4:流密码,常见S盒初始化过程
    • RSA:涉及大素数操作,模幂运算
  2. 魔改算法分析

    • 对比标准算法实现
    • 关注初始化过程、S盒生成、密钥调度等关键点
    • 动态调试验证猜测
  3. 密钥来源分析

    • 硬编码字符串
    • 文件哈希(如APK签名、资源文件)
    • 设备信息(IMEI、MAC地址等)
  4. 动态分析技巧

    • 使用Frida hook加密函数
    • 使用IDA动态调试so文件
    • 监控文件操作(如释放的DEX文件)
  5. 数据流追踪

    • 从输入点追踪到加密点
    • 从加密点回溯密钥生成过程
    • 关注跨语言调用(Java-Native)的数据转换
2025数字中国创新大赛-移动互联网(APP)安全积分争夺赛决赛Writeup解析 1. crackme题目解析 关键函数分析 定位到关键函数 verify_system_password ,使用了 CCCrypt 函数进行AES加密。 AES加密分析 CCCrypt 函数原型及相关枚举量: 加密算法:AES 操作模式:CBC模式(根据上下文推断) 填充方式:PKCS7Padding(iOS默认) 解密方法 由于题目使用了标准AES加密,只需获取以下信息即可解密: 密钥(Key) 初始化向量(IV) 加密模式 填充方式 解密脚本示例(Python): 2. ezapk题目解析 流量包分析 从流量包中提取出APK文件,使用jadx反编译。 验证逻辑 验证逻辑在so文件中,分析发现是魔改的RC4算法。 RC4魔改点 S数组初始化顺序:1→255→0(标准RC4是0→255) 输入处理:对连续相同字符进行类似长度编码的操作 解密方法 还原魔改的RC4初始化过程: 处理输入的长度编码: 3. Task_ get_ vip题目解析 DEX释放逻辑 APK运行时会在 /data/user/0/com.example.wyy/files/yongye.dex 释放一个DEX文件。 验证逻辑 在 com.example.wyy.ui.play.PlayFragment 中找到验证逻辑: 使用MP3文件的MD5前6位作为RC4密钥 对数据进行RC4解密 解题步骤 提取MP3文件 计算MD5哈希并取前6位作为密钥 使用标准RC4解密数据 示例代码: 4. taskDB题目解析 数据库加密 使用 android-database-sqlcipher 组件加密SQLite数据库。 密码生成逻辑 密码为APK签名的MD5值,位于 com.example.managepatients.utils.SecureDatabaseHelper 类中。 解题步骤 提取APK签名 计算MD5得到数据库密码 使用密码打开SQLite数据库 修改用户密码为电话号码(需分析密码存储处理逻辑) 密码存储处理逻辑示例: 5. taskdecode题目解析 恶意Service分析 定位到 com.example.weather.util.SsService ,其中 dVar2.o(encrypt) 对外发送加密数据。 加密层次 Java层:魔改的Chacha20 Native层:魔改的RC4 Native层RC4魔改点 S数组初始化过程执行两次 j的计算加上了S[ j ] 解密脚本关键点: 6. SignalScope题目解析 整体流程 MainActivity启动HttpServer 对POST数据调用Native的 aaa 方法加密后对比 Native层加密分析 获取APK签名 对签名进行两次SHA256和一次SHA1 使用结果生成RSA参数(p,q) 进行RSA加密 对p,q进行MD5得到AES的key和iv 使用AES加密数据 解密步骤 提取APK签名 计算SHA256和SHA1得到p,q 计算MD5得到AES密钥和IV 逆向RSA和AES加密过程 关键代码示例: 通用解题技巧总结 加密算法识别 : AES:通常有固定块大小(16字节),可能使用CBC/ECB模式 RC4:流密码,常见S盒初始化过程 RSA:涉及大素数操作,模幂运算 魔改算法分析 : 对比标准算法实现 关注初始化过程、S盒生成、密钥调度等关键点 动态调试验证猜测 密钥来源分析 : 硬编码字符串 文件哈希(如APK签名、资源文件) 设备信息(IMEI、MAC地址等) 动态分析技巧 : 使用Frida hook加密函数 使用IDA动态调试so文件 监控文件操作(如释放的DEX文件) 数据流追踪 : 从输入点追踪到加密点 从加密点回溯密钥生成过程 关注跨语言调用(Java-Native)的数据转换