アーカイブ

第7章 7.ページングおよびメモリダンプ対策

公開日:2007年9月26日

独立行政法人情報処理推進機構
セキュリティセンター

本ページの情報は2007年9月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。

仮想メモリを採用しているオペレーティングシステムでは、ページング処理によってメモリ内容の一部または全部がディスク上の領域に書き出されるのが通常である。また、プログラムが異常終了した際に、メモリのダンプがファイルとしてディスクに書き出される。

これらのディスク領域にアクセスでき、内容を読み出すことのできる者によって、プログラムが扱っていた秘密情報が盗み出されるおそれがある。

ページング領域からの情報流出対策

多くのオペレーティングシステムが採用している仮想メモリシステムにおいては、プロセスが多数起動される等により物理メモリが不足してくると、メモリ内容の一部がハードディスクの特定領域(ページング領域)に一時的に退避(ページアウト)されるようになる。このページング領域を悪意のある第三者が読み出すことにより、秘密情報が盗まれるおそれがある。

仮想メモリシステムのAPIを使う等により、特定の情報はページング領域にページアウトされないようにする方法がある。

仮想メモリのページをロックをすればディスクには書かれなくなるが、Windows、Unixのいずれの場合も、次のような注意が必要である。

  • メモリのロックは、メモリページ単位に行われる
  • ひとつのプロセスで同時にロックできるページ数には上限がある
  • ロックするメモリ量を制限しないと、システム全体のパフォーマンスに影響する
  • 図7-7: ページング領域からの情報流出対策

(1) Unix, GNU/Linuxのメモリロック

Unix, GNU/Linuxでは、システムコールのメモリロック mlock() を使うと、指定した物理メモリをロックでき、ディスクにスワップされるのを防ぐことができる。

mlock() は、次のようにして呼び出す。

const void *lock_addr; // ロックするエリアの先頭アドレス
size_t   lock_size; // ロックするエリアのサイズ
......
if (mlock (lock_addr,lock_size) == -1)
 // ロックに失敗
else
 // ロックに成功

注意:

  • mlock() システムコールを行うには、スーパーユーザ特権が必要である
  • 子プロセスには、メモリのロックは継承されない

(2) Windowsのメモリロック

Windowsでは、 VirtualLock() があり、mlock() と同様にスワップを防ぐことができる。

VirtualLock() は、次のようにして呼び出す。

LPVOID  lock_addr; // ロックするエリアの先頭アドレス
DWORD  lock_size; // ロックするエリアのサイズ
......
if (!VirtualLock(lock_addr, lock_size))
 // ロックに失敗
else
 // ロックに成功

メモリダンプの回避

プログラムの異常終了時にメモリダンプが自動生成されることがあるが、これはメモリ上に展開していたデータをファイルに書き出しており、このデータに秘密データがあると流出につながる可能性がある。

回避策としてメモリダンプを自動生成させない設定をするとともに、秘密データをメモリ上に平文でもつことを極力避けるようにする。

(1) コアファイル

Unix, Windows 等のシステムでは、プロセスに障害が発生するとコアファイル(core) を出力する。これは、障害のおきたプロセスのメモリイメージをディスク上のファイルに書き出したものであり、デバッグや保守のために用いられる。もし障害のおきたプロセスのメモリ上に秘密情報(例:ユーザが入力したパスワード等)が含まれていた場合は、コアファイルに秘密情報が含まれてしまう。

攻撃者は強制的にターゲットのプロセスをクラッシュさせ、コアファイルを生成させて秘密情報をディスクに書き出させる事が考えられる。よって、攻撃者がコアファイルを読み出せる環境にある場合は、プログラムがコアダンプするのを防ぐ必要がある。

(2) メモリダンプの抑制

1) setrlimit() を使用する(Unix)

コアファイルの生成を止めるには、次の例のようにプログラムから制御することができる。これは、システムコール setrlimit() を使用し、コアファイルの最大サイズを 0 にすることで、コアファイルを生成しないようにするものである。

[例]

void no_corefile(void) {
 struct rlimit no_core;
 no_core.rlim_cur = 0;  ←ソフトリミットを0に設定
 no_core.rlim_max = 0;  ←ハードリミットを0に設定
 if (setrlimit(RLIMIT_CORE, &no_core) == -1) { ←core ファイルの最大サイズを設定
  // エラー処理
 }
}

2) システムの設定を変更する(Windows)

Windowsの場合、Unix のようにプログラム単位にはコアダンプの制御はできない。Windows XPまででは、障害時にワトソン博士(Drwatson.exe)によって生成されるダンプがある。しかし、このファイルへアクセスできるユーザは、アクセス制御リスト(ACL)により、制限されている。また、OS 全体では下記の方法によりメモリダンプの生成を止めることができる。

  1. [マイ コンピュータ]の[プロパティ]で "システムプロパティ" を表示する
  2. [詳細設定]タブを選択し、"起動と回復"グループの[設定]を選択する
  3. "デバッグ情報の書き込み"グループ中のメモリダンプの出力区分から[(なし)]を選択する

ページング対策およびメモリダンプ対策のまとめ

ページング処理によってメモリ内容の一部または全部がディスク上の領域に書き出すような仮想メモリは、悪意のある第三者が読み出すことにより、秘密情報が盗まれるおそれがある。

対策としては、ディスクへの書き込みを行わないために、仮想メモリのページをロックをすることである。しかし、ページのロックには、ロックできるページ数等に条件や制限があるので、重要な情報を扱う所を中心にロックするようなデザインが必要である。

コアファイルは,障害発生時のプロセスのメモリイメージをそのまま保存したものである。このメモリイメージからパスワード等の秘密情報が漏洩する可能性がある。第三者からコアファイルを参照されないように厳重に管理する必要がある。もしそれが困難である場合、プログラム自身がcoreファイルを生成しないように設計すべきである(Unix)。