自宅Wi-Fiに接続してくるデバイスの調査

# 本記事の要約
株式会社 ONE COMPATHの並木です。
- 自宅のWi-Fiに見ず知らずのデバイスが勝手に接続してきました (と勘違いした) 
- 自宅のWi-Fiに勝手に接続してきたデバイスを特定しました
- 勝手に接続してきたデバイスがどんな通信をしているのか確認しました

## はじめに
先日、自宅のWi-Fiに突然見知らぬデバイスが接続をしてきました。
「第三者が勝手に自宅のWi-Fiに接続しているのでは」という恐怖に苛まれつつ、問題のデバイスを特定する迄の経緯を記事にさせて頂きます。
又、記事後半ではWi-Fiフレームのキャプチャから復号化迄の手順についてカロリー低めに記載をさせて頂きます。

## 事の始まり
自宅にてWi-Fiの検証をしていたある日、見知らぬデバイスが検証用AccessPoint(以下、検証用AP)に接続している事に気が付きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/b12e1b67-8b96-ad0a-b287-01fd3b022b11.png)

検証用APに接続する為にはパスフレーズ(WPA2-PSK)が必要です。
検証用APのパスフレーズを登録しているデバイスは自身のiPhoneのみであり、第三者にパスフレーズが漏洩していない限り(又は4way-handshakeをキャプチャされaircrack-ngやhashcatで解析されなければ)自身のiPhone以外、デバイスが検証用APに接続をするという事は出来ません。

:::note warn
パスフレーズが"password"や"12345678"のような酷い物の場合を除きます。
:::

inSSIDerというアプリケーションで確認すると問題のデバイスが検証用APと通信をしている様子が表示されます。

![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/a8a5ba00-e02e-2d07-fc88-85b1d3bc8523.png)

このデバイスは一体何者なのか、調査を開始しました。

## 調査の開始
### 問題のデバイスの情報を確認する
まず、inSSIDerを用いて問題のデバイスのMACアドレス、IPアドレスを確認します。
inSSIDerはデバイスのMACアドレスやIPアドレス、使用チャンネルやRSSI、チャンネル使用率やフレーム数等の情報を視覚的に確認する事が出来る非常に有益なツールです。

![image0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/d61f23c3-4327-2c91-eaed-59727cd1c8bd.png)

問題のデバイスの電波状況は

- 使用周波数帯：5GHz
- 受信感度(RSSI)：-48dBm

と確認する事が出来ます。

5GHzの周波数帯は減衰が激しく、離れた場所まで届きにくい特徴があります。
その5GHzでありながら受信感度は-48dBmという強めの値が出ている事より、問題のデバイスはお隣の家や自宅近辺にあるのではなく**自室の何処かに問題のデバイスがある**と推測しました。

### MACアドレスからベンダーを調査する
MACアドレスからベンダーを調査し問題のデバイスの特定を試みました。

https://uic.jp/mac/

問題のデバイスはランダムMACアドレスを利用している様子で、該当するベンダーは見当たらずデバイスを特定する事は出来ませんでした。残念・・・

### Pingを送信してみる
問題のデバイスにIPアドレスが割り当たっている様子の為、Pingを送信してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/34285baf-9638-ada1-230c-b7feb5bacf4d.png)

なんかPingが通ったり通らなかったりする・・・

#### APのログファイルを確認してみる
望み薄ですが検証用APのログファイルから何か情報が無いか確認をしてみました。
```
3:57:04	Client	Deauthenticated:Client MAC:46:65:43:xx:xx:xx, IpAddress:(192.168.0.11)
3:55:40	Client	Associated:Assigning Ip Address:(192.168.0.11) to Client MAC:46:65:43:xx:xx:xx.	
3:55:38	Client	Association:Client MAC:46:65:43:xx:xx:xx
1:15:18	Client	Deauthenticated:Client MAC:46:65:43:xx:xx:xx, Ip Address:(192.168.0.11)
1:13:13	Client	Associated:Assigning Ip Address:(192.168.0.11) to Client MAC:46:65:43:xx:xx:xx.
1:13:13	Client	Association:Client	MAC	46:65:43:xx:xx:xx
0:31:17	Client	Deauthenticated:Client	MAC:46:65:43:xx:xx:xx, Ip Address:(192.168.0.11)
```
検証用APのログファイルを確認して分かった事は
- 日中に検証APへの接続は無い
- 夜中に検証APへの接続がある

という2点だけでした。

#### APからデバイスの切断を試みる
検証用APから問題のデバイスに対して切断要求(Deauthentication)のフレームを送信し強制的に切断を試みました。
問題のデバイスは検証用APから切断されたものの、数秒後に再接続してきました:thinking:

#### iPhoneのWi-FiをOFFにしてみる
「検証用APには**iPhoneしか接続できない**」=「**iPhoneのWi-FiをOFFにしたら何か改善するかも**」と思いiPhoneのWi-FiをOFFにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/13ab527a-db16-bba4-9613-48df916d26ef.png)

しかしながら問題のデバイスは検証用APに接続された状態を維持しています。

![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/bb412715-200c-98f6-a6b5-581079e2fae1.png)

