VPNトンネル経由でルーティングされるTCP接続にパケットを偽装、変更、または挿入できる攻撃手法(CVE-2019-14899)。この問題は、 LinuxFreeBSD、OpenBSD、 Android, macOSiOSやその他のUnix系システム。 Linux IPv4 用の rp_filter (逆パスフィルタリング) メカニズムをサポートしており、これを「厳密」モードで有効にすると、この問題は解消されます。
この方法では、暗号化されたトンネル内を通過する TCP 接続レベルでのパケットの置換が可能になりますが、追加の暗号化レイヤー (TLS、HTTPS、SSH など) を使用する接続を妨害することはできません。偽のパケットは外部インターフェースから送信され、カーネルによって VPN インターフェースからのパケットとして処理されるため、VPN で使用される暗号化アルゴリズムは重要ではありません。最も可能性の高い攻撃対象は暗号化されていないHTTP接続を妨害することですが、 攻撃を使用して DNS 応答を操作します。
パケットスプーフィングの成功は、以下の方法で作成されたトンネルで実証されています。 OpenVPN, WireGuard IKEv2/IPSec.Tor は、トラフィック転送とループバックインターフェイスへのバインドに SOCKS を使用するため、この問題の影響を受けません。 IPv4 の場合、rp_filter が「Loose」モード (sysctl net.ipv4.conf.all.rp_filter = 2) に設定されている場合、攻撃が可能です。当初、ほとんどのシステムは「Strict」モードを使用していましたが、 昨年12月にリリースされたバージョンでは、デフォルトモードが「Loose」に変更され、この変更は多くのディストリビューションのデフォルト設定に反映されました。 Linux.
rp_filter メカニズム 送信元アドレスのスプーフィングを防ぐためにパケット パスをさらにチェックします。 0 に設定すると、送信元アドレスのチェックは実行されず、ネットワーク インターフェイス間でパケットを制限なく転送できます。モード 1「厳密」では、各着信パケットをルーティング テーブルと照合し、パケットを受信したネットワーク インターフェイスが応答を配信するための最適なルートに関連付けられていない場合、パケットは破棄されます。モード2「Loose」は、ロードバランサーや非対称ルーティングを使用する場合に作業を可能にするためにチェックを緩和します。
応答ルートは、着信パケットが到着したネットワーク インターフェイスと同じネットワーク インターフェイスを通過しない可能性があります。
Loose モードでは、着信パケットはルーティング テーブルと照合されますが、送信元アドレスが利用可能なネットワーク インターフェイスを介して到達可能である場合は有効であると見なされます。提案された攻撃は、攻撃者が VPN インターフェイスに対応する偽装された送信元アドレスを持つパケットを送信できるという事実に基づいています。このパケットは VPN ではなく外部ネットワーク インターフェイスを介してシステムに入るにもかかわらず、rp_filter の「Loose」モードではそのようなパケットは破棄されません。
攻撃を実行するには、攻撃者はユーザーがネットワークにアクセスするゲートウェイを制御する必要があります(たとえば、被害者が攻撃者が制御する無線アクセスポイントに接続する場合はMITM組織を介して、または )。攻撃者は、ユーザーがネットワークに接続する際に経由するゲートウェイを制御することで、VPN ネットワーク インターフェイスのコンテキストに表示される偽のパケットを送信できますが、応答はトンネル経由でルーティングされます。
VPN インターフェイスの IP アドレスが置き換えられたダミー パケットのストリームを生成することにより、クライアントによって確立された接続に影響を与えようとしますが、これらのパケットの影響は、トンネルの動作に関連する暗号化されたトラフィック フローの受動的な分析を通じてのみ観察できます。攻撃を実行するには、VPN サーバーによって割り当てられたトンネル ネットワーク インターフェイスの IP アドレスを見つけ、トンネルを介して特定のホストへの接続が現在アクティブであることを確認する必要があります。
VPNの仮想ネットワークインターフェイスのIPアドレスを特定するために、SYN-ACKパケットが被害者システムに送信され、仮想アドレスの全範囲を順番に調べます(まず、VPNでデフォルトで使用されるアドレスが検索されます。たとえば、 OpenVPN サブネット10.8.0.0/24が使用されます。アドレスの存在は、RSTフラグ付きの応答を受信することで判断できます。
同様に、特定のサイトへの接続の存在とクライアント側のポート番号が判別されます。ポート番号を並べ替えることで、サイト IP が送信元アドレスとして置き換えられ、仮想 IP VPN が宛先アドレスとして置き換えられた SYN パケットがユーザーに向けて送信されます。サーバー ポートは予測可能 (HTTP の場合は 80) であり、異なる番号に対する ACK 応答の強度の変化と RST フラグ付きのパケットの不在を組み合わせて分析することで、ブルート フォースによってクライアント側のポート番号を計算できます。
この時点で、攻撃者は接続の 4 つの要素 (送信元 IP アドレス/ポートと宛先 IP アドレス/ポート) をすべて知っていますが、被害者のシステムが受け入れる偽のパケットを生成するには、攻撃者は TCP 接続のシーケンス番号と確認応答 (seq と ack) 番号を特定する必要があります。これらのパラメータを決定するために、攻撃者は、番号が TCP ウィンドウ内にあることを示す応答 ACK パケットを受信するまで、さまざまなシーケンス番号を試しながら偽の RST パケットを継続的に送信します。
攻撃者は、同じ番号のパケットを送信し、受信したACK応答を観測することで検出の正しさを検証し、その後、現在のシーケンスの正確なシーケンス番号を決定します。応答が暗号化されたトンネル内で送信され、傍受されたトラフィックストリーム内での応答の存在を間接的にしか分析できないため、このタスクは複雑になります。クライアントがVPNサーバー宛てのACKパケットを送信したかどうかは、偽造パケットの送信と相関する暗号化された応答のサイズと遅延に基づいて判断されます。たとえば、 OpenVPN サイズが79の暗号化されたパケットであれば、それがACK確認メッセージを含んでいることを正確に判断できます。
攻撃に対する保護がオペレーティングシステムカーネルに追加されるまで、問題をブロックするための一時的な方法として 「preroute」チェーン内のパケット フィルターを使用して、トンネルの仮想 IP アドレスが宛先アドレスとして指定されているパケットの通過をブロックします。
iptables -t raw -I PREROUTING ! -i wg0 -d 10.182.12.8 -m アドレスタイプ ! —ソースタイプ LOCAL -j DROP
またはnftablesの場合
NFT テーブル IP 生の追加
nft はチェーン ip raw prerouting '{ type filter hook prerouting priority 0; を追加します。 }'
nft ルール ip raw prerouting を追加 'iifname != "wg0" ip daddr 10.182.12.8 fib saddr type != local drop'
IPv4 トンネルから保護するには、rp_filter を「Strict」モードに設定するだけです (「sysctl net.ipv4.conf.all.rp_filter = 1」)。 VPN 側では、暗号化されたパケットにパディングを追加してすべてのパケットを同じサイズにすることで、シーケンス番号の決定方法をブロックできます。
出所: オープンネット.ru
