
Savant Web Server 3.1 における古典的なスタックベースのバッファオーバーフロー。細工された HTTP リクエストによって、2000年代初頭のリモートメモリ破損を示しています。
2000年代初頭のリモートメモリ破壊を、巧妙に細工されたHTTPリクエストで実演するSavant Web Server 3.1の古典的なスタックベースのバッファオーバーフロー(2025年のほとんどのバッファオーバーフローCVEよりも初心者に多くの知識を要求する2002年の脆弱性)。
このリポジトリは、メモリ破壊エクスプロイトを教える際に使用する教材の一部です(通常業務に加えて、次世代のリバースエンジニアを育成するさまざまなサイバーセキュリティコースでも指導を行っています)。授業でスタックベースのバッファオーバーフローを取り上げる際には、おもちゃの例ではなく実際の事例を扱っており、このCVEは特に、基本的なEIP上書きの経験を持つ学生に挑戦させるために使用するものです。
その理由は、CVE識別子の年号はエクスプロイトの難易度を何も示さないからです。多くの学生は、古いCVEは単純で、オーバーフロー→JMP ESP→完了、というものだと思い込んでいます。しかし、このCVEはその逆を証明します。私が教える2025年のCVEの中には、この脆弱性クラスがより単純だったり制約が少なかったりするため、基本的にこれよりも簡単なものもあります。CVE-2002-1120 では、現代のエクスプロイトでは要求されないことを理解する必要があります。なぜ特定のオペコードをリクエストの一部で使用できないのか、無条件ジャンプがブロックされているときに必ず発動する条件付きジャンプをどのように作成するのか、通常シェルコードを置く場所に収まらない場合にどのように届けるのか、そしてエッグハンターがどのようにして、そうでなければエクスプロイトを不可能にするスペース問題を解決するのか、といったことです。
これは、受講者が本当に理解しているかどうかを確認するために私が割り当てるCVEです。
この脆弱性は、2002年のフリーウェアWindows HTTPサーバーであるSavant 3.1に影響します。2025年に研究する価値がある理由は、その古さではなく、導入される制約の組み合わせと、それを回避するために必要なテクニックにあります。
これらの制約のそれぞれが、それ自体で教訓となります。
Savantは、任意のデスクトップコンピュータをWebサーバーに変えるために設計されたフリーウェアのオープンソースWindows HTTPサーバーです。TCPポート80で待機し、標準のHTTP GETリクエストを処理します。オーバーフローは、URIパスを固定サイズのスタックバッファにその長さを検証せずにコピーするハンドラで発生します。
主な技術的詳細:
Savantは着信HTTP GETリクエストを処理し、URIパスをその長さをチェックせずに固定サイズのスタックバッファにコピーします。脆弱なロジックを簡略化すると次のようになります。
char uri_buffer[270];
strcpy(uri_buffer, uri_path);
URIが約271バイトのGETリクエストを送信すると、スタック上の保存されたリターンアドレスが上書きされます。オーバーフローには制約があり、それ以上送信するとEIPが制御できなくなる方法でクラッシュが発生するため、使用可能なウィンドウは狭くなります。
このエクスプロイトは、標準のEIP上書きよりも複雑です。サーバーにはさらに2つの特性があるためです。HTTPメソッドフィールドもメモリにコピーされて実行されること、およびHTTPリクエストのボディはスタックではなく別のヒープ領域に保存されることです(これらの特性は両方ともエクスプロイトチェーンの必須部分になります)。
十分に長いURIを持つGETリクエストを送信することで、クラッシュを再現できます。認証は不要です。Pythonを使用した例:
import socket
HOST = '127.0.0.1'
PORT = 80
payload = b"A" * 271
request = (
b"GET /" + 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
これは、保存されたリターンアドレスがオーバーフローによって破損したことを確認しています。
このリポジトリの目的は、クラッシュの実演だけでなく、完全なエクスプロイトプロセスを段階的に解説することです。標準のEIP上書きよりもこのケースを難しくしているすべての制約と、それらを回避するために行われたすべての決定を含みます。
メインのREADMEをわかりやすく保つため、詳細なエクスプロイトノート、スクリプト、デバッガの手順は、このリポジトリの Vulnerability 📂 フォルダに配置しています。
そこには、このCVEのエクスプロイトに使用した完全なワークフローが含まれています。