
自己完結型のHeartbleed(CVE-2014-0160)ラボ:脆弱なOpenSSL 1.0.1fをDockerでビルドし、許可されたテスト用のPythonメモリリークPoCを含みます。
CVE-2014-0160 (Heartbleed) 向けの、小さく自己完結したラボ — OpenSSL 1.0.1〜1.0.1f における TLS ハートビートの過剰読み取り。使い捨てコンテナ内で、ピン留めされたアップストリームソースから実際に脆弱な OpenSSL をビルドして起動し、そこから生きたプロセスメモリを漏洩させる概念実証クライアントを含んでいます。
認可されたラボ利用に限ります。 ここにあるものはすべて
localhost/ 自分で実行するコンテナを対象としています。PoC を、自分が所有しておらず明示的なテスト許可を持たないホストに向けないでください — 稼働中のシステムに対して Heartbleed を無断で使用することは、ほとんどの法域で犯罪です。Heartbleed は OpenSSL 1.0.1g (2014年4月) で修正されました。このラボはバグを理解するために存在し、誰かを攻撃するためのものではありません。
| パス | 内容 |
|---|---|
Dockerfile | チェックサムでピン留めされたアップストリームソースから、ハートビートを有効にして OpenSSL 1.0.1f をビルドし、使い捨て証明書を生成して openssl s_server を実行します — これが実際に脆弱なサーバーです。 |
exploit/heartbleed.py | Python 3 の PoC。不正なハートビートを送信し、サーバーが漏洩して返すメモリを hexdump します。対象が脆弱なら終了コード 0、修正済みなら 1 で終了します。 |
demo/server.py | 純粋な Python による素朴なシミュレーション — OpenSSL は関与しません。64 KB を盲目的にエコーするだけで、実際には何も漏洩しません。過剰読み取り応答の形を示すためだけに残されています。 |
demo/gen-cert.sh | デモ用の使い捨て localhost 証明書を再生成します。 |
秘密鍵はコミットされていません — 証明書はローカルで生成されます (.gitignore を参照)。
# 1. Build and start the vulnerable server (needs Docker)
docker build -t heartbleed-lab .
docker run --rm -p 8443:8443 heartbleed-lab
# 2. In another terminal, bleed it
python3 exploit/heartbleed.py 127.0.0.1 -p 8443
脆弱なサーバーは漏洩したメモリの hexdump を出力します。PoC を何度か再実行してください — 各リクエストはヒープの異なるスライスを返します。これこそが Heartbleed がこれほど危険だった理由です。セッション Cookie、フォームデータ、秘密鍵の素材がすべてそこに存在します。
cd demo
./gen-cert.sh
python3 server.py
これは CVE ではありません — 常に 64 KB の A を返すだけの教育用スタブです。
TLS ハートビートリクエストは、ペイロードと長さフィールドを運びます。脆弱な OpenSSL は攻撃者が指定した長さを信頼し、リクエストバッファからそのバイト数だけをレスポンスに memcpy します — しかしリクエストにはそれだけのデータが含まれていなかったため、コピーはそれを超えて、隣接するプロセスメモリの内容まで読み取ってしまいます。1.0.1g での修正は境界チェックです: if (1 + 2 + payload + 16 > s->s3->rrec.length) return 0; — 実際に送信された量を超える量を主張するハートビートは、黙って破棄されます。
-DOPENSSL_NO_HEARTBEATS を付けてビルドします。