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协议逆向
步骤:
-
配置抓包环境:
adb shell settings put global http_proxy 192.168.1.100:8888
-
绕过SSL Pinning:
// Frida脚本注入 Java.perform(() => { CertificatePinner.check.overload().implementation = function() {} });
-
定位加密参数:
-
使用Charles捕获
/api/v3/order
请求 -
分析
X-Sign
头部生成逻辑
-
-
算法逆向:
-
Hook发现使用HMAC-SHA256算法
-
密钥通过
SecureStorage.getKey()
获取
-
-
模拟请求:
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等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我