Android Studio のAndroid Emulatorの通信をBurpを使ってパケットキャプチャする

- 久しぶりにセットアップしたけどちょっとハマったので忘れないように個人的なメモ
- この先にBurpからSOCKSにつなげる必要があるのでBurp必須
- 使ってたエミューター端末が壊れたついでに更新した

# Burpにちょっと真面目に取り組んだのでたぶん正しいやり方
Android Studioは入ってるものとする

## エミュレータのインストールと起動
- API Level : 28
- ABI : x86_64
- Target : Android9.0 (Google APIs)
のPixel3aにした
- 名前は Pixel_3a_API_28

## コマンドラインから起動
Macだと

```
$ /Users/user/Library/Android/sdk/emulator/emulator -avd Pixel_3a_API_28 -writable-system
```

Windowsだと

```
C:\Users\user\AppData\Local\Android\Sdk\emulator\emulator.exe -avd Pixel_3a_API_28 -writable-system
```
rootになるにはここで起動するエミュレーターは 「Play Store」ではないものでないとダメ

## adbをダウンロード
https://developer.android.com/studio/releases/platform-tools

解凍して好きなところに置く

```
$ /置いたところ/platform-tools/adb 
```
で動く

## 証明書の書き込み
ネイティブアプリはAndroid APIのレベルが24以上の場合、システムレベルの証明書のみ信頼するので直接証明書を書き込む必要があるらしい。

自分のhttp://burpから証明書をダウンロード

Macだと

```
$ openssl x509 -noout -subject_hash_old -in cacert.der -inform DER
```
たぶん 9a5ba575.0 になると思う

```
$ openssl x509 -inform DER -in cacert.der -outform PEM > 9a5ba575.0
```

Windowsでもほぼ同じ（OpenSSLはダウンロードする必要がある）

```
"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" x509 -noout -subject_hash_old -in cacert.der -inform DER
```
たぶん 9a5ba575.0 になると思う

```
"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" x509 -inform DER -in cacert.der -outform PEM > 9a5ba575.0
```

## ADBで証明書のコピー デバイス確認（Macでもほぼ同じ）
```
C:\platform-tools\adb.exe devices
C:\platform-tools\adb.exe root
```

### rootになるにはここで起動するエミュレーターは 「Play Store」ではないものでないとダメらしい（再掲）。

```
C:\platform-tools\adb.exe remount
C:\platform-tools\adb.exe push 9a5ba575.0 /system/etc/security/cacerts/
C:\platform-tools\adb.exe shell
```

```
# chmod 644 /system/etc/security/cacerts/9a5ba575.0
C:\platform-tools\adb.exe reboot
```
rebootはしなくてもいいのではないか説もあるけどまあ念のため

## 注意点
* Play Store使えないからapkファイルは各自どこかから手に入れる必要がある
* 証明書の期限が長すぎるのでエラーになることがある
* 別hostのproxyにつなごうとしたけどつながらなかったのは謎

## burpだとブラウザ絡みで証明書の期限が長すぎるエラーが出ることがあるのでmitmproxyも入れる

### Macだと

```
$ brew install mitmproxy
$ mitmproxy --listen-port 8080
```
で起動

```
$ mitmweb
```
 でデフォルトだとポート8081にWebUIが開く

```
$ mitmweb --server --listen-port 8888
```
でポート8888でproxyを立ち上げてWebUIをデフォルトポート（8081）で開く

### Windowsだと
mithproxyはないのでmitmweb を開くとプロキシとWebUIが開くオプションも付けられる

```
"C:\Program Files (x86)\mitmproxy\bin\mitmweb.exe" -p 17888
```
アップストリームするには

```
"C:\Program Files (x86)\mitmproxy\bin\mitmweb.exe" -p 17888 --mode upstream:http://localhost:8080 --ssl-insecure
```


mitmproxyを通したブラウザから http://mitm.it/ にアクセスして証明書をダウンロード



## 証明書の導入

```  
$ openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.pem
```
```
"C:\Program Files\OpenSSL-Win64\bin\openssl.exe" x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.pem
```
c8750f0d
mitmproxy-ca-cert.pemをc8750f0d.0にファイル名を変更

後は以下の通り

```
/platform-tools/adb.exe root
/platform-tools/adb.exe remount
/platform-tools/adb.exe push c8750f0d.0 /system/etc/security/cacerts/
/platform-tools/adb.exe shell
# chmod 644 /system/etc/security/cacerts/c8750f0d.0
/platform-tools/adb.exe reboot
```

# 参考にした資料
http://otameshi61.hatenablog.com/entry/2017/12/03/151706
https://horosora.hatenablog.com/entry/2019/02/03/153211
https://developer.android.com/studio/run/emulator-commandline?hl=ja
https://developer.android.com/studio/releases/platform-tools

-----------
# 以下雑なやり方（アプリによっては通用しなかった）

## Android Emulator
- Android Studioをインストール
- ツール-> AVDマネージャを開く
- 仮想デバイスの作成をクリックしてインストール Pixel 2 Android 7.1.1 にした
- インストール終了
- エミュレーターを起動して メールアカウントを設定

## Burpのインストール
- Burpはすでに使ってるので省略
- 証明書を書き出してエミュレーターのメールアカウントに送る
- ワンチャンあるかと思ったけどやっぱり der 形式は認識されないので死亡
- 127.0.0.1:8888 で待ち受け

## OWASP ZAPのインストール
- ZAPをダウンロードしてインストール
- 127.0.0.1:8080 で待ち受け
- アップストリームの設定を行ってBurpに通す
- ツール -> オプション -> ネットワーク 外部プロキシサーバ使用にチェック アドレスを127.0.0.1 ポート8888 に設定
- 証明書を書き出してエミュレーターのメールアカウントに送る

## Android Emulator
- ZAPの証明書を受け取って「設定」-> 「セキュリティ」-> 「SDカードからインストール」からインストール ZAPの証明書ならインストールできるよやったね
- 「...」をクリック
- 「Settings」-> 「Proxy」タブを開く
- Manual proxy configuration の host nameを 127.0.0.1 Port numberを8080
- このままだと証明書エラーが出るので悩む
- エミュレータ端末のWifiの設定からプロキシの設定を行う
- 「設定」-> 「Wi-Fi」-> デフォルトで設定されてるAndroidWifiを選択 ->「ネットワークの変更」
- プロキシを「手動」プロキシのホスト名 10.0.2.2（母艦の仮想アドレスのはず）プロキシポート 8080 にすると証明書エラーが消える
- アプリで確認しても通信が証明書エラーにならずZAPでもBurpにもログが流れる
- Extended controlsのプロキシ設定なくてもいい？
- Pinning されてるアプリはもちろん見れない