inSSIDerからもiPhoneの表示は消えましたが問題のデバイスは検証用APに絶賛接続中のまま変わらず。。。

#### 犯人を発見
問題のデバイスが見つからず~~検証用APのパスフレーズを変更して現実から目をそらそうと~~半ば諦めかけた時、ふとiPhoneの接続先SSIDを別のSSID(別のAP)に変更してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/b079526e-8aba-8ea7-c167-d0e3d9b1a2b0.png)

すると問題のデバイスが切断された様子をinSSIDerから確認する事が出来ました。

![image00000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/6f9c42ad-442d-202d-f77d-eb29d5edc788.png)
「奴が切断された！」

上記の動作からiPhoneとペアリングをしている機器が怪しいと考え、充電中のApple WatchのMACアドレスを確認した所、問題のデバイスのMACアドレスと合致しました。

```plantuml
@startuml
<style>
root {
  Padding 0
  Margin 0
}
caption {
  FontSize 14
}
</style>
title <img:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/6ceff52c-b825-6036-3950-0f3624e122be.png>
caption 犯人
@enduml
```
iPhoneのWi-Fiネットワーク情報がApple Watchにも同期される事はApple Watchを使用していて何となく把握しておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/3c6cf645-5f12-2493-a80f-ea1c66f1f3a3.png)

しかし「iPhone側でWi-FiをOFF」にすれば「Apple Watch側もWi-FiがOFF」になると勝手に思い込み、問題のデバイスがApple Watchであるという事は全く予想していませんでした。

興味深いのは
- iPhone側でWi-FiをOFFにすればApple Watch側もWi-FiがOFFになる
**という事は無く**
- iPhone側でWi-FiをOFFにしてもApple Watch側はWi-FiがONのままである

という動作をする点です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/3b0d742c-a9c4-dcea-51d1-82c68cadbf9a.png)

Apple Watchの動作仕様に詳しい方であればすぐに解決出来た問題かと思いますが、自身の知識不足と思い込みで解決までに時間を要してしまいました。

最終的に「もしや第三者が自宅のWi-Fi環境に接続しているのでは」という夜眠れず、昼寝する日々から解放されました。

## Apple Watchは何を送信していたのか
問題のデバイスはApple Watchである事が特定出来ました。
しかしApple Watchが検証用APにどんなデータを送信していたのか気になりApple Watch⇔検証用AP間のWi-Fiをキャプチャしてみました。

:::note alert
Wi-Fiのフレームをキャプチャして復号化する場合、必ず自身が管理運用しているWi-Fiネットワークで且つ自身のデバイス間の通信のみを対象として下さい。
:::

### キャプチャの実施
Wi-Fiのフレームをキャプチャするには以下の2つの方法があります。

- WindowsOSの場合：対応するネットワークインターフェイスアダプタを用いる
- MacOSの場合：標準搭載のスニファ機能を用いる

今回はASUS USB-AX56というアダプタとCommView for WiFiというアプリケーションを用いてWindowsOSでキャプチャしました。

```plantuml
@startuml
<style>
root {
  Padding 0
  Margin 0
}
caption {
  FontSize 14
}
</style>
title <img:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/9640dda7-12c8-985a-f85b-10b7020edb15.png>
caption カブトムシが羽を広げているようでカッコいいですね！
@enduml
```

具体的な手順は以下の通りです。
1. inSSIDerを用いてキャプチャしたいデバイスが使用しているチャンネルを確認する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/f36f03b6-ed46-789f-cd36-a4d972464ef3.png)  
2. WindowsOS端末とASUS USB-AX56をUSB接続する
3. CommView for WiFiを起動しキャプチャしたいチャンネルを選択する(マルチチャンネルを使用している場合は使用中のプライマリチャンネルを選択して下さい)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/cbd6d108-868e-0a9a-5e53-3509a5af6c97.png)
4. 「キャプチャの開始」ボタンを押下する

MacOSでのキャプチャ方法は以下のURLをご参考下さい。

https://www.cisco.com/c/ja_jp/support/docs/wireless-mobility/wireless-mobility/217042-collect-packet-captures-over-the-air-on.html

### Wiresharkで確認
キャプチャしたWi-FiフレームをWiresharkで確認します。
更にApple Watchから検証APに送信されたWi-Fiフレームだけを抽出して表示します。

:::note info
WPA2-PSKの場合、パスフレーズとSSIDからPMKを生成し、PMKとNonceの値からPTKを生成、PTKに含まれるTKでフレームのデータ部分を暗号化します。Nonceの値は4way-handshake時にAPとSTAとで交換し合う為、4way-handshakeをキャプチャ出来ていないと復号化する事は出来ません。
:::

具体的な手順は以下の通りです。
1. CommView for WiFiからpcapng形式でエクスポート
2. Wiresharkにpcapngファイルをドラッグ＆ドロップ 
    ![image000000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/8aef8483-2735-32f2-8cbc-1fe58e624dc6.png)
3. Wiresharkにデータフレームと送信元デバイスだけが表示されるようフィルタを設定
    ```
    wlan.fc.type == 2 and wlan.ta == 46:65:43:xx:xx:xx
    ```

    ![image00000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/3d452216-67f3-cabc-eb5f-cb87a2922ad4.png)

