前言
证书校验
在许多业务非常聚焦比如行业应用、银行、公共交通、游戏等行业,C/S 架构中服务器高度集中,对应用的版本控制非常严格,这时候就会在服务器上部署对 app 内置证书的校验代码。
抓包出现如下提示时,我们确定出此 APP 为服务器校验 app 客户端证书


对于此类 APP 抓包而言通常需要完成两项内容:
- 找到证书密码
- 安装证书
在这里不进行探讨,今天的目的是使用 Objection 来 hook 进行自吐抓包,绕过证书检测。
OkHttp 介绍
OkHttp 是一款优秀的网络请求框架,针对于传输层的一种封装,基于 socket 通信
OkHttp 有 2.0 版本和 3.0 的版本,目前常用的是 OkHttp3
准备阶段
如果我们要进行 hook 就要明确,android 是如何进行
新建一个 Android 工程 引入 Okhttp 这个库


再 AndroidMainFest.xml 中添加网络权限,并再 Gradle 中引入 okhttp 这个库


打开 MainActivity 编写以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package cn.mineseb.okhttp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log; import android.view.View; import android.widget.*;
import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;
import java.io.IOException;
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
Button button; TextView textView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
button = findViewById(R.id.button2); textView = findViewById(R.id.text); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { new Thread(new Runnable() { @Override public void run() { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build(); try { Log.i("codecat","okhttp start"); Response response = client.newCall(request).execute(); String s = response.body().string(); Log.i("codecat",s); Log.i("codecat","请求成功"); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }); } }
|
装入手机模拟器 点击 Button 查看 Log 成功发送

objection 进行 hook
我们知道 Objection 很强大,可以 hook 参数 返回值 调用栈,知道这一点我们就可以进行下一步,具体的使用方法可以看我之前的一篇博客

1 2 3
| android hooking list classes cd ~/.objection cat objection.log|grep okhttp
|

复制粘贴 一键 hook


发现关键方法 cn.mineseb.okhttp.MainActivity$1.onClick 进行 hook

查看到了栈、发送、返回值。
既然我们明白了原理,我们就可以使用框架 OkhttpLogger 进行一键 hook,同时这个框架也有一键反混淆。


修改 okhttp_poker 文件 再次进行 frida hook hook 成功

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| [Pixel 3::cn.mineseb.okhttp ]-> ........... hookRealCall : okhttp3.internal.connection.RealCall
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── | URL: https://www.httpbin.org/get?a=1&b=2 | | Method: GET | | Request Headers: 0 | no headers | |--> END | | URL: https://www.httpbin.org/get?a=1&b=2 | | Status Code: 200 / | | Response Headers: 6 | ┌─date: Thu, 16 Jun 2022 07:18:42 GMT | ┌─content-type: application/json | ┌─content-length: 314 | ┌─server: gunicorn/19.9.0 | ┌─access-control-allow-origin: * | └─access-control-allow-credentials: true | | Response Body: | { "args": { "a": "1", "b": "2" }, "headers": { "Accept-Encoding": "gzip", "Host": "www.httpbin.org", "User-Agent": "okht | tp/4.4.0", "X-Amzn-Trace-Id": "Root=1-62aad952-07cf18fe440c9c816716c120" }, "url": "https://www.httpbin.org/g | et?a=1&b=2" }
| |<-- END HTTP └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
总结
至此,介绍完了关于使用 Hook 抓包的通用流程。从这个案例分析可以发现,通过过滤网络框架的关键字的批量 hook 对快速定位 App 中收发数据包函数的帮助是非常巨大的,而这也正是不适用抓包工具而使用 hook 方式最大的原因。