DEPの仕組みとその回避手法:Beyond Zero-day Attacks(5)(2/3 ページ)
ゼロデイ攻撃をめぐる攻防、第5回はコードエリア以外でのプログラム実行を防ぐDEP(Data Execution Prevention)を取り上げます。
DEPを回避する――Return to Libc攻撃
DEPが有効になっているモジュールに対する攻撃手法の一つとして利用されるのが、「Return to Libc」と呼ばれる攻撃です。
Libcとは、標準Cライブラリの意味で、Windowsにおいては標準的なAPIと考えていただいて問題ありません。Return to Libcは、スタックに展開したShellcodeのアドレスの代わりに、任意の標準APIを任意のパラメーターで呼び出します。上書きするスタックの構造を工夫することで、複数のAPIを呼び出すことも可能です。
Return to Libcで、コードとして実行されるのは、コードエリアにある標準のAPIであるため、データエリアでの実行を防止するDEPは機能しません。
Return to Libc単体ではあまり多くのことはできないので、さほど有効性が高くないように思われますが、Return to Libcを使ってDEPを無効にするAPIを呼び出すことで、大きな効果を発揮します。つまり、Return to Libcで、DEPを無効にし、その後にスタックエリアやヒープエリアに展開したShellcodeに実行を移すことで、これまで通りのDEPの影響を受けずに、攻撃を実施することができるようになります。
Return to Libcを使って、DEPを解除する手法として、VirtualProtectというAPIを利用する手法が公開されています(図5)。
この例では、「VitrualProtect」を呼び出すことで、Shellcodeを展開した領域を実行可能にした後に、Shellcodeにジャンプ(return)していますが、少し分かりにくいと思うので、この攻撃の動きを解説しましょう。
図5の1、2、3はそれぞれ次のような動きになります。
- 脆弱な関数の戻り番地を、VirtualProtectのアドレスに書き換える
- VitrualProtectは、正規に呼び出された際と同様にretで戻り、ESPがShellcodeのアドレスを指すことになるので、“jmp esp”を命令のアドレスをEIPに相当する+0バイト目にセットし、その後ろにShellcodeを“実行可能”=DEPを無効にするための引数をセットしている。なお、絶対アドレスではなく、“jmp esp”を使うことで、スタックの絶対アドレスにかかわらず、Shellcodeを実行することが可能になる
- VirtualProtectが戻り番地として、Shellcodeのアドレス(Address of jmp esp)を読み込むため、“jmp esp”が実行され、DEPが無効となった状態でShellcodeに制御が移動する。
VirtualProtect 呼び出し側のプロセスの仮想アドレス空間内のコミット済みページ領域に対するアクセス保護の状態を変更します。 任意のプロセスのアクセス保護を変更するには、VirtualProtectEx 関数を使います。 BOOL VirtualProtect( LPVOID lpAddress, // コミット済みページ領域のアドレス DWORD dwSize, // 領域のサイズ DWORD flNewProtect, // 希望のアクセス保護 PDWORD lpflOldProtect // 従来のアクセス保護を取得する変数のアドレス );
関連リンク
VirtualProtect(Microsoft Developer Network)
http://msdn.microsoft.com/ja-jp/library/cc430214.aspx
また、オーバーライトするスタックの作り方によっては、複数のAPIを順次呼び出すことも可能です。図6は、NtSetInformationProcessを使って、プロセス全体がDEPの影響を受けないようにした上で、Shellcodeを呼び出している例です。
Copyright © ITmedia, Inc. All Rights Reserved.