「cat readme.txt」はiTerm2を使用する場合、安全ではありません
19時間前原文(blog.calif.io)
概要
- iTerm2のSSH統合機能における脆弱性の詳細
- cat readme.txtコマンド実行時の危険性
- 攻撃の仕組みとエクスプロイト手法の解説
- 修正状況と再現手順の概要
- OpenAIとの協力による調査
iTerm2のSSH統合機能における脆弱性
- iTerm2のSSH統合機能、リモートセッションの詳細な管理を目的
- it2ssh経由でSSH統合を開始、リモート側にconductorスクリプトを配置
- conductorとiTerm2間で端末エスケープシーケンスを交換し、各種操作を調整
- conductorはネットワークサービスではなく、リモートシェル内で動作する単なるスクリプト
- プロトコルは通常の端末I/O経由でやり取り
端末エミュレータとPTYの役割
- 端末エミュレータは従来のハードウェア端末をソフトウェアで再現
- OSが提供する**PTY(擬似端末)**が、エミュレータと前面プロセス間の橋渡し
- 通常のSSHセッションでは、iTerm2がPTYへバイト列を書き込み、sshがリモートへ転送
- conductorはstdinからこれらのデータを受信
SSH統合プロトコルの仕組み
- DCS 2000pでconductorのフック
- OSC 135でconductorメッセージのやり取り
- DCS 2000pが発生すると、iTerm2はconductorパーサを生成
- その後、OSC 135メッセージ(begin, send, runhook等)を受け付ける
脆弱性の本質と攻撃手法
- iTerm2が信頼できない端末出力からもSSH conductorプロトコルを受け入れてしまう設計ミス
- 悪意あるファイルやサーバーレスポンス等がDCS 2000pフックや偽OSC 135メッセージを出力可能
- iTerm2はこれを本物のSSH統合セッションと誤認し、通常のワークフローを開始
- 攻撃用ファイルには、偽のconductorセッションのトランスクリプトを含む
- iTerm2がファイルを描画する際、偽のプロトコルシーケンスを処理
エクスプロイトの流れ
- 偽DCS 2000pラインでセッション開始を宣言
- 偽OSC 135メッセージでiTerm2のリクエストに応答
- conductor.start()がgetshell()やpythonversion()を自動送信
- 偽メッセージは最小限で正確に応答し、iTerm2を通常のフローへ誘導
- 最終的にiTerm2が**run ...**コマンドを生成、base64エンコードしてPTYへ送信
- 攻撃者が用意したace/c+aliFIoという実行可能ファイルを呼び出す構造
再現手順とPoC
- genpoc.pyで攻撃用ファイルと実行ファイルを生成
- ace/c+aliFIo:実行可能なヘルパースクリプト
- readme.txt:悪意あるDCS 2000p・OSC 135シーケンスを含むファイル
- 同じディレクトリでcat readme.txtを実行すると、最終チャンクが実行ファイルとして解決される
修正と現状
- 2024年3月30日:iTerm2へバグ報告
- 2024年3月31日:コミットa9e745993c2e2cbb30b884a16617cd5495899f86で修正
- 記事執筆時点で安定版には未反映
- パッチのみを元に再現したエクスプロイトはgenpoc2.pyとして公開
まとめ
- iTerm2利用者は安易なファイル表示にも十分注意が必要
- 端末エスケープシーケンスやPTYの仕組みを悪用した新しい攻撃ベクトル
- 修正パッチの適用と、信頼できないファイルの取り扱い注意が重要