PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

AndroidのVPNロックダウンをすり抜けるNAT-T keepaliveの話

Androidの「Always-on VPN」と「Block connections without VPN」は、通信がVPNの外に漏れないようにするための仕組みだと思われてきました。ところが今回の報告では、普通のアプリが公開APIを使うだけで、VPNの外側にUDP/4500のkeepaliveパケットを出せてしまうとされています。しかも対象は特定機種だけではなく、Android 12以降の多くの端末にまたがる可能性がある、というのがこの話の重さです。単なる学術的な指摘ではなく、「VPNで守られているはずの通信の境界がどこまで信用できるのか」を突く内容になっています。

Android 16端末で見えた、VPNの外へ出るUDP/4500

元記事が示しているのは、AndroidのNAT-T keepalive offloadが、VPN lockdownをまたいで物理ネットワークにパケットを出してしまう、という不具合です。NAT-TはIPsecでよく使われるUDP 4500番ポートの仕組みで、Androidではアプリが IpSecManager.UdpEncapsulationSocket を開き、ConnectivityManager.createSocketKeepalive(...) を呼ぶことで、NAT変換のためのkeepaliveを維持できます。問題は、その経路がフレームワーク内部で startNattKeepaliveWithFd(...) に流れ、そこで受け付けられたあと、Wi‑Fiのkeepalive offloadに渡されてしまう点です。元記事は、ここで現在のVPNポリシーが十分に確認されないまま、物理インターフェース側にUDP/4500が出ていくと主張しています。

検証はかなり具体的です。Pixel 8 ProでAndroid 16 build CP1A.260505.005を使い、Always-on VPNと「Block connections without VPN」を有効にした状態でアクセス・ポイント側をキャプチャしたところ、公共の最小間隔である10秒ごとにパケットが観測されたとされています。Samsung SM-F966BでもAndroid 16で同系統の挙動が確認され、VPN Leak Guardが物理IPv4のデフォルトゲートウェイを選び、アクティブな callback を拾って、24時間32分にわたる継続的な lease を記録したとしています。Nothing A059(Asteroids)でも同じく物理ゲートウェイが選ばれ、アクティブなWi‑Fi slotが1つ見えたという結果でした。ただし、このNothing端末については独立したパケットキャプチャや継続時間の測定は取れていない、と明記されています。

報告の中心にあるのは、AndroidのVPN lockdownが本来守るべき「そのアプリの通信はVPNの外へ出ない」という前提が崩れていることです。元記事では、アプリが普通の権限だけでこの経路をたどれたとされ、rootやADB、隠しAPI、dangerous permission、PACKET_KEEPALIVE_OFFLOAD のような特権権限は不要だったと説明します。INTERNETACCESS_NETWORK_STATE だけを持つPoCでも成立した、というのが厄介です。さらにソース履歴をたどると、startNattKeepaliveWithFd(...) はもともと特権的な raw-fd API だったのに、公開の UdpEncapsulationSocket 経由へと形が変わる中で、resource validation が入ったり戻されたりし、現在はfd/resourceの組が本当にその呼び出し元のVPNポリシーに属するかを確かめていない、と論じています。

元記事は適用範囲にも踏み込みます。F-DroidとIzzyOnDroidの4,679個の異なるGit originを調べたところ、Android frameworkのIPsec、IKE、NAT-T APIを使うものは検出されず、手動確認で73個のAndroid VpnServiceアプリが見つかったとしています。さらに、実機確認は3つのOEMと2つの確認済みWLAN familyで成立し、ファームウェアの対応範囲を合わせると、推定されるAndroid由来出荷台数の91.24%に影響すると結論づけています。残り8.76%は未解決のままです。つまり、これは個別の端末の癖というより、Android 12以降のかなり広い端末群に共通する露出だ、という主張です。

これ、VPNの「暗号化」ではなく「境界管理」の問題だと思う

