
Meltdownマイクロアーキテクチャ攻撃を実証するPoCデモとlibkdumpライブラリ。脆弱なIntel CPU上でカーネルメモリおよび物理メモリを漏洩させる。
このリポジトリには、Meltdown バグを実証するいくつかのアプリケーションが含まれています。バグの技術的な情報については、論文を参照してください:
このリポジトリ内のアプリケーションは、論文のために開発したライブラリである libkdump を使用してビルドされています。このライブラリは、環境の特定の特性に自動的に適応することで、バグの悪用を簡素化します。
このリポジトリには、Meltdown を実証するいくつかの動画が含まれています
このリポジトリには、さまざまなユースケースを実証する 5 つのデモが含まれています。すべてのデモは、Intel Core i7-6700K を搭載した Ubuntu 16.04 でテストされていますが、2010 年以降の最新の Intel CPU を搭載した任意の Linux システムで動作するはずです。
最良の結果を得るには、Intel TSX をサポートする高速な CPU (例: Intel Core i7-5xxx、i7-6xxx、i7-7xxx のいずれか) を推奨します。 さらに、各デモは 1 つの CPU コアに固定する必要があります (例: taskset を使用)。
前提条件として、マシンに glibc-static をインストールする必要があります。
RPM ベースのシステムの場合:
sudo yum install -y glibc-static
test)これは最も基本的なデモです。Meltdown を使用して、自身のアドレス空間からアクセス可能なアドレスを読み取りますが、分離メカニズムを破ることはありません。
このデモが動作しない場合、残りのデモもおそらく動作しません。理由は多岐にわたります。例えば、CPU が遅すぎる、アウトオブオーダー実行をサポートしていない、高分解能タイマーが十分に正確でない (特に VM 内)、オペレーティングシステムがカスタムシグナルハンドラをサポートしていない、などです。
make
taskset 0x1 ./test
次のような出力が表示された場合
Expect: Welcome to the wonderful world of microarchitectural attacks
Got: Welcome to the wonderful world of microarchitectural attacks
基本的なデモは動作しています。
kaslr)Linux カーネル 4.12 以降、KASLR (Kernel Address Space Layout Randomizaton) はデフォルトで有効になっています。これは、カーネルの位置 (および物理メモリ全体をマップする直接物理マップ) が再起動ごとに変わることを意味します。
このデモは、Meltdown を使用して直接物理マップの (秘密の) ランダム化を漏洩させます。このデモでは、プロセスを高速化するために root 権限が必要です。論文では、root 権限を必要としない変種が説明されています。
make
sudo taskset 0x1 ./kaslr
数秒後、次のような出力が表示されるはずです
[+] Direct physical map offset: 0xffff880000000000
reliability)このデモは、物理メモリをどの程度信頼性高く読み取れるかをテストします。このデモでは、直接物理マップのオフセット (例: デモ #2 から) が必要か、カーネルコマンドラインで nokaslr を指定して KASLR を無効にする必要があります。
reliability をビルドして起動します。KASLR が有効な場合、最初のパラメータは直接物理マップのオフセットです。それ以外の場合、プログラムはパラメータを必要としません。
make
sudo taskset 0x1 ./reliability 0xffff880000000000
数秒後、次のような出力が得られるはずです:
[-] Success rate: 99.93% (read 1354 values)
physical_reader)このデモは、物理メモリを直接読み取ることで、別のプロセスからメモリを読み取ります。このデモでは、直接物理マップのオフセット (例: デモ #2 から) が必要か、カーネルコマンドラインで nokaslr を指定して KASLR を無効にする必要があります。
原則として、このプログラムは任意の物理アドレスを読み取ることができます。ただし、物理メモリには人間が読めないデータが多く含まれているため、人間が読める文字列をメモリに配置し、その文字列の物理アドレスを直接提供するテストツール (secret) を用意しています。
デモでは、まず secret を (root として) 実行して、人間が読める文字列の物理アドレスを取得します:
make
sudo ./secret
次のような出力が表示されるはずです:
[+] Secret: If you can read this, this is really bad
[+] Physical address of secret: 0x390fff400
[+] Exit with Ctrl+C if you are done reading the secret
secret プログラムが実行されている間に、physical_reader を起動します。最初のパラメータは secret によって出力された物理アドレスです。KASLR が無効になっていない場合、2 番目のパラメータは直接物理マップのオフセットです。
taskset 0x1 ./physical_reader 0x390fff400 0xffff880000000000
数秒後、次のような出力が得られるはずです:
[+] Physical address : 0x390fff400
[+] Physical offset : 0xffff880000000000
[+] Reading virtual address: 0xffff880390fff400
If you can read this, this is really bad
memdump)このデモは、メモリの内容をダンプします。デモ #3 と #4 と同様に、直接物理マップを使用して、物理メモリの内容を hexdump 形式でダンプします。
繰り返しになりますが、物理メモリには人間が読めない内容が多く含まれているため、大量の物理メモリを人間が読める文字列で埋めるテストツールを用意しています。
デモでは、まず memory_filler を実行して、メモリを人間が読める文字列で埋めます。最初の引数は、埋めるメモリの量 (ギガバイト単位) です。
make
./memory_filler 9
次に、memdump ツールを実行してメモリの内容をダンプします。以前に memory_filler を実行した場合、いくつかの文字列断片が表示されるはずです。
複数のタブで Firefox または Chrome を実行している場合、開いている、または最近閉じたウェブサイトの一部も表示されることがあります。
最初のパラメータは、ダンプを開始する物理アドレスです (空のままにすると、最初のギガバイトから開始します)。2 番目のパラメータは、読み取りたいバイト数です。すべてを読み取るには -1 を指定します。KASLR が無効になっていない場合、3 番目のパラメータは直接物理マップのオフセットです。
taskset 0x1 ./memdump 0x240000000 -1 0xffff880000000000 # start at 9 GB
メモリの一部の hexdump (パスワードなどの秘密が含まれている可能性もあります。論文の例を参照) が得られるはずです。例:
240001c9f: | 00 6d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .m.............. |
24000262f: | 00 7d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .}.............. |
24000271f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 6e 20 75 | ............en u |
24000272f: | 73 65 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 | ser space and ke |
24000273f: | 72 6e 65 6c 57 65 6c 63 6f 6d 65 20 74 6f 20 74 | rnelWelcome to t |
24000298f: | 00 61 72 79 20 62 65 74 77 65 65 6e 20 75 73 65 | .ary between use |
24000299f: | 72 20 73 70 61 63 65 20 61 6e 64 20 6b 65 72 6e | r space and kern |
2400029af: | 65 6c 42 75 72 6e 20 61 66 74 65 72 20 72 65 61 | elBurn after rea |
2400029bf: | 64 69 6e 67 20 74 68 69 73 20 73 74 72 69 6e 67 | ding this string |
240002dcf: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c8 | ................ |
2400038af: | 6a 75 73 74 20 73 70 69 65 64 20 6f 6e 20 61 00 | just spied on a. |
240003c8f: | 00 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24000412f: | 00 00 00 00 00 00 00 00 00 00 00 00 65 74 73 2e | ............ets. |
24000413f: | 2e 2e 57 65 6c 63 6f 6d 65 20 74 6f 20 74 68 65 | ..Welcome to the |
2400042ff: | 00 00 00 00 00 00 00 00 00 6e 67 72 61 74 75 6c | .........ngratul |
24000430f: | 61 74 69 6f 6e 73 2c 20 79 6f 75 20 6a 75 73 74 | ations, you just |
24000431f: | 20 73 70 69 65 64 20 6f 6e 20 61 6e 20 61 70 70 | spied on an app |
Windows / Ubuntu on Windows (WSL) / Mac OS で動作しますか?
いいえ。この PoC は Linux でのみ動作します。これは、直接物理マップなど、Linux カーネルに固有の特性を使用しているためです。
仮想マシンで PoC を実行できますか?
はい、PoC は仮想マシンでも動作します。ただし、仮想マシンによって導入される追加のレイヤーのため、ネイティブハードウェアほど良好に動作しない可能性があります。
KASLR プログラム (kaslr) がオフセットを見つけられません!
kaslr ツールは高速化のためにごく少数の測定しか行いません。オフセットが見つからない場合、2 つの可能性があります:
kaslr.c のリトライ回数を変更する: config.retries = 1000;kaslr_offset のカーネルモジュールを使用して、カーネルから直接オフセットを読み取る。カーネルのカーネルヘッダーをインストールし (sudo apt-get install linux-headers-`uname -r` )、sudo ./direct_physical_map.sh を実行しますキャッシュされていないメモリで動作すると言いましたが、すべてのデモでメモリがキャッシュされることを保証しています!
キャッシュされていないメモリで動作させるのはより難しく、しばしばパラメータの微調整が必要です。したがって、PoC では再現を容易にするためにメモリがキャッシュされることを保証しています。ただし、値をキャッシュするコードを単純に削除し、clflush に置き換えることで、キャッシュされていないメモリでエクスプロイトをテストできます (例については動画 #5 を参照)。
Google による元のブログ投稿にはありませんが、これは独立した研究者によっても確認されています (例: Alex Ionescu、Raphael Carvalho、Pavel Boldin)。
警告 #1: このコードは現状のまま提供されます。このコードによって引き起こされるあらゆるリスクから、あなた自身、あなたの財産とデータ、および他者を保護する責任はあなたにあります。このコードは、あなたのマシンで予期しない、望ましくない動作を引き起こす可能性があります。このコードは、あなたのマシン上の脆弱性を検出しない可能性があります。
警告 #2: コンピュータが Meltdown バグに対して脆弱であることが判明した場合、それをマルチユーザーシステムとして使用することを避けたいと思うかもしれません。Meltdown は CPU のメモリ保護を破ります。Meltdown バグに対して脆弱なマシンでは、1 つのプロセスが他のプロセスまたはカーネルによって使用されているすべてのページを読み取ることができます。
警告 #3: このコードはテスト目的のみです。いかなる本番システムでも実行しないでください。他の人物または組織によって使用される可能性のあるシステムで実行しないでください。
自分のコンピュータでは動作しません。どうすればよいですか?
これには多くの異なる理由が考えられます。試せるいくつかのことを集めました:
libkdump/libkdump.c の #define MELTDOWN meltdown_nonull の行で変更できます。例えば、meltdown_nonull の代わりに meltdown を試してみてください。これは一部のマシンではるかにうまく動作します (ただし、他のマシンではまったく動作しません)。stress -i 2 でツール stress を実行します (または、コア数に応じて i パラメータに他の値を使用します)。