
OpenBSDの約37年前のカーネルバグを悪用、root権限への昇格を検証
Calif は、OpenBSD カーネルの脆弱性を組み合わせることで、KARL・SMAP・SMEP を有効にした状態でもローカル環境から root 権限を取得できたとしている。問題は修正済みである。
Calif は OpenBSD カーネルの脆弱性を報告した。そのうち1件は、元の BSD ソースまでさかのぼると約37年前から存在するとされる。今年早い時期に公開された本記事では、整数オーバーフローと別の範囲外書き込みを組み合わせた悪用手法が示されている。
脆弱性の概要
問題の箇所は、元の BSD ソースにおける共有メモリのアタッチメントカウンタである。このカウンタは符号付き16-bit short として定義されていた。
同じ共有メモリのアタッチレコードを持つプロセスを繰り返しフォークすると、カウンタは最大値の32,767を超え、負の値にラップアラウンドする可能性がある。Calif の悪用経路では、127 個の SysV 共有メモリセグメントをマッピングし、259 個のプロセスをフォークしたうえで、カウンタの値は -32,643 に変えられた。
この整数オーバーフローは、レースコンディションを介した use-after-free につながる可能性がある。Calif によると、悪用は lo0 と enc0 の ioctl ハンドラを確実に狙えるとしている。
権限昇格の仕組み
Calif は、整数オーバーフローによる use-after-free と、カーネル内の別の範囲外書き込みを組み合わせることで、ローカルから root 権限への昇格が可能になったとしている。使用されたのは、持続的な struct ip_moptions の確保であり、そのために IP_MULTICAST_TTL を既定値以外の 2 に設定した。確保されるサイズは 16-byte である。
Calif は、この悪用が KARL、SMAP、SMEP を有効にした環境で成立し、情報漏えいの脆弱性は使っていないとしている。また、対処としてエラータ 026 が整数オーバーフローに、エラータ 018 が範囲外書き込みにそれぞれ割り当てられた。
防御策の提案
本記事は、以下の防御策を提案している。
- safe-unlinking の導入
- 自己参照型の PTE マップのランダム化
- カーネルアロケータの動作のランダム化
- array bounds sanitizer や Alloc Tokens などのコンパイラ機能の活用
Calif は、ブートタイムアロケータとベストフィットアロケータの両方に、ベースアドレスのランダム化が欠けていると指摘している。PTE ランダム化の具体的な方式としては、PML4 スロットの選択式として 320 + (random_byte & 127) が示され、PTE_BASE の候補ベース間隔は 512 GiB とされた。
ランダム化が適さない場合の代替策として、PTE を読み取り専用にし、変更時に CR0.WP を変更する方法などで足りる可能性があるとされる。
Calif は FreeBSD に対し、array bounds sanitizer が悪用緩和策として有用である可能性を示唆した。そのうえで、同sanitizer で検出できたはずの 21 件の問題を非公開で報告したとしている。
筆者の見立て
- 脆弱性が積極的に狙われる前に防御を強化することは、攻撃者の参入障壁を高める可能性を示唆している。
- AI支援による脆弱性発見が進む中で、脆弱性クラス全体を緩和することと攻撃の複雑化は、今後さらに重要になると論じている。
- ベースアドレスのランダム化は、それによって生じる隙間を後から利用できるため、実質的にコストがかからないと論じている。
- どちらのランダム化手法も、追加の脆弱性なしに予測可能なポインタ位置を破るのに十分だと予想している。
- より詳細なアロケータの変更により、実行時ランダム化の性能オーバーヘッドが緩和される可能性があると予想している。
- 事前の堅牢化によって悪用プリミティブのクラス全体を体系的に無効化でき、少なくとも攻撃者のコストを高められると論じている。
この記事は元記事の事実のみに基づいて自動生成されました。
出典
- 媒体名: Calif
- 原題: Big Fish: Exploiting a 37-Year-Old Kernel Bug in OpenBSD
- URL: https://calif.io/research/big-fish