DEPの仕組みとその回避手法:Beyond Zero-day Attacks(5)(1/3 ページ)
ゼロデイ攻撃をめぐる攻防、第5回はコードエリア以外でのプログラム実行を防ぐDEP(Data Execution Prevention)を取り上げます。
DEPという強力な防御手法の登場、そして……
これまで第2回では「スタックに対する攻撃」を、そして第3回、第4回の2回にわたり「ヒープに対する攻撃」を紹介してきました。これらの攻撃の対策として、実行ファイルを生成する段階で作成するコンパイラー、リンカによる対策と、実行時に機能するシステム(OSなど)レベルの対策を紹介しました。しかし、これらの対策を実施しても、脆弱性をなくし、攻撃を完全に防ぐことはできないのが実情です。
今回紹介するDEP(Data Execution Prevention)は、これまで紹介した対策手法とは異なるアプローチの対策で、脆弱性が存在し攻撃が成功したとしても、攻撃コード(Shellcode)の実行を阻止するというものです。
DEPはとても強力な手法です。複数の専門家の方から、WindowsにDEPが実装された際に「戦いは終わったと思った」と伺いました。それくらい強力な手法なのですが、それでもDEPを破る方法が編み出され、実装されてきました。
今回はこのDEPと、DEPの回避策を紹介しましょう。
DEPとは
DEP(Data Execution Prevention)は、その名前の通りデータエリアでのプログラムの実行を防止するという、ハードウェアで実装された機能です。これまで書いてきたように、正規のプログラムはコードエリア(セグメント)に読み込まれて実行されますが、攻撃コードは、主にスタックエリアやヒープエリアに書き込まれて実行されます(図1)。
これに対してDEPは、スタックエリアやヒープエリア、つまりコードエリア以外の領域でプログラムが実行されると、プログラムを異常終了させます。
第4回ではUse After Freeとヒープスプレーの手法をご紹介していますが(図2)、この例では「0x0c0d0c0d0」がアドレスと実行コードとして利用されています。DEPが有効である場合、インストラクションポインターが「0x0c0d0c0d」に移行した段階でDEPが機能し、プログラムを異常終了させることで攻撃コードの実行を防ぎます。
また、Safe SEHのように、コンパイル時に対策が行われていないモジュールに対する攻撃の場合(図3)でも、攻撃コード(Shellcode)が、スタックやヒープに展開されていれば、DEPによって攻撃を防ぐことが可能です。
DEPを回避する――DEPが無効なモジュールを攻撃する
防衛側の最終兵器と思われたDEPですが、まずは、コンパイル時に明示的にDEPを有効にする必要がある点が問題となりました。つまり、DEPが無効なモジュールがある場合、そのモジュールへの攻撃を行うことで、攻撃コードが実行できてしまいます。
全てのモジュールがコンパイル時にDEPを有効にしていれば解決する問題なのですが、いくつかの課題があります。まず、DEPを有効にするオプションがない時代にコンパイルされたプログラムは、DEPが無効なままで実行されます。また、システムリソースが貧弱な時代に開発されたプログラムの中には、データ領域上でプログラムを生成するものがあり、DEPを有効にすると動きません。
最近の環境で開発されたコードでは、このようなことはないと思いますが、誰も触るな!」といわれているような古いコードが組み込まれている場合、DEPを有効にするとこのコードが動かず、プロジェクト全体をDEPなしで構築する、という例はいまでもありそうな話です。
Windows Systemとしてみた場合、DEPは「OptIn(デフォルト)」「OptOut」「AlwaysOn」「AlwaysOff」の四つのモードを選ぶことができます。ここで記載しているような、DEPが無効になっているプログラムが攻撃を受けることを防ぐためには、「AlwaysOn」か「OptOut」に設定をすればよいわけですが、DEPを有効にすると動かないプログラムが出る可能性があるため、デフォルトの設定は「OptIn」になっています。
なお、Windows 8から導入されたWinRTアプリ(Windows ストアアプリ)は、後方互換を考慮する必要がないため、システムの設定にかかわらず常にDEPが有効となります。
Copyright © ITmedia, Inc. All Rights Reserved.