Apache のメモリから SSL の秘密鍵を取り出す

スポンサーリンク

以前、某所に置いたサーバで SSL の秘密鍵を誤消去 (リダイレクトで上書き) してしまい、えらい目にあった。

秘密鍵のファイル自体は消えてしまったものの、Apache は再起動しておらず、SSL も問題なく動作している。つまり、メモリ上のどこかで秘密鍵を保持しているだろうと考え、Apache の ML に助けを求めた。復元は絶望的だと思われたが、最終的に メモリから秘密鍵を取り出すことに成功した。もうそろそろ時効だろうと言うことで、その際の手順をメモしておく。

スポンサーリンク

手順

  1. ダミー (サンプル) の秘密鍵を数個生成する。
    $ openssl genrsa -des3 2048 > test1.key
    $ openssl rsa -outform der -in test1.key -out key1dec.bin
  2. 生成した秘密鍵をバイナリエディタで開くと、最初の 3 バイトが毎回「30 82 04」になっていることがわかる。つまりメモリからこれを探せば良い。
    $ od -tx1 key1dec.bin | head -n 1
    0000000 30 82 04 a3 02 01 00 02 82 01 01 00 9c e4 bd d2
  3. gdb の gcore で httpd のコアをダンプする。方法は以前のエントリに書いた。
  4. バイナリエディタで、ダンプしたコアから「30 82 04」を検索する。2 箇所見つかるが、片方は公開鍵なので、まともな文字列を含まない方がたぶん本物。
  5. 秘密鍵と思われる部分から、ダミーで生成した秘密鍵の長さ+αくらいを切り出す。
  6. 切り出したデータの長さを色々変えて base64 encode し、公開鍵を使って検証する。今回は PHP の base64_encode() や openssl_x509_check_private_key() を使った。
    $ cat test.key |php -r "echo(file_get_contents('php://stdin'));" > decoded.key

これでめでたく秘密鍵を復元できた。バックアップは大切だね!

参考ページ


(2012/07/24 追記)

当該 ML でも有益なアドバイスを下さいました、高知大名誉教授の菊地時夫先生のご冥福をお祈りいたします。

コメント

タイトルとURLをコピーしました