アドレス空間レイアウトランダム化( ASLR ) は、メモリ破損の脆弱性の悪用を防ぐためのコンピュータ セキュリティ技術です。[ 1 ]攻撃者がメモリ内の特定の悪用関数にコードの実行を確実にリダイレクトすることを防ぐために、ASLR は実行可能ファイルのベース、スタック、ヒープ、ライブラリの位置など、プロセスの重要なデータ領域のアドレス空間の位置をランダムに配置します。カーネルに適用された場合、この技術はカーネル アドレス空間レイアウトランダム化( KASLR )と呼ばれます。[ 2 ]
Linux PaXプロジェクトは最初に「ASLR」という用語を作り出し、2001年7月にLinuxカーネルのパッチとしてASLRの最初の設計と実装を公開しました。これは完全な実装と見なされており、2002年10月からカーネルスタックのランダム化のためのパッチを提供しています。[ 3 ]
ASLRをデフォルトでサポートした最初の主流オペレーティングシステムは、 2003年のOpenBSDバージョン3.4でした[ 4 ] [ 5 ]。続いて2005年にLinuxがサポートしました。
アドレス空間のランダム化は、攻撃者がターゲットアドレスを予測することを困難にすることで、一部のセキュリティ攻撃を阻止します。例えば、return-to-libc攻撃を実行しようとする攻撃者は、実行するコードを特定する必要があります。一方、スタックに注入されたシェルコードを実行しようとする攻撃者は、まずスタックを見つける必要があります。どちらの場合も、システムは関連するメモリアドレスを攻撃者から予測不可能にします。これらの値は推測する必要があり、誤った推測は通常、アプリケーションのクラッシュにより回復不可能となります。
アドレス空間配置のランダム化は、攻撃者がランダムに配置された領域の位置を推測する可能性が低いことに基づいています。セキュリティは、検索空間を拡大することで向上します。したがって、アドレス空間のランダム化は、ランダムオフセットにエントロピーが多いほど効果的です。エントロピーは、ランダム化が行われる仮想メモリ領域の空間量を増やすか、ランダム化が行われる期間を短縮することによって増加します。期間は通常、可能な限り短く実装されるため、ほとんどのシステムではVMA空間のランダム化を拡大する必要があります。
ランダム化を無効化するには、攻撃者は攻撃したいすべての領域の位置を正確に推測する必要があります。スタックやヒープなどのデータ領域では、カスタムコードや有用なデータがロードされるため、コードにNOPスライドを使用したり、データを繰り返しコピーしたりすることで、複数の状態を攻撃できます。これにより、領域が少数の値のいずれかにランダム化されていれば、攻撃が成功します。一方、ライブラリベースやメイン実行ファイルなどのコード領域は、正確に発見する必要があります。これらの領域は、スタックフレームがスタックに挿入され、ライブラリが返されるなど、しばしば混在しています。
以下の変数を宣言できます。
mmap()基底のエントロピービット)mmap()(基本エントロピーの試行ごとに攻撃されたビット数)攻撃者が成功する確率を計算するには、署名ベースのIPS、法執行機関、またはその他の要因によって中断されることなく実行される試行回数αを仮定する必要があります。総当たり攻撃の場合、デーモンを再起動することはできません。関連するビット数と、各試行で攻撃されるビット数も計算する必要があり、攻撃者が突破しなければならないビット数が残ります。
以下の式は、 Nビットのエントロピーに対して、与えられたα回の試行における成功確率を表しています。
多くのシステムでは、数千から数百万になることもあります。32ビットシステムでは、典型的なエントロピーNの値は8ビットです。[ 6 ] 2004年のコンピュータ速度に関して、Shachamらは「…16ビットのアドレスランダム化は、総当たり攻撃によって数分以内に 破られる可能性がある」と述べています。 [ 7 ](著者らの主張は、同じアプリケーションを遅延なく複数回攻撃できるという前提に基づいています。grsecurityに含まれるようなASLRの適切な実装では、このような総当たり攻撃を不可能にするいくつかの方法が提供されています。1つの方法は、実行ファイルが一定回数クラッシュした場合に、設定可能な時間だけ実行を阻止することです。)64ビットシステムでは、これらの数値は通常、少なくとも数百万に達します。
Android [ 8 ]およびおそらく他のシステムでは、ライブラリのロード順序をランダム化する ASLR の一種であるライブラリロード順序ランダム化が実装されています。これはエントロピーをほとんど提供しません。必要なライブラリごとに提供されるエントロピーのビット数の近似値は以下に示されています。これはまださまざまなライブラリサイズを考慮していないため、実際に得られるエントロピーは実際にはもう少し高くなります。攻撃者は通常 1 つのライブラリしか必要としません。複数のライブラリの場合は計算がより複雑になり、以下にも示されています。攻撃者が 1 つのライブラリのみを使用する場合は、より複雑な式を簡略化したものです。。
これらの値は、 lの値が大きい場合でも低い傾向があり、最も重要なのは、攻撃者は通常C 標準ライブラリしか使用できないため、多くの場合、しかし、ライブラリの数が少なくても、ここで得られるエントロピーはわずかです。そのため、ライブラリのロード順序のランダム化とVMAアドレスのランダム化を組み合わせることで、さらにエントロピーを少し増やすことができる可能性があります。これらの追加エントロピーは、他のmmap()セグメントには適用されず、ライブラリにのみ適用されます。
攻撃者は、ランダム化されたアドレス空間に存在するエントロピーを減少させるために、単純な情報漏洩から、1回の攻撃で複数のビットのエントロピーを攻撃する(ヒープスプレー攻撃など)まで、さまざまな手法を用いる可能性があります。これに対してできることはほとんどありません。
フォーマット文字列の脆弱性を利用すれば、メモリレイアウトに関する情報を漏洩させることが可能です。printfなどのフォーマット文字列関数は、可変引数リストを使用して処理を実行します。フォーマット指定子は、引数リストの構造を記述します。引数の渡し方の一般的な仕組み上、各フォーマット指定子はスタックフレームの先頭に近づいていきます。最終的に、戻りポインタとスタックフレームポインタを抽出することで、脆弱性のあるライブラリのアドレスと既知のスタックフレームのアドレスが明らかになります。これにより、ライブラリやスタックのランダム化が攻撃者にとって障害とならなくなる可能性があります。
スタックまたはヒープのエントロピーを減少させることもできます。スタックは通常16バイトにアラインメントされる必要があり、これが最小のランダム化間隔となります。一方、ヒープは通常4096バイトのページアラインメントが必要です。攻撃を試みるとき、これらの間隔で重複した攻撃をアラインメントすることが可能です。シェルコードインジェクションでNOPスライドを使用することができ、システムに戻ろうとするときに文字列「 」を任意の数のスラッシュ「 」に置き換えることができます。削除されるビット数は正確に/bin/sh////////bin/shn個の区間が攻撃された。
このような減少は、スタックまたはヒープ内のデータ量によって制限されます。たとえば、スタックは通常、8 MB [ 9 ]までで、それよりはるかに少なくなります。これにより、最大で19 ビットだが、より控えめな推定では8~ 4-10ビットに対応する10ビット16 KB [ 9 ]のスタックスタッフィング。一方、ヒープはメモリ割り当ての動作によって制限されます。glibc の場合、 128 KB を超える割り当てはmmap を使用して作成され、攻撃者は 5ビットの削減に制限されます。これは総当たり攻撃の際の制限要因でもあります。実行する攻撃の数は減らすことができますが、攻撃のサイズは十分に大きくなるため、状況によっては侵入検知システムにその動作が明らかになる可能性があります。
ASLRで保護されたアドレスは、様々なサイドチャネル攻撃によって漏洩する可能性があり、その場合、ASLRによる保護の有効性が失われます。最近の攻撃では、CPUの分岐ターゲット予測バッファ(BTB)やメモリ管理ユニット(MMU)のページテーブルから漏洩した情報が利用されています。この種のASLR攻撃を緩和できるかどうかは明らかではありません。もし緩和できない場合、ASLRの利点は低下するか、あるいは完全に失われます。
2024年8月、Linux、macOS、Windowsなどの主要なデスクトッププラットフォームを実証的に分析した論文[ 10 ]が発表されました。この論文では、さまざまなプロセス、スレッド、システム再起動におけるメモリオブジェクトの配置の変動性を調べています。その結果、2024年時点でLinuxディストリビューションのように堅牢なランダム化を提供するシステムもあれば、WindowsやmacOSのように実行可能コードやライブラリなどの重要な領域を適切にランダム化できないシステムもあることが分かりました。さらに、Linux 5.18バージョン以降、ライブラリのエントロピーが大幅に減少していることが分かり、攻撃者が悪用を著しく複雑化するために利用できる相関パスが特定されました。
いくつかの主要な汎用オペレーティングシステムはASLRを実装している。
Android 4.0 Ice Cream Sandwich では、メモリ管理の問題によるエクスプロイトからシステムおよびサードパーティ アプリケーションを保護するために、アドレス空間レイアウトランダム化 (ASLR) が提供されています。位置独立実行可能ファイルのサポートは Android 4.1 で追加されました。[ 11 ] Android 5.0 では、非 PIE サポートが廃止され、すべての動的にリンクされたバイナリが位置独立である必要があるようになりました。[ 12 ] [ 13 ]ライブラリのロード順序ランダム化は、2015 年 10 月 26 日に Android オープンソース プロジェクトに受け入れられ、[ 8 ] Android 7.0 リリースに含まれました。
DragonFly BSDには、OpenBSDのモデルに基づいたASLRの実装があり、2010年に追加された。[ 14 ] デフォルトでは無効になっており、sysctl vm.randomize_mmapを1に設定することで有効にできる。
ASLR のサポートはFreeBSD 13.0 で登場しました。[ 15 ] [ 16 ] 13.2 以降はデフォルトで有効になっています。[ 17 ]
AppleはiOS 4.3(2011年3月リリース)でASLRを導入した。[ 18 ]
KASLRはiOS 6で導入されました。[ 19 ] ランダム化されたカーネルベースは0x01000000 + ((1+0xRR) * 0x00200000)、0xRRiBoot(iOSブートローダーの第2段階)によって生成されたSHA1(ランダムデータ)からのランダムなバイトです。[ 20 ]
Linuxカーネルは、2005年6月にリリースされたカーネルバージョン2.6.12以降、デフォルトで弱い形式のASLRを有効にしています。[ 21 ] LinuxカーネルへのPaXおよびExec Shieldパッチセットは、より完全な実装を提供します。Linux用のExec Shieldパッチは、16バイトの期間に19ビットのスタックエントロピーと、4096バイトの1ページ期間に8ビットのmmapベースランダム化を提供します。これにより、スタックベースは524,288個の可能な位置を含む8MB幅の領域に配置され、mmapベースは256個の可能な位置を含む1MB幅の領域に配置されます。
ASLR は、実行ドメインを変更することで特定のプロセスに対して無効にすることができますpersonality(2)。[ 22 ] sysctl のオプションのいくつかは、メインライン ASLR の動作を制御します。たとえば、はランダム化するものkernel.randomize_va_spaceを制御します。最も強力なオプションは 2 です。は mmapに対してランダム化するビット数を制御します。[ 23 ]vm.mmap_rnd_bits
位置独立実行可能ファイル(PIE) は、メイン実行可能バイナリにランダムなベースアドレスを実装するもので、2004 年 4 月 18 日から運用されています。これにより、共有ライブラリに使用されているものと同じアドレスのランダム性がメイン実行可能ファイルにも適用されます。PIE 機能は、同じ実行可能ファイルに対してプリリンク機能と併用することはできません。プリリンクツールは、実行時ではなくプリリンク時にランダム化を実装します。これは、プリリンクが動的リンカがライブラリの再配置処理を行う前に処理することを目的としており、再配置処理をプログラムの複数回の実行に対して一度だけ実行できるようにするためです。したがって、実際のアドレス空間のランダム化は、プリリンクの目的を損なうことになります。
2014 年、 Marco-Gisbert と Ripoll は、 PIE 実行可能ファイルの Linux ASLR を弱体化させるoffset2lib技術を公開しました。Linux カーネルは、ライブラリの直後に PIE 実行可能ファイルをロードします。その結果、実行可能ファイルとライブラリ関数の間に固定のオフセットが存在します。攻撃者が実行可能ファイル内の関数のアドレスを見つける方法を見つけると、ライブラリのアドレスもわかります。彼らは、400 回未満の試行でアドレスを見つける攻撃を実証しました。彼らは、randomize_va_space=3ライブラリに対する実行可能ファイルの配置をランダム化する新しいオプションを提案しましたが、[ 6 ] 2024 年現在、まだアップストリームに組み込まれていません。[ 24 ]
2022 年 5 月にリリースされた Linux カーネル 5.18 では、32 ビットと 64 ビット両方の実装の有効性が低下しました。Linux ファイルシステムは、thp_get_unmapped_areaファイルベースのmmapに応答するために呼び出しを行います。5.18 の変更により、2 MiB を超えるファイル は 2 MiB にアラインされたアドレスを返すようになり、巨大ページ によってバックアップされる可能性があります。(以前は、アラインメントの増加は Direct Access (DAX) マッピングにのみ適用されていました。) 一方、C ライブラリ (libc) は時間の経過とともにサイズが大きくなり、この 2 MiB のしきい値を超えているため、以前のように (通常) 4 KiB のページ境界にアラインされる代わりに、これらのライブラリは現在 2 MiB にアラインされています。これは、9 ビットのエントロピーの損失です。32 ビット Linux の場合、多くのディストリビューションでは libc の配置にランダム化がまったく行われていません。64 ビット Linux の場合、28 ビットのエントロピーが 19 ビットに減少します。これに対し、Ubuntu は設定値を上げました。[ 25 ] Martin Doucha は、この問題を検出するためにLinux Test Project のテストケースを追加しました。[ 26 ] mmap_rnd_bits
カーネルアドレス空間レイアウトランダム化 (KASLR) は、起動時にカーネルコードが配置される場所をランダム化することで、Linux カーネルイメージのアドレス空間ランダム化を可能にします。[ 27 ] KASLR は、2014 年 3 月 30 日にリリースされたカーネル バージョン 3.14 でLinux カーネルのメインラインに統合されました。 [ 28 ]コンパイル時に、カーネルの起動パラメータの 1 つとしてnokaslr を指定することで、起動時に無効にすることができます。 [ 29 ]
x86プロセッサには、カーネル アドレスを漏洩させる可能性のあるサイドチャネル攻撃がいくつかあります。[ 30 ] [ 31 ] 2017 年後半には、これらの攻撃に対抗するためにカーネル ページ テーブル分離(KPTI 別名 KAISER) が開発されました。[ 32 ] [ 33 ]しかし、この方法は、分岐予測構造の衝突を利用するサイドチャネル攻撃から保護することはできません。[ 34 ]
2021年現在、よりきめ細かいカーネルアドレス空間レイアウトランダム化(または機能粒度KASLR、FGKASLR)は、KASLRを拡張して、機能を別々のセクションに配置し、起動時にそれらを再配置することで、機能レベルまでランダム化する計画です。[ 35 ]
Microsoft のWindows Vista ( 2006 年 11 月に製造開始、2007 年 1 月に一般提供開始) 以降では、ASLR が有効になっているのは、ASLR が有効になるように特別にリンクされた実行可能ファイルとダイナミックリンクライブラリのみです。 [ 36 ]HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\MoveImages互換性のために、他のアプリケーションではデフォルトでは有効になっていません。通常、古いソフトウェアのみが互換性がなく、レジストリエントリを編集するか、Microsoft のEnhanced Mitigation Experience Toolkit をインストールすることでASLR を完全に有効にすることができます。[ 37 ]
ヒープ、スタック、プロセス環境ブロック、スレッド環境ブロックの位置もランダム化されます。Symantec のセキュリティ ホワイトペーパーでは、32 ビット Windows Vista の ASLR は期待どおりに堅牢ではない可能性があると指摘されており、Microsoft もその実装に弱点があることを認めています。[ 38 ]
WehnTrust [ 39 ]やOzone [ 40 ]などのホストベースの侵入防止システムも、 Windows XPおよびWindows Server 2003オペレーティングシステム向けに ASLR を提供しています。WehnTrust はオープンソースです。[ 41 ] Ozone の実装の詳細は公開されていません。[ 42 ]
2012年2月[ 43 ]には、Windows 8以前の32ビットWindowsシステムにおけるASLRは、メモリ不足の状況ではその有効性が低下する可能性があることが指摘された。同様の効果は、同じ研究においてLinuxでも確認された。テストコードによってMac OS X 10.7.3システムがカーネルパニックを起こしたため、このシナリオにおけるASLRの動作は不明のままとなった。
ユーザーランドでの ASLR のサポートはNetBSD 5.0 (2009 年 4 月リリース) で登場し、[ 44 ] 2016 年 4 月の NetBSD-current ではデフォルトで有効になりました。[ 45 ]
amd64 のカーネル ASLR サポートは、2017 年 10 月に NetBSD-current に追加され、NetBSD は KASLR をサポートする最初の BSD システムとなりました。[ 46 ]
2003 年、OpenBSD は、強力な ASLR をサポートし、それをデフォルトで有効にした最初の主流オペレーティングシステムとなりました。[ 4 ] OpenBSD は、 PIEバイナリ のサポートを追加した 2008 年に ASLR サポートを完了しました。[ 47 ] OpenBSD 4.4 のmalloc(3)は、OpenBSD のmmapシステムコールの一部として実装された ASLR およびギャップページ機能を利用してセキュリティを向上させ、解放後使用バグを検出するように設計されました。[ 48 ] 2013 年にリリースされた OpenBSD 5.3 は、複数のハードウェア プラットフォームでデフォルトで位置独立実行可能ファイルを有効にした最初の主流オペレーティングシステムであり、OpenBSD 5.7 ではデフォルトで位置独立静的バイナリ (Static-PIE) が有効になりました。[ 47 ]
Mac OS X Leopard 10.5(2007年10月リリース)では、Appleはシステムライブラリのランダム化を導入した。[ 49 ]
Mac OS X Lion 10.7(2011年7月リリース)では、Appleは実装を拡張してすべてのアプリケーションをカバーし、「アドレス空間配置ランダム化(ASLR)はすべてのアプリケーションで改善されました。32ビットアプリでも利用可能になり(ヒープメモリ保護と同様)、64ビットおよび32ビットアプリケーションは攻撃に対してより耐性を持つようになりました。」と述べています。[ 50 ]
OS X Mountain Lion 10.8(2012年7月リリース)以降では、カーネル、kext、ゾーンを含むシステム全体がシステム起動時にランダムに再配置されます。[ 51 ]
ASLRはSolaris 11.1(2012年10月リリース)以降、 Solarisに導入されました。Solaris 11.1のASLRは、システム全体、ゾーンごと、またはバイナリごとに設定できます。[ 52 ]
分岐ターゲットバッファを利用したサイドチャネル攻撃により、 ASLR 保護を回避できることが実証された。[ 34 ] 2017 年に、 JavaScriptを使用したWeb ブラウザで ASLR を破ることができる「ASLR⊕Cache」と呼ばれる攻撃が実証された。[ 53 ]