web-dev-qa-db-ja.com

DEP / ASLRをバイパスする「ポインターのリーク」の仕組み

DEP/ASLRの動作を回避するための「リークポインター」の手掛かりを誰かが私にいくつかの手がかりを与えることができるかどうか疑問に思っていました。私は読む ここ

DEPとASLRを確実にバイパスする唯一の方法は、ポインターリークを経由することです。これは、信頼できる場所にあるスタック上の値を使用して、使用可能な関数ポインターまたはROPガジェットを見つける可能性がある状況です。これが完了すると、両方の保護メカニズムを確実にバイパスするペイロードを作成できる場合があります。

これがどのように達成されるかは、私にとって一種の謎です。バッファオーバーフローがあります。EIPとスタックの内容まで上書きできます。スタックに信頼できる関数ポインタまたはコードポインタがあり、これが格納されている場所がわかります。また、この場所がわかっている場合はどうすればよいですか。このアドレスをEIPに入れますか? EIPをその信頼できる場所に変更できない場合、実行ストリームを制御できません

18
John Smith

「漏洩ポインタ」またはより一般的に「ダングリングポインタ」として知られているものは、階層化されたセキュリティシステムをバイパスする攻撃チェーンを作成するのに役立ちます。

DEPの背後にある考え方は、この領域のシェルコードを実行できないように、メモリの領域を非実行可能にすることです。 DEPだけでバイパスするのは本当に簡単で、libに戻り、好きな関数を呼び出すことができます。system()がお気に入りです。

ただし、Windowsでは [〜#〜] aslr [〜#〜] 有効なライブラリにはランダムなメモリ空間があるため、攻撃者はsystem()のメモリアドレスを知ることができません。関数、それを呼び出すことはできません。 ASLRの背後にある考え方は、ジャンプ先がわからない場合にEIPを制御できるかどうかは関係ありません

ランダム化されたメモリの領域の位置を読み取ることができると、ASLRの保護が損なわれます。これで、信頼できるジャンプ位置が得られます。これは、さまざまな方法で実現できます。バッファオーバーフローを使用してnullターミネーターを上書きし、配列の末尾を超えてreadをIEに対してpwn2ownで使用しました。しかし、実際に最も一般的な手法は、 Dangling Pointer を使用することです。これは、ASLRにもかかわらず、読み取り/書き込み、または有効なメモリ位置の実行にさえ使用できます。

ASLRを使用しても、すべてのメモリ位置がランダム化されるわけではありません。実際、実行可能バイナリは予測可能なレイアウトを持っているため、 ROPチェーン で実行可能ファイルを自己に対して使用できます。ただし、特にターゲットバイナリが非常に小さい場合は、有用なROPガジェットを見つけるのが難しい場合があります。有用なROPチェーンを構築できない場合、ぶら下がりポインタなどのメモリ開示の脆弱性は、優れた攻撃方法です。 ASLRはページの場所(メモリアドレスの最初の数バイト)のみをランダム化することに注意することが重要です。このページ内の領域にシェルコードを入力できる場合、リークされたメモリを使用してシェルコードを正確に実行できる可能性があります。ベースとしてアドレスし、うまくいけばあなたのシェルコードはこのランダムな場所のオフセットにあります。

一連のメモリ操作の脆弱性の使用は、JavaScriptなどのスクリプト環境内でのみ可能です。

13
rook

ASLRは、メモリ内のオブジェクトの場所をランダム化します。たとえば、ヒープがメモリ内のランダムなオフセットに移動される場合があります。

どういうわけかヒープ内のオブジェクトのアドレスを学習できた場合は、メモリ内のヒープの場所に関する多くの情報を取得しています。これで、ヒープ内の他のオブジェクトの場所を予測できるようになります。その時点で、ASLRのランダム化は役に立たなくなります。したがって、ポインター(そのアドレス)の値を明らかにする情報開示の脆弱性は、ASLRを破壊するために使用される可能性があります。

ポインタのアドレスはどのようにリークできますか? 1つの方法は、フォーマット文字列の脆弱性を利用することです。あなたがこれを次のようにするとします:

_printf(msg);
_

ここで、msgは攻撃者が制御するメッセージであり、攻撃者はstdoutを読み取ることができます。次に、攻撃者はメッセージが文字列_"%d"_であることを指定できます。これにより、スタック上のランダムデータの値が明らかになります。これは有効なポインタである可能性があります。 (なぜ?printf()は別の引数を渡したと考え、スタックを調べてその追加の引数の値を見つけて出力するからです。実際に別の引数を渡さなかったということはわかりません。無関係なメモリを介してトロール。)

この種の情報が漏えいする方法は他にもありますが、漏えいした場合、ASLRをバイパスすることがよくあります。 ASLRをバイパスできるようになると、標準的な手法を使用してバッファオーバーランの脆弱性を悪用することができます。したがって、これらの種類の情報漏えいの脆弱性は、アプリケーションで持つのは良いことではありません。

5
D.W.