この報告で一番気になるのは、話が単なる「暗号化の穴」ではないことです。VPNというと、通信内容を読めなくする話に目が行きがちですが、元記事が突いているのはもっと手前の、通信がどの経路を通ってよいかという境界の話です。VPN lockdownは「アプリの通信がVPNの外に出ない」ことを約束する機能なのに、今回は中身のペイロードを見ず、keepaliveという比較的地味な制御通信が外へ出てしまう。ここが危ない。攻撃者がデータを大量に送る必要はなく、定期的なUDP/4500だけで、非VPN側の到達先に「この端末は今そこにいる」という存在証明を渡せてしまうからです。

しかも、この種の抜け道は見つけにくいと思います。実運用では、VPN漏れの検査はDNSやIPv6、WebRTCのような派手な漏れに偏りやすい。でも今回のように、アプリの通常送信ではなく、OSが肩代わりするoffloadが漏れ道になると、アプリ層の監視では拾いにくい。ログにも素直には残らないかもしれません。だからこそ、問題は「アプリが何を送ったか」より「OSが何を代わりに送ったか」に移っています。ここを前提にしないと、VPN保護の説明はかなり楽観的になりすぎると思います。

端末メーカーごとの差より、共有フレームワークの弱さが本丸に見える

Pixel、Samsung、Nothingで確認されたという並び方は、読んでいて少しぞっとします。個別OEMの実装ミスなら、話はまだ限定的です。でも元記事は、共有のAndroid framework pathに起因すると見ています。つまり、上流で同じロジックを持っていれば、端末メーカーが違っても似た挙動になる。Androidの世界では、こういう「共通土台の誤り」が後から広く効いてくることがあるので、端末単位で安心してしまうのは危ないです。

もうひとつ重要なのは、元記事が示した数字の意味です。91.24%というカバー率は、厳密な市場全体の断定というより、調査したWLAN familyの範囲で「かなりの大部分に波及する」と見るべき数字でしょう。それでも、十分に大きい。セキュリティ上の欠陥は、理屈のうえで再現できることと、現実の出荷台数に乗ることの両方がそろって初めて重くなりますが、今回はその両方にかなり近いところまで来ているように見えます。未解決の8.76%があるから安心、とは到底言えません。

いちばん厄介なのは、特権を持たないアプリでも成立する点

この手の話でよくある誤解は、「どうせrootが必要なんでしょう」というものです。ところが元記事では、そうではないと明言しています。研究用の計測にはADBやrootを使ったが、攻撃成立の前提ではない。普通の第三者アプリが、公開APIを使い、ユーザーがVPN lockdownを有効にしている状況で、物理ネットワーク側へkeepaliveを投げられる。ここはかなり深刻です。

特に嫌らしいのは、攻撃者が狙う相手の行動をほとんど選ばない点です。アプリ起動直後に成立するPoCがあるなら、ユーザーがそのアプリを一度でも開いた時点で、静かに継続通信の土台ができてしまう。大きなデータを抜く必要もなく、定期的な小さなパケットで十分です。監視の観点ではノイズに紛れやすいし、通信量ベースの検知にも引っかかりにくいでしょう。だから、こういう欠陥は「派手な侵入」ではなく「じわじわと境界を壊す」タイプとして見るべきだと思います。

直されるべきなのは、APIの形より前の認可だろう

元記事を読むと、修正の焦点はAPIを隠すことではないように見えます。問題は、公開された UdpEncapsulationSocket から来た要求を受ける時点で、fd/resourceの組と現在のVPNポリシーの整合性を十分に確認していないことです。つまり、見た目が公開APIかどうかではなく、その時点で「この呼び出し元に物理underlayへkeepaliveを出す権利があるのか」を判断していないのが本質です。

これはAndroidだけでなく、OSがアプリの代わりにネットワーク操作を肩代わりする設計全般に通じる話でもあります。便利さのためにoffloadや仲介を増やすほど、認可のチェックポイントは増えるはずなのに、実際には見落とされやすい。VPNやファイアウォールは最後の出口で守るだけでは足りず、途中で委譲された通信にも同じポリシーを通さないといけない。今回の報告は、その当たり前をかなり強い形で突きつけているように思います。

参考: Android NAT-T Keepalive Offload Bypasses VPN Lockdown: Device-Class Exposure Across Most Android 12+ Devices

同じ著者の記事