web-dev-qa-db-ja.com

PHP GETパラメータを介して

明確に言うと、これは私の仕事に代わってアプリケーションを保護するための倫理テストの利益のためです。

これで終わりです。詳細は次のとおりです。

  1. 無害化されていないGETパラメータは、HTMLページを動的に変更するためにPHPスクリプトで使用されます。
  2. _/_の前のparamサブストリングのみがHTMLファイルに書き込まれます

HTMLページがレンダリングされるときにコード<?php phpinfo() ?>を実行しようとしています。

私が移動したとき:

_[Host]/index.php/someparam=<?php phpinfo() ?>
_

ページのソースは、コードがコメントでラップされていることを示しています。

_<!--?php phpinfo() ?-->
_

_<?_が検出された場合のみ、コードはHTMLコメントでラップされます。つまり、_?>_自体は問題ありません。

これを倒すためのアイデアはありますか?私はもう試した:

_%3C%3F%70%68%70%20%70%68%70%69%6E%66%6F%28%29%20%3F%3E
_

結果は次のようになります:

_<!--?php phpinfo() ?-->
_

base64はそのままレンダリングされ、コードとして扱われません。10進値はソースのどこにも存在しません(HTMLコメントでラップされていません)。

9
Très

単純なシナリオは、--><?php phpinfo();?><!--を送信しようとすることです。 <?phpタグがエスケープされている場合、これは

 <!-- -->
 <?php phpinfo();
 <!-- -->

(明確にするために改行が追加されています)。ただし、HTMLページに<?php ...?>が存在するだけでは不十分な場合があります。 PHPコードは、クライアントに送り返すだけでなく、サーバー側で解釈する必要があります。

結果の文字列の先頭をさらに詳しく調べると、次のようになります。

 <!--?

エスケープをトリガーするのはPHPタグではなく、<だけではないことは明らかであり、これはおそらくHTML/XML/XSS防御として意図されています。アクティブコンテンツを送信せずに実行するか、クライアントが実行可能な形式でレンダリングします。

もう一度、「pre-unescaping」で送信してみてください。

 < --><hr><!-- >

そしてこれが素朴に変換されるかどうかを見て

 <!----><hr><!-- -->

hTMLとしてレンダリングされるか、より完全に

 <!-- -- --><!-- hr --><!-- !-- -->

これは何の役にも立たない。これは、HTMLオープンタグの検出方法と動作方法に完全に依存します。時々preg_replaceは、正しくない、不完全な、または貪欲でない正規表現で使用されます。これは、最初または最後のタグのみをデファングしたり、最初のオープニングを最後のクロージングで盲目的にデファングし、途中にあるものを無視します。その場合、ページはJavascriptインジェクションおよび関連するさまざまな攻撃に対して脆弱です。

消毒コードは検査に使用できますか?

単純な検証の例

たとえば、このコードはどうやらHTML出力をサニタイズします。

preg_replace("/<(.*)>/", "<!-- \\1 -->", $input);

しかし、(ひどく考え抜かれた対策は別として)貪欲な演算子の欠如?単純なエスケープ前の攻撃に対して脆弱なままにします。

<?php
    $params = array(
            "<script>alert('FAIL');</script>",
            "< --><script>alert('Success');</script><!-- >",
    );
    foreach($params as $param)
            print preg_replace("/<(.*)>/", "<!-- \\1 -->", $param) . "\n\n\n";
?>

最初の単純攻撃は失敗し、2番目は成功します。

<!-- script>alert('FAIL');</script -->

<!--  --><script>alert('Success');</script><!--  -->

残念ながら、このpreg_replaceオプションはHTMLインジェクション攻撃の「クイックフィックス」として提案または実装されていることが多く、ほとんどの「一時的なフィックス」では実行できないため、永続的になる可能性があります

より良い戦略は、元のパラメーターに属さないものoutをフィルターすることです(たとえば、[^A-Za-z0-9_]をまったく何も置き換えないでください)。禁止された文字は、このように邪悪なものが来ることを意味し、したがって、最も安全な反応は、リクエストを完全にドロップすることです(おそらく、偶然または問題が原因で発生したことをユーザーに通知します-たとえば、おそらく構文的に正しくないリンク-他の場所。そのため、HTTP_REFERERのロギングを強くお勧めします)。

9
LSerni

これを見て、私が考えることができる唯一のことは XSS攻撃 です。あなたがしようとしていることは、サイトが特定の入力をフィルタリングしているためではなく、おそらくこの「機能」が実装されている方法です。それはおそらく次のようなものです:

_echo '<!--'.$_GET['someparam'].'-->';
_

_<!-- -->_がなくても、スクリプトは入力を受け取り、変数に格納し、それをユーザーに出力します。PHPインタープリターによって再度処理されることはありません。

悪用可能な状況はeval($_GET);ですが、ここでは明らかにそうではありません。

2
Adi