
MiniShare 1.4.1 における、単一の HTTP PUT リクエストでトリガー可能なスタックベースのバッファオーバーフロー。
MiniShare 1.4.1 におけるスタックベースのバッファオーバーフロー。単一の HTTP PUT リクエストで到達可能。
このリポジトリは、メモリ破壊エクスプロイトの教育用資料の一部です(普段の業務に加えて、私は複数のサイバーセキュリティコースで教鞭をとり、次世代のリバースエンジニアを育成しています)。
CVE-2020-13768 は、シンプルなネットワーク向けサーバが標準プロトコルメソッドを通じて古典的なスタックベースのバッファオーバーフローを露出し得ることを示す事例として使用しています。脆弱なエンドポイントは認証不要で、オーバーフローは直接的な EIP の上書きであり、エクスプロイトの経路はクリーンで明確に定義されています。これは、現実的な無認証リモートシナリオにおいて、完全なエクスプロイト手法を学ぶための理想的なケースです。
さらに、このケースが教育上の演習として興味深い点は、同じ根本原因(固定サイズのスタックバッファに未サニタイズの入力がコピーされる)が、同一バイナリに対する複数の CVE エントリに現れていることです。CVE-2018-19861、CVE-2018-19862、CVE-2019-17601 はすべて同一クラスの脆弱性を記述しており、異なる研究者が異なる HTTP メソッドやエンドポイントを通じて報告したために別々の CVE 番号が割り当てられました。これは、CVE 番号だけでなく根本原因に注目することを学生に教える良い機会となります。
この脆弱性は MiniShare 1.4.1 に影響します。MiniShare は、シンプルなローカルファイル共有のために設計された、現在は開発が終了した軽量 Windows HTTP サーバです。このソフトウェアは最新のセキュリティ対策を念頭に置かずに作成されました。教育の観点からこのケースが特に興味深いのは、以下の要素が組み合わさっている点です。
これらの組み合わせにより、CVE-2020-13768 は、現実的な無認証シナリオにおいてネットワークベースのバッファオーバーフローエクスプロイトの基礎を教えるための優れた事例となっています。
MiniShare は、LAN 上でのクイックなローカルファイル共有を目的として設計された最小限の Windows HTTP サーバです。TCP ポート 80 で待ち受け、GET や PUT を含む限られた HTTP メソッドのサブセットを処理します。PUT ハンドラは受信リクエストを処理し、URI パスを固定サイズのスタックバッファにコピーしますが、その長さを検証しません。
主な技術的詳細:
MiniShare は受信した HTTP リクエストを処理し、メソッドに基づいて適切なハンドラに振り分けます。PUT ハンドラはリクエストから URI パスを抽出し、長さをチェックせずに固定サイズのスタックバッファにコピーします。
脆弱なロジックを簡略化すると次のようになります。
char path_buffer[256];
strcpy(path_buffer, uri_path);
宛先バッファは固定サイズであり、入力長が検証されないため、PUT リクエスト内に十分に長い URI を送信すると、コピーがバッファの末尾を超えて書き込まれ、最終的にスタック上の保存されたリターンアドレス (EIP) に到達して上書きします。
脆弱な関数がリターンすると、CPU は攻撃者が制御する値をスタックから EIP にロードし、そのアドレスにジャンプします。そのアドレスがシェルコードを含む攻撃者制御のデータを指している場合、任意のコード実行が達成されます。
クラッシュは、HTTP PUT リクエスト内に過剰に長い URI を送信することで再現できます。認証は不要です。Python を使用した例:
import socket
HOST = '127.0.0.1'
PORT = 80
payload = b"A" * 3000
request = (
b"PUT /" + payload + b" HTTP/1.1\r\n"
b"Host: 127.0.0.1\r\n"
b"Connection: close\r\n"
b"\r\n"
)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(request)
s.close()
デバッガで実行すると、EIP がユーザ制御のデータで上書きされたクラッシュが発生します。
EIP = 41414141
これにより、保存されたリターンアドレスがオーバーフローによって破損したことが確認できます。
このリポジトリの目的は、クラッシュのデモンストレーションだけでなく、実際のスタックベースのエクスプロイトを開発する際に使用される手法に沿って、完全なエクスプロイトプロセスを段階的に解説することでもあります。
メインの README を簡潔に保つため、詳細なエクスプロイトノート、スクリプト、デバッガの手順は、このリポジトリ内の Vulnerability 📂 フォルダに配置しています。
そこには、この CVE をエクスプロイトするために使用した完全なワークフローが含まれており、以下の内容が含まれます。