:::note info
metageek社から公開されているWireshark用のプロファイルを使用するとフレームの種類毎に色分けをしてくれて視認性が高まるのでお勧めです。

https://support.metageek.com/hc/en-us/articles/115013527388-Wireshark-Configuration-Profile
:::

:::note info
Wi-FiフレームをWiresharkで見ると様々なデータが見えてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/feec7685-1fbf-13c2-f7c9-60d8bd14ecdf.png)
- Radiotop Header：L1の情報を符号化したフィールド
- 802.11 radio information：L1やRadiotop Headerを簡潔に纏めたフィールド
- IEEE 802.11 QoS Data：IEEE 802.11フレームのヘッダ情報のフィールド
- Data：IEEE 802.11フレームに含まれるデータ
:::

### Wiresharkで復号
キャプチャしたWi-Fiフレームは(オープンWi-Fiのような暗号化されていない場合を除き)データの部分が暗号化されておりそのままでは内容を確認する事が出来ません。

![image000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/efff7cd0-c1d9-4079-f93c-02e8dbb17de6.png)

Wiresharkで暗号化されたデータ部分を復号化する具体的な手順は以下の通りです。
1. Wiresharkでデータフレームを選択する
2. IEEE 802.11フレームのヘッダを選択する
3. 右クリック＞プロトコル設定 を選択＞IEEE 802.11 wireless LAN設定を開く＞Decryption keys　を選択する
    ![image0000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/16521c34-a38b-467e-a5fd-154933c845fd.png)

4. Decryption keys＞編集　を選択する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/4a344752-8ccb-4e8e-d9d3-5ab461cf4e08.png)
5. Key Typeを「wpa-pwd」、Keyに「パスフレーズ:SSID」のフォーマットで入力、OKを押下する
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/2c7612c4-880a-f2a2-acea-3b0a6acdd94a.png)

:::note info
今回はWPA2-PSKで暗号化されたデータの復号化を行っています。WPA3で暗号化されたデータは復号化出来ない事に注意して下さい。WPA3 はパスフレーズを認証にのみ使用する為、復号化する事は出来ません。
:::

### 内容を確認
復号化に成功するとWi-Fiフレームのデータ部分を確認する事が出来ます。
データフレームとヌルデータフレームが繰り返し検証用APに送信され続けている様子が分かります。

![image00000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/3d452216-67f3-cabc-eb5f-cb87a2922ad4.png)

復号化前は「Data」としか表示されなかった部分が「Logical-Link Control」と「Address Resolution Protocol」になっている事が分かります。デフォルトゲートウェイへのARPである事が確認出来ます。
![image00000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/39a44fd7-9577-cf86-5410-c044853b7923.png)

:::note info
Logical-Link ControlはIEEE 802.2LLCヘッダです。LLCヘッダの中にL2より上位のL3に関するプロトコルの情報(IPパケットの種類や情報)が付与されます。
LLCはWi-Fiフレーム(802.11)特有の物で、有線(EthernetⅡ)ネットワークではEhternetフィールドで上位プロトコルの情報を付与する為、LLCは存在しません。
:::

ヌルデータフレームに関してはApple Watchと検証用AP間とで通信が完結しており、wlan.fc.pwrmgtフィールドに1と0を交互に設定したヌルフレームが繰り返し検証用APに送信され続けていました。
![iamge00000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817950/09ec06cd-d4b0-ba23-6833-fbba2d3d31b5.png)

更にこれらのフレームがApple Watchから検証APに送信されるタイミングやシチュエーションを検証してみました。結果、Apple Watchが充電中で且つスリープ状態となった際に、これらのフレームが送信されている様子を確認しました。

この結果から
1. Apple Watchが充電中で且つスリープ状態となった
2. 検証用APとの接続を維持する為、キープアライブの目的でデータフレームとヌルデータフレームを送信した

と考えられます。

## おわりに
Wi-Fiフレームの流れや構造をWiresharkで眺めているとたった1つのデータを送信するだけでもデータ以外の様々なフレームが流れている事が見えてきます。
「玄関開けたら2分でご飯」のように「Wi-Fiを繋げたら即データ送信」とならないのがWi-Fiの難しい所と感じます。あと"当たり前を疑おう"。

## 参考
- https://support.apple.com/ja-jp/guide/watch/apd0443fb403/watchos
- https://www.cisco.com/c/ja_jp/support/docs/wireless-mobility/wireless-mobility/217042-collect-packet-captures-over-the-air-on.html
- https://www.wireshark.org/download.html
- https://www.metageek.com/inssider/
- https://www.linkedin.com/pulse/wifi-analysis-troubleshooting-using-inssider-tool-gupta-bobby
- https://support.metageek.com/hc/en-us/articles/115013527388-Wireshark-Configuration-Profile
- https://www.tamos.com/products/commwifi
- https://www.silex.jp/library/blog/20131121-1
- https://www.cisco.com/c/ja_jp/td/docs/wireless/controller/ewc/17-6/config-guide/ewc_cg_17_6/802_11v.pdf