网络协议抓取与分析(SSL Pinning突破)

1. 网络协议逆向基础

1.1 网络协议分析流程

graph TD  
    A[抓包环境配置] --> B[流量捕获]  
    B --> C{协议类型}  
    C -->|HTTP| D[明文解析]  
    C -->|HTTPS| E[SSL Pinning突破]  
    D --> F[参数逆向]  
    E --> F  
    F --> G[协议重放与模拟]  
1.1.1 关键分析目标
  • 协议结构:Header/Body格式、编码方式(JSON/Protobuf)

  • 认证机制:Token生成、签名算法、时间戳验证

  • 加密方式:AES密钥交换、RSA非对称加密


2. 抓包工具链配置

2.1 工具对比与选择

工具名称 优势 缺陷
Charles 可视化友好,支持SSL代理 无法绕过双向证书验证
Burp Suite 插件生态丰富,支持主动扫描 商业版功能受限
Fiddler Everywhere 跨平台,支持移动端 高级功能需订阅
Wireshark 底层流量捕获,支持所有协议 HTTPS解析依赖密钥导出

2.2 代理环境配置

Android设备代理设置

adb shell settings put global http_proxy 192.168.1.100:8888  
# 导入Charles证书到系统信任区  
adb push charles.pem /sdcard/  
adb shell mv /sdcard/charles.pem /system/etc/security/cacerts/  
adb shell chmod 644 /system/etc/security/cacerts/charles.pem  

3. SSL Pinning突破技术

3.1 证书锁定机制解析

常见实现方式

// OkHttp证书锁定示例  
CertificatePinner pinner = new CertificatePinner.Builder()  
    .add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAA=")  
    .build();  
OkHttpClient client = new OkHttpClient.Builder()  
    .certificatePinner(pinner)  
    .build();  

3.2 Frida动态Hook方案

绕过证书检查

Java.perform(() => {  
    const CertificatePinner = Java.use('okhttp3.CertificatePinner');  
    CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (hostname, pins) {  
        console.log(`[+] Bypass SSL Pinning for: ${hostname}`);  
        return; // 跳过校验逻辑  
    };  
});  

Xposed模块方案

XposedHelpers.findAndHookMethod(  
    "com.android.org.conscrypt.TrustManagerImpl",  
    lpparam.classLoader,  
    "checkTrusted",  
    X509Certificate[].class,  
    String.class,  
    String.class,  
    boolean.class,  
    new XC_MethodHook() {  
        @Override  
        protected void beforeHookedMethod(MethodHookParam param) {  
            param.setResult(null); // 强制信任所有证书  
        }  
    }  
);  

4. 协议逆向实战

4.1 加密参数定位

Hook网络库入口

// OkHttp拦截示例  
const OkHttpClient = Java.use('okhttp3.OkHttpClient');  
OkHttpClient.newCall.implementation = function (request) {  
    const url = request.url().toString();  
    const body = request.body().toString();  
    console.log(`请求URL: ${url}\n请求体: ${body}`);  
    return this.newCall(request);  
};  

4.2 算法逆向分析

AES密钥提取案例

const SecretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');  
SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (key, algo) {  
    console.log(`[AES密钥] 算法: ${algo}, 值: ${hexdump(key)}`);  
    return this.$init(key, algo);  
};  

5. 协议重放与模拟

5.1 Python请求模拟

自动化脚本模板

import requests  

def simulate_api(payload):  
    headers = {  
        "User-Agent": "Mozilla/5.0",  
        "X-Sign": generate_sign(payload)  # 逆向生成的签名算法  
    }  
    response = requests.post(  
        "https://api.target.com/v1/data",  
        json=payload,  
        headers=headers,  
        verify=False  # 忽略证书验证  
    )  
    return response.json()  

# 使用示例  
print(simulate_api({"user_id": 1001}))  

5.2 签名算法破解

Hook签名函数

Java.perform(() => {  
    const SignUtils = Java.use('com.target.app.SignUtils');  
    SignUtils.generateSign.implementation = function (data) {  
        const realSign = this.generateSign(data);  
        console.log(`原始数据: ${data} → 签名: ${realSign}`);  
        return "deadbeef";  // 返回固定签名绕过验证  
    };  
});  

6. 高级对抗技术

6.1 双向证书验证突破

客户端证书提取

const KeyStore = Java.use('java.security.KeyStore');  
KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (param) {  
    this.load(param);  
    const aliases = this.aliases();  
    while (aliases.hasMoreElements()) {  
        const alias = aliases.nextElement();  
        const cert = this.getCertificate(alias);  
        console.log(`[客户端证书] Alias: ${alias}\n${cert.toString()}`);  
    }  
};  

6.2 协议混淆对抗

流量伪装技术

# 在请求中插入随机噪声  
def add_noise(data):  
    noise = os.urandom(8).hex()  
    return {"data": data, "noise": noise}  

# 服务端需配合去除噪声  

7. 企业级实战案例

7.1 某电商APP协议逆向

步骤

  1. 配置抓包环境

    adb shell settings put global http_proxy 192.168.1.100:8888  
  2. 绕过SSL Pinning

    // Frida脚本注入  
    Java.perform(() => {  
        CertificatePinner.check.overload().implementation = function() {}  
    });  
  3. 定位加密参数

    • 使用Charles捕获/api/v3/order请求

    • 分析X-Sign头部生成逻辑

  4. 算法逆向

    • Hook发现使用HMAC-SHA256算法

    • 密钥通过SecureStorage.getKey()获取

  5. 模拟请求

    import hashlib, hmac  
    key = bytes.fromhex("deadbeef")  
    signature = hmac.new(key, payload.encode(), hashlib.sha256).hexdigest()  

7.2 即时通讯协议解密

技术要点

  • 使用Wireshark捕获原始TCP/UDP流量

  • 通过Frida提取TLS会话密钥

  • 配置Wireshark TLS解密:

    (Pre)-Master-Secret log: /path/to/sslkey.log  

8. 防护与检测方案

8.1 对抗Hook检测

检测Frida特征

public static boolean isFridaRunning() {  
    try {  
        new File("/data/local/tmp/frida-server").exists();  
        return true;  
    } catch (Exception e) {  
        return false;  
    }  
}  

8.2 动态协议保护

密钥轮换机制

public class KeyManager {  
    private static String getCurrentKey() {  
        // 每10分钟从服务端获取新密钥  
        return fetchFromServer(System.currentTimeMillis() / 600_000);  
    }  
}  

技术验证清单

  • 成功捕获并解析HTTPS流量

  • 绕过主流SSL Pinning实现

  • 提取并验证加密算法密钥

  • 实现协议重放攻击

  • 复现企业级协议逆向案例

本章实验需在授权测试环境进行,建议使用自建服务或开源API作为目标。禁止对未授权商业服务实施网络攻击,所有抓包操作需符合当地法律法规。

关于作者:

15年互联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我