web-dev-qa-db-ja.com

バッファオーバーフローを教える必要はもうありませんか?

生徒は、実行不可能なスタックをオフにし、カナリアをオフにし、ASLRをオフにすることは現実的な環境であることに懐疑的です。 PaX、DEP、W ^ Xなどがバッファオーバーフローの悪用を阻止するのに効果的である場合、それらについて学ぶことにはまだ価値がありますか?

44
Fixee

もちろんです。 [〜#〜] aslr [〜#〜] および [〜#〜] dep [〜#〜] は多層防御策です。それぞれを迂回できるエクスプロイトが存在します(実際の例については、IEに対して使用した Peter VreugdenhilのPwn2Ownエクスプロイトを参照 )。

ASLR for Windowsをバイパスするために必要なのは、情報開示の脆弱性だけです。これは、ロードされたDLL(プロセスがVreugdenhilを利用した最初の脆弱性でした)のベースアドレスを知らせます。) 、 ret-to-libc 攻撃を使用して、そのDLL内の任意の関数を呼び出すことができます。

結論:スタック(およびヒープ)オーバーフローは、今日でも絶対に関連しています。以前よりも悪用するのは困難ですが、依然として関連性があります。

@ Larry'sと@SteveSの優れた簡潔な回答に加えて、非常に重要なポイントを指摘したいと思います。

生徒は、実行不可能なスタックをオフにし、カナリアをオフにし、ASLRをオフにすることは現実的な環境であることに懐疑的です。

うまくいけば、これはあなたの学生のシステムに当てはまります。
しかし、これ以外の国では、残念ながらこれはまだ非常に一般的です。これらをサポートしないプラットフォームに加えて、これらを停止する必要がある貧弱なビルド製品、古いバージョンのOS、さらには単に誤った設定さえあります。
それでもvery現実的に、悲しいことに。

その上、教育的視点からのコメントがさらに2つあります。
1。 somebody防御を構築する必要がありますよね?
2。仮に彼らが正しかったとしても-you only need pointers in C/C++は、Java開発者が学ぶべきではない方法を意味するわけではありません。これらはコンピュータ内部で機能しますよね?

18
AviD

はい。バッファオーバーフローが悪用に成功するシステムとは別に、バッファオーバーフローに関する完全な説明は、常にセキュリティについての考え方を示す優れた方法です。アプリケーションの実行方法に集中する代わりに、アプリケーションを脱線させるために何ができるかを見てください。

また、スタックの実行やインストールする悲鳴を上げるカナリアの数に関係なく、バッファオーバーフローはバグです。これらのセキュリティ機能はすべて、バグのconsequencesを変更するだけです。リモートシェルの代わりに、アプリケーションを即座にクラッシュさせるだけです。アプリケーションのクラッシュ(特にリモートでトリガーできるクラッシュ)を気にしないことは、せいぜいずさんなプログラミングです。私の時計にはありません!

完全を期すために、実行不可能なスタックとカナリアはバッファオーバーフローを防止しません。バッファオーバーフローを悪用する簡単な方法のいくつかを止めただけです。従来のバッファオーバーフローは、戻りアドレスを、バッファをオーバーフローしたデータの一部として読み込まれる悪意のあるコードへのポインタに置き換えることです。悪意のあるコードは、関数が戻るときに実行されます。実行不可能なスタックとは、攻撃者が自分のコードをスタックに配置できないことを意味します(標準ライブラリのexecve()実装などのライブラリコードへのジャンプを手配する必要があります)。カナリアは、スタックバッファがオーバーフローした場合にリターンアドレスが使用されないようにします(オーバーフローが「単純」であると仮定すると、連続したデータのチャンク)。ただし、オーバーフローは、関数ポインター(特にC++のコンテキスト)を含む他のデータを上書きする可能性もあります。

17
Thomas Pornin

もちろんです。これらが問題の解決策であることを彼らが知っているだけでは十分ではありません。彼らは、それらが問題の解決方法と理由を知っている必要があります。

さらに、すべてのプラットフォームがこれらのテクノロジーをサポートしているわけではありません。

10
Steve

最近バッファオーバーフロー攻撃について深く学び始めた学生の視点からお答えしたいと思います。私も同じ懸念を抱いており、バッファオーバーフロー攻撃について学ぶことの利点に疑問を抱いていましたが、私はそれについて理解することをどれだけ学んだかを考えると、それを選んだことを非常に嬉しく思います。

これまでのところ、私はしなければなりませんでした:

  1. X86アセンブリを学ぶ-主にUbuntuベース
  2. Cプログラミングを学ぶ
  3. Gdbで忍者になる
  4. シェルコードを理解する
  5. 私ができるすべてのITセキュリティフォーラムを探し、ソフトウェア/オペレーティングシステムをより安全にするプロセスを学ぶ

これらのスキルは非常に移転可能であり、後悔はありません。残念ながら、私にはこれを教えてくれる人はいません。私は私のマスターのプロジェクトのためにビデオチュートリアルとサンプルコードでそれをラフしなければなりませんでした。バッファオーバーフロー攻撃は、5〜10年前よりもITセキュリティの懸念事項ではないかもしれませんが、より複雑な脅威や現代の脅威について学ぶための足がかりとして役立つ可能性があります。

7
SunnyNewb

ここにはすでにすばらしい答えがあるので、それらを再び取り上げることはしません。ただし、ここではバッファオーバーフローを防止するメカニズムについて説明しているので、生徒に伝えたいことを強調しておきます。

プログラムがJavaはではないで記述されているからといって、バッファオーバーフローがないことを意味します。Java仮想マシン自体はJavaで実装されていません;(おそらく)CまたはC++で実装されており、他のプログラムと同じようにバッファーオーバーフローが発生する傾向があります。

その上に JVMの多くの実装 があります。修正するすべての問題について、まだ脆弱である可能性が高いさらに10の問題があります。

私は石鹸箱のあちこちを旅行しただけではなかったことを願っています.... :-)

7
Jeremy Powell

いいえ、バッファオーバーフローを教えません。メモリ破損を教えます。悪用プリミティブを教える。はい、彼らは歴史も知る必要がありますが、それはクラスの半分以上を占めるべきではありません。実際の宿題になると、すべてのメモリ保護を有効にして課題を与えますが、脆弱なサーバーを弱くする可能性があります。いくつかのメモリの開示により、さまざまなオフセットでヒントが得られます。

彼らはまた、多くのメモリ保護はほとんどが仕掛けであり、多くの場合、「ランダムオフセット」は、思ったほどランダムではないことを理解する必要があります。彼らはバグを認識する方法を学び、彼らが知っていることを突き刺さなければならないバグを使って、彼らが望むものにたどり着けるようにしなければなりません。

リターンアドレスではなく関数ポインタを上書きすることを考慮し、スタック/ヒープ上のシェルコードにジャンプするのではなく、既知の実行可能コード(ret2libc、ROP)にジャンプする必要があります。

3
pierce

大学生でc ++クラスから生まれたばかりなので、そうではないことはわかっていますが、私の教授は、バッファオーバーフローとその防止方法について教えることに特に重点を置いたので、引き続き教えていただくことをお勧めしますプログラミングを教えるコースでバッファオーバーフローが発生します。害を及ぼすことはありません。

1
Todd-ProNoob