Android 抓包以及 mitmproxy
这篇文章介绍了如何使用 mitmproxy 抓取 Android Emulator 的包。

最佳实践

经过一段时间的研究,又有了新的看法。

准备以下两种工具:

  • mitmproxy
  • Android Emulator(MuMu, BlueStack …)

mitmproxy

mitmproxy最好使用pipx安装。因为mitmproxy运行在独立的venv中,使用pipx方便为mitmproxy安装额外的python包。

brew install pipx
pipx install mitmproxy

最好按照提示说明,使用pipx ensurepath修改环境变量。

这样我们就可以为mitmproxy安装额外的python包了。

pipx inject mitmproxy pycryptodome # 安装 pycryptodome 包,用于AES解码

将浏览器代理设置到8080端口,打开(mitm.it)[mitm.it]下载对应平台的证书。

Android Emulator

抓包之前有两个步骤:

  1. 设置手动代理
  2. 安装并信任自签名https证书

设置WiFi代理为主机8080端口:

Snipaste_2021-11-26_01-12-38

以下是简化的脚本1,先看看adb devices信息,是否已经连接。如果没有成功连接需要adb kill-server,再重试几次。或者参照后文2。 直接运行以下脚本./push.sh YOUR_CRT.crt

PEM_FILE_NAME=$1
echo "$PEM_FILE_NAME"
hash=$(openssl x509 -inform PEM -subject_hash_old -in $PEM_FILE_NAME | head -1)
OUT_FILE_NAME="$hash.0"

cp $PEM_FILE_NAME $OUT_FILE_NAME
openssl x509 -inform PEM -text -in $PEM_FILE_NAME -out /dev/null >> $OUT_FILE_NAME

echo "Saved to $OUT_FILE_NAME"
adb shell mount -o rw,remount,rw /system
adb push $OUT_FILE_NAME /system/etc/security/cacerts/
adb shell mount -o ro,remount,ro /system
adb reboot

如果模拟器正常重启的话应该就可以了。

抓包

运行mitmweb,通过web界面观察包的发送和接收。

123

mitmproxy 是一个非常强大的工具,其用法如恒河沙数,无不天花乱坠。官方文档提供的用例很值得仔细参阅,这里只介绍一个简单的例子。

ContentView是显示requestresponse负载的界面。有时需要查看的payload不是明文的jsonplain text,默认情况下会以raw格式显示。

content view

这样会很麻烦。

所以可以考虑通过插件增加一个ContentView的选项,让请求以我想要的方式显示。模仿addons-examples/#contentview,以挂载脚本的方式启动mitmweb -S decode.py

from mitmproxy import contentviews, flow
from mitmproxy import http
from mitmproxy.contentviews.json import format_json
from Crypto.Cipher import AES
import base64
import hashlib
import json
import random

class ViewAESDecode(contentviews.View):
    name = "AES decode"

    def __call__(
        self,
        data: bytes,
        *,
        content_type: Optional[str] = None,
        flow: Optional[flow.Flow] = None,
        http_message: Optional[http.Message] = None,
        **unknown_metadata,
    ):
        jsdata = decrypt(data)
        jsdata = json.loads(jsdata)
        return "AES decode", format_json(jsdata)

    def render_priority(
        self,
        data: bytes,
        *,
        content_type: Optional[str] = None,
        flow: Optional[flow.Flow] = None,
        http_message: Optional[http.Message] = None,
        **unknown_metadata,
    ):
        if 'what I want' in flow.request.host:
            return 10  # 出现的权重,为10的话会在最前面
        else:
            return 0

def decrypt(data):
   key = '1234567890123456'
   iv = '1234567890123456'
   mode = AES.MODE_CBC
   cryptor = AES.new(key, mode, iv)
   data = base64.b64decode(data)
   decrypted = cryptor.decrypt(data)
   return decrypted.decode('utf-8')


def load(l):
    contentviews.add(view)


def done():
    contentviews.remove(view)

结果如下: content view

ADB 无法连接的问题

打开USB调试。夜神的USB调试并不通过默认的5037 端口与adb客户端通信,可能是考虑多开也许超过16个客户端的官方限制。

一般情况下,只需以下步骤就能连接adb

# WSL ubuntu 18.04
wesley@WIN10:/mnt/c/Users/Vita/Desktop$ adb devices
List of devices attached

wesley@WIN10:/mnt/c/Users/Vita/Desktop$ adb connect 127.0.0.1:62001
connected to 127.0.0.1:62001
wesley@WIN10:/mnt/c/Users/Vita/Desktop$ adb devices
List of devices attached
127.0.0.1:62001 device

虚拟机比较多时就无效了,需要手动找到端口2

# Powershell
PS C:\Users\Vita> Get-Process | where name -like "Nox*"

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
   1037     184   177620      49000     161.20  28604   1 Nox
   2006     173  1046392      46020     251.53   4716   1 NoxVMHandle
   3058      16     6268      19040       0.67  27528   1 NoxVMSVC
   
PS C:\Users\Vita> Get-NetTcpConnection -OwningProcess 4716 -State Listen


LocalAddress    LocalPort RemoteAddress   RemotePort State   AppliedSetting
------------    --------- -------------   ---------- -----   --------------
127.0.0.1       64001     0.0.0.0         0          Listen
127.0.0.1       63001     0.0.0.0         0          Listen
127.0.0.1       62001     0.0.0.0         0          Listen
127.0.0.1       61001     0.0.0.0         0          Listen

依次尝试连接这些LocalPort,验证adb devices是否正常。


  1. pwlin, “Android : add cert to system store,” Gist, Mar. 07, 2016. https://gist.github.com/pwlin/8a0d01e6428b7a96e2eb (accessed Nov. 25, 2021). ↩︎

  2. Mateusz, “ADB can’t connect to Nox,” Stack Overflow, Jul. 06, 2018. https://stackoverflow.com/questions/51214825/adb-cant-connect-to-nox (accessed Nov. 25, 2021). ↩︎ ↩︎


最后修改于 2024-09-10