アドレス空間配置ランダム化(ASLR)は、2001年に初めて実装されたOS向けの安全対策です。現代の主要なOS(iOS、Android、Windows、macOS、Linux)にはASLRが搭載されています。しかし、先週、ASLRを回避する新たな手法が発見されました。これを踏まえ、心配する必要があるのでしょうか?
低レベルのプログラム知識がない場合、ASLRは分かりにくいかもしれません。まずは、仮想メモリの概念を理解することが必要です。
アドレス空間配置ランダム化(ASLR)は、OSに搭載されている記憶安全対策で、攻撃者のバッファオーバーフロー攻撃に備え、アプリが読み込まれるメモリの位置をランダムにして守ります。
多くのサイバー攻撃、特にゼロデイ攻撃の成功は、攻撃者がメモリ内のプロセスや領域の位置を把握あるいは推測できるかどうかにかかっています。ASLRはメモリ領域の位置を偶然に設定します。もし攻撃者が誤った場所を狙えば、対象のアプリがクラッシュし、攻撃が止まりOSに警告が出されます。
ASLRは2001年、Pax ProjectによってLinux向けに導入され、その後2007年のVistaからWindowsにも組み込まれました。それ以前は、アプリやプログラムのメモリ領域は固定または予測可能でした。
VistaにASLRを追加したことで、利用可能なメモリ領域は256通りに増え、攻撃者が正しい場所を見つける確率は256分の1となりました。AppleはMac OS X 10.5 LeopardからASLRを採用し、Apple iOSやGoogle Androidも2011年に利用を開始しました。
仮想メモリは多くの利点を持つ記憶管理技術ですが、もともとはプログラムをシンプルにするために作られました。例えば、4GBのRAM搭載PCでGoogle Chrome、Microsoft Word、その他のアプリを同時に開いたとします。これらのアプリは合計で4GBを超えるRAMを使用しますが、すべてが常に活発ではなく、同時にRAMへアクセスする必要もありません。
OSはアプリに対してページと呼ばれる単位でメモリを割り当てます。もし全ページをRAMに収めきれなければ、必要性が低いページがより大容量だが遅いハードドライブに保存されます。保存されたページが必要になると、RAM上の重要度の低いページと入れ替えられます。この処理をページングと呼び、Windowsの pagefile.sys ファイル名の由来となっています。
仮想メモリにより、アプリは記憶管理が容易になるとともに、安全性も向上します。アプリは他のプログラムがどこにデータを保存しているかや残りのRAM量を気にする必要がなく、必要に応じてOSに追加メモリを求めたり使わなくなったメモリを返したりできます。アプリが見るのは、自身専用の連続した仮想アドレスのブロックだけです。他のプログラムのメモリを覗くことは認められていません。
アプリがメモリにアクセスする際、OSに仮想アドレスを提示します。OSはCPUの記憶管理ユニット(MMU)と連携し、仮想アドレスと実際のアドレスの変換を行ってその情報を返します。アプリは直接RAMとやりとりすることはありません。
ASLR有効化は、安全性向上と24ビット、31ビット、64ビットのプライベート領域が減少するという妥協点です。24ビットおよび31ビットの仮想メモリの場合、利用可能なプライベート領域はそれぞれ最大63ページと255ページ減少します。プロセスが起動するには、指定されたアドレスサイズがこの縮小されたプライベート領域内で確保される必要があります。満たされない場合、ABEND 822が発生します。指定サイズが満たされても、プライベート領域の不足でプロセスが完了せず、ABEND 878が起こる可能性があります。
ASLR有効時にプロセスが必要とする24ビット、31ビットのプライベート領域が確保できるかを判断する一手段として、parmlib内でCSA境界の値を大きく指定する方法があります。24ビットおよび31ビットCSAの範囲を1M拡大すると、プライベート領域のサイズが1M減少し、ASLR下での最大削減量を上回ります。
ASLRでは、DLLの基準アドレスが起動時のランダム化に依存しています。つまり、ライブラリの基準アドレスは次回の再起動時にランダムに決まります。これは、メモリ情報漏洩やブルートフォース攻撃などの脆弱性と結びつき、攻撃者に悪用される弱点となります。
実行ファイルやDLLがASLR対応でない場合、ASLRは利用されません。Windows 8やWindows 10ではこの制限を克服しようと試みていますが(例:Windows 8におけるASLR強制)、例外が存在し、その結果、ASLRの効果が薄れる場合があります。古いWindows版や従来型のアプリでは特に影響を受けやすいです。また、32ビットシステムのASLRはエントロピーが低いため、ブルートフォース攻撃などに弱いと言えます。
ASLRは、攻撃者が狙ったメモリアドレスに確実に到達するのを防ぐことを狙っています。攻撃の捕捉ではなく、攻撃が成功しにくくなることを目的としており、シェルコードがメモリのランダム化により不適切な位置にジャンプすると、プログラムの動作は予測できなくなります。プロセスは例外を起こしたり、クラッシュ、ハング、または誤動作を引き起こす可能性があります。
ASLRは攻撃試行に関する警告を出しません。脆弱性が悪用され失敗しても、エラーや攻撃を示す兆候は表示されません。つまり、ASLRは攻撃が発生したかどうかを把握しません。
攻撃、悪用、シェルコードに関する情報は、詳細なフォレンジック調査に欠かせません。利用されたプロセス、メモリダンプ、コールスタックを分析することで、攻撃の特定や特徴付けが可能ですが、ASLRでは攻撃の発生や阻止の有無を示せないため、情報提供ができません。
Windows OSにASLRが導入されて以来、実際の攻撃やエクスプロイトで何度も回避されてきました。攻撃者は常にASLRの防御を突破する新たな手法を開発しており、回避手法としては、ASLR非対応モジュールでのROPチェーン(例:CVE-2013-1347)、JIT/NOPスプラッシング(例:CVE-2013-3346)、メモリ情報漏洩の脆弱性などが挙げられます。
2016年、SUNY Binghamtonとカリフォルニア大学リバーサイド校の研究者は、『Jump Over ASLR: Attacking Branch Predictors to Bypass ASLR』という論文を発表しました。論文では、分岐ターゲットバッファ(BTB)への攻撃手法が詳述されています。BTBは、予測により処理を高速化するプロセッサにとって重要な役割を担っており、研究者の手法を用いると、実行中のアプリ内の既知の分岐先位置を特定できます。この攻撃は、2013年初登場のIntel Haswellプロセッサ搭載のLinuxマシンで実証されましたが、現代のOSやプロセッサにも応用可能と考えられます。
結局のところ、パニックに陥る必要はありません。論文では、ハードウェアやOSのエンジニアがこのリスクを軽減するための複数の方法が示されました。より細かいASLRの手法は攻撃者にとって実施が困難となり、エントロピー(ランダム性)の増加によってJump Over攻撃が不可能になる可能性があります。恐らく、最新のOSやプロセッサはこの攻撃に対して耐性を持つでしょう。
ASLRが有効な場合、SAF権限を用いて特定のアドレス領域をASLRの対象外に設定することが可能です。FACILITYクラス内のIARRSM.EXEMPT.ASLR.jobnameオブジェクトにSAF READ権限を与えればプロセス全体を、IARRSM.EXEMPT.ASLR24.jobnameオブジェクトに与えれば24ビットASLRのみを除外できます。以下は、プロセスをASLRから完全に除外するコマンド例です:
Reclassify FACILITY IARRSM.EXEMPT.ASLR.jobname UACC(READ)
SETROPTS CLASSACT(FACILITY)
SETROPTS RACLIST(FACILITY) REFRESH
IPL処理中に早期に読み込まれるMASTERなど、一部のOSアドレス領域はランダム化されません。また、高い仮想メモリが使用される領域でも、読み込み割り当ての都合によりランダム化されない場合があります。プロセスのステップで、タスクツリーに属さない別のプロセスへ高容量の仮想メモリを割り当てると、割り当てメモリが次のステップまで維持され、OSが後続ステップでランダム化を実施しにくくなります。
ASLRを回避しようとする試み
ASLRには多くの利点があるものの、その回避の試みは一般的で、以下のような方法に分けられます:
ASLRは非常に価値が高く、特に64ビットシステムで正しく実装された場合、その効果が顕著です。回避の試みが完全に防げるわけではありませんが、OSの脆弱性の悪用を大いに難しくします。
最新情報を購読