
Samsung Tizen 9 TVをChromium WasmGC RCEとV4L2 physmapによる任意の物理メモリアクセス経由でroot化するリサーチツールキット。起動時の永続ペイロードとrootシェルチャネルを備える。
Tizen 9 を実行する 2024 年製 Samsung Neo QLED に関する非公式のセキュリティリサーチ。 sdb も開発者モードもファームウェア書き換えも不要:テレビは自身のブラウザから root 化され、root は起動時に実行される純正サービスアプリを通じて永続化される。
| テスト機 | 2024 年製 Neo QLED、QNX1D シリーズ(QTV T09 プラットフォーム) |
| ファームウェア | T-PTMxxxx (01400) |
| カーネル | Linux 5.4.249、ARM32(VMSPLIT_3G + HIGHMEM、LPAE なし)、PAGE_OFFSET 0xC0000000、PHYS_OFFSET 0x20000000 |
| ブラウザ | Chromium 120.0.6099.5(SamsungBrowser/7.0) |
| Root | uid=0、CapEff=0x3fffffffff |
| 永続ペイロード | リポジトリ v41(現在の md5/サイズは AGENTS.md の状態行に記載 — 成果物から再生成);テスト機は同一ビルドを実行中(2026-10-27 にデプロイ、ビーコンには tok= が含まれる);payload_backup.dll は前回のビルドを保持 |
| Root チャネル | テレビ上の TCP 31337、ラインプロトコル、応答は __END__ で終了 |
pwsh -File .\root.ps1 -TvIp <tv-ip> # root the TV
pwsh -File .\uninstall.ps1 -TvIp <tv-ip> # restore stock
root.ps1 は PC 上で実行され、すべてを制御します。ポート 80 のサーバーを起動し、ブラウザスタブを root 化し、ブートペイロードをインストールし、再起動後に root チャネルを待機します。2 つの手順は TV のリモコンで操作する必要があり、両方についてプロンプトが表示されます:
http://<pc-ip>/index.html を開き、RUNNING を待ちます;その後:
python tools\root_shell.py "id" <tv-ip> # talk to the TV's root channel
すべてのオプション、正確なプロンプト、期待される出力、ホストIPに関する注意点、そして手動フォールバックについては docs/USAGE.md を参照してください。
/dev/video40/30/60)は、mmap() で攻撃者が指定した vm_pgoff を受け入れ、検証せずに remap_pfn_range() へ渡します。これにより、非特権プロセス(uid 5001、グループ video)から任意の物理メモリ読み書きが可能になります。init_task を見つけ、フォークした子プロセスの real_parent をたどって自身のタスクを特定し、資格情報をゼロクリアします。app_onboot サービスの IL アセンブリを、起動のたびに physmap/資格情報パッチを繰り返し、自身のノードを閉じて TCP 31337 で root コマンドチャネルを提供する .NET ペイロードに置き換えます。GPU の CVE も、カーネルエクスプロイトも、署名済みモジュールも使いません。興味深いのは physmap の部分です。実測した定数を含む段階ごとの解説は docs/EXPLOIT.md にあります。
| ドキュメント | 内容 |
|---|---|
docs/USAGE.md | 実行方法: オプション、プロンプト、期待される出力、アンインストールの詳細、リカバリ |
docs/EXPLOIT.md | チェーンを段階ごとに、ファームウェア固有の定数とともに解説 |
docs/ROOT-METHODS.md | 評価したすべての root/永続化手法と、採用された手法 |
docs/FAILED.md | うまくいかなかったこととその理由 — 行き止まりの一覧のように読め、数週間を節約できる |
docs/BOOT-REGRESSION-SMACK.md | プロジェクトで最も微妙なバグ: 誤った SMACK ラベルによりアプリが Main の前に終了した件 |
docs/PORTABILITY.md | 別の Tizen 9 TV: 4つのゲート、再測定すべき項目、段階的な移植手順 |
docs/SERVER-HOSTING.md | PC 側サーバー: 実行方法、無言で停止する罠、ファイアウォール、ログ |
docs/SCRIPT-REVIEW.md | スクリプトの本番運用準備状況の監査 |
docs/TESTING.md | テスト層(オフラインおよび TV 上)と、それぞれが検出するもの |
docs/LOGGUIDE.md | すべてのビーコンとツールエラーの解説と次のステップ |
docs/REFERENCE-MATERIALS.md | 自分のモデル向けのファームウェア / GPL ソース / シミュレーションツールのダウンロード先 |
docs/REVIEW-HISTORY.md | クローズ済みのレビュー指摘とその根拠(アーカイブ) |
docs/OPEN-ISSUES.md | 現在の状態、保留中の作業、クローズ済みのレビュー/パスの履歴 |
AGENTS.md | 引き継ぎ: ツール、手順、検証、罠、リカバリ |
CHANGELOG.md | 変更内容とその理由の日付付き履歴 |
SECURITY.md | 認証なしの 31337 バックドア、スコープ、報告、法的事項 |
NOTICE.md | サードパーティの帰属表示、再ライセンスされていないファイル |
LICENSE | オリジナルの成果物は MIT(サードパーティファイルは除外) |
root.ps1, uninstall.ps1 PC entry points (PowerShell)
payload/ boot payload source (.NET 6, Program.cs)
server/ port-80 server, exploit page, TV-side deploy scripts
tools/ physmap client, kernel helpers, build scripts
docs/ the documents above
AGENTS.md hand-off notes
LICENSE, NOTICE.md license + third-party attribution
SECURITY.md backdoor/scope/reporting
ツールキット全体がコミットされているため、クローンは他の作業ツリーなしで動作します。
server/payload.dll は意図的に含まれています(ビルド出力とバイト単位で同一)。
これにより .NET SDK なしでもツールキットが動作します。ランタイムログ、ビルド出力、
ホストごとに生成されるデプロイスクリプトは git で無視され、HTTP 経由で提供されることはありません。
docs/PORTABILITY.md を参照してください。server/deploy.sh はテンプレートであり、
その H=/WANT=/SIZE_WANT=/TOKEN= マーカーを server.py がリクエストごとに、
TV が使用したアドレスと実際に提供されたペイロードからレンダリングします。ページは
シェルコードのコールバック(IP および ポート)を書き換え、ペイロードは
share/rootchan.host を読み取ります。コンパイル時に埋め込まれた Host は TEST-NET の
プレースホルダーです。docs/SERVER-HOSTING.md を参照)。payload/global.json は
10.0.x を固定しており(rollForward: latestPatch)、プロジェクトは net6.0 をターゲットと
していますが、固定された SDK でもビルド可能です(EOL 警告が表示されるのは想定内です)。参照資料(ファームウェア、GPL カーネルソース、QEMU ツール)は同梱されていません。 docs/REFERENCE-MATERIALS.md に、お使いのモデル向けに 各資料をダウンロードする場所が記載されています。
この手法はポータブルですが、このビルドはそうではありません。payload.dll はこのカーネルの
PHYS_OFFSET、init_task、および 4 つの task_struct オフセットをハードコードしており、
ブラウザチェーンは Chromium 120 に固有です。手短に言うと:
server/probe.html を配信し(安全です。何も実行しません)、
TV で開きます。WasmGC を備えた Chromium ~120 が必要です。そうでなければ、この CVE は
適用されません。owner としてコード実行を取得し(ブラウザチェーン)、
その後 tools/physmap.py / tools/physrpc.S を使って TV の /dev/video* ノードの
1 つで任意の pfn の mmap を証明します。オフセットが検証できたら、そこで停止します。PHYS_OFFSET、Image ベース、init_task、および
tasks/comm/cred/real_parent オフセットを測定します。payload/Program.cs の
定数を編集し、以下の読み取り信頼性の制限を再確認します。/opt 上で、自身の SMACK ラベルの下でファイルを
書き換えられる dotnet-inhouse、app_onboot アプリを見つけます。そのアプリ ID/パスを
server/deploy.sh、server/uninstall.sh、server/recover.sh に設定します。dotnet build -c Release -o out を実行し、成果物を
server/payload.dll にコピーし(デプロイゲートはそこからレンダリングされるため、
編集すべき WANT= はありません)、root.ps1 経由でデプロイし、その後コールドブート
します。試行 2 回目が想定される下限です。