
CVE-2022-23093 FreeBSD スタックベースのオーバーフロー
⚠️ デフォルトで使用されるシェルコードは FreeBSD/x86-64 - execve - Gitsnik 作の 28 バイト です。起動用に変更して独自のものを使用してください ⚠️
ping ユーティリティは、ホストまたはゲートウェイから ICMP ECHO_RESPONSE を要求するために使用され、ICMP プロトコルの必須の ECHO_REQUEST データグラムを介して、IPv4-host または IPv4-mcast-group のいずれかの IPv4 ターゲットを指定して呼び出されます。ECHO_REQUEST データグラムは、IP ヘッダーと ICMP ヘッダーで構成され、その後に "struct timeval" と、パケットを埋めるための可変長の "pad" バイトが続きます。
FreeBSD プロジェクトのセキュリティアドバイザリによると、ping ユーティリティは、pr_pack() 関数内で応答を処理するために、ネットワークから生の IP パケットを取得します。応答処理において、ping は IP ヘッダー、ICMP ヘッダー、および存在する場合は、ICMP エラーの原因となったパケットを表す "quoted packet" を再構築します。quoted packet には IP ヘッダーと ICMP ヘッダーも含まれます。
pr_pack() 関数は、受信した IP ヘッダーと ICMP ヘッダーを、さらなる処理のためにスタックバッファにコピーします。しかし、応答または quoted packet のいずれかにおいて、IP ヘッダーに続く IP オプションヘッダーの可能性を考慮していません。IP オプションが存在する場合、pr_pack() は宛先バッファを最大 40 バイト分オーバーフローさせます。
ping ユーティリティはユーザー空間で実行され、ping コマンドを呼び出すと、/sbin/ping にあるバイナリが実行されます。このユーティリティのソースコードは FreeBSD ソースで公開されています。脆弱な関数である pr_pack() は、ICMP パケット応答情報を文字列形式で stdout に出力します。例: "64 bytes from 1.3.3.7: icmp_seq=1 ttl=55 time=13.7 ms."
✔️ リクエストとレスポンスの両方において、ICMP パケットは、上記の図のように、オプションの Options フィールドを持つ IP ヘッダーで構成されています。悪意のある攻撃では、これらの IP オプションが有効化され、null 以外のバイトで埋められます。 ✔️
ICMP パケットが宛先ホストへの経路上で不正な形式であるか、意図的に改ざんされ、元のエコー要求で IP オプションが有効になっている場合、pr_pack() 関数は IP オプションの存在を収容するための十分なスペースをスタックに割り当てられず、スタックオーバーフローが発生します。
🤝 これらのエラーケースでは、宛先ホストからの応答のデータセクションに、ICMP エラーの原因となった特定のパケットを識別する "quoted packet" が含まれる場合もあります。quoted packet に ICMP ヘッダーが含まれている場合、pr_pack() 関数はスタックをオーバーフローさせます。 🤝