PHP多字節(jié)編碼漏洞小結(jié)

如果小結(jié)中有理解錯(cuò)誤的地方,麻煩大家提出。漏洞本質(zhì): php 使用 php_escape_shell_cmd這個(gè)函數(shù)來轉(zhuǎn)義命令行字符串時(shí)是作為單字節(jié)處理的而當(dāng)操作系統(tǒng)設(shè)置了GBK、EUC-KR、SJIS等寬字節(jié)字符集時(shí)候,將 ...
如果小結(jié)中有理解錯(cuò)誤的地方,麻煩大家提出。
漏洞本質(zhì):
php 使用 php_escape_shell_cmd這個(gè)函數(shù)來轉(zhuǎn)義命令行字符串時(shí)是作為單字節(jié)處理的
而當(dāng)操作系統(tǒng)設(shè)置了GBK、EUC-KR、SJIS等寬字節(jié)字符集時(shí)候,將這些命令行字符串傳遞給MySQL處理時(shí)是作為多字節(jié)處理的
先看個(gè)簡(jiǎn)單的例子
<?php
header('Content-type: text/html; charset=gbk');
//連接MySQL
$conn = mysql_connect("localhost", "root", "");
//選擇數(shù)據(jù)庫
mysql_select_db("test", $conn);
//設(shè)置字符集編碼
mysql_query("SET CHARACTER SET 'gbk'", $conn);
//創(chuàng)建DEMO表如果不存在
mysql_query("CREATE TABLE IF NOT EXISTS `demo` (
`uid` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL,
`password` varchar(32) NOT NULL,
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk AUTO_INCREMENT=1;", $conn);
//插入個(gè)測(cè)試數(shù)據(jù)
mysql_query("REPLACE INTO `demo` VALUES('','admin','admin888') ",$conn);
//獲取用戶輸入
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : '';
//執(zhí)行查詢并且DEBUG
$sql = "SELECT * FROM demo WHERE username = '{$username}' LIMIT 1";
echo "sql: ".$sql."
";
$res = mysql_query($sql, $conn);
$row = mysql_fetch_array($res);
echo "result: <br/>";
var_dump($row);
?>
當(dāng)GPC=OFF時(shí):
username未經(jīng)任何過濾,這是個(gè)典型的字符型SQL注入
測(cè)試地址:
http://localhost/gbk.php?username=' or 1%23
http://localhost/gbk.php?username=' or 0%23
當(dāng)然很多情況下GPC=OFF時(shí)候都會(huì)使用一些函數(shù)來過濾用戶的輸入
// 對(duì)用戶傳入的變量進(jìn)行轉(zhuǎn)義操作
if (!get_magic_quotes_gpc())
{
$username = addslashes($username);
}
看上去貌似沒問題了,但是由于多字節(jié)編碼問題,同樣還是可以注入的
測(cè)試地址:http://localhost/gbk.php?username=%df%27
使用mysql_real_escape_string函數(shù)對(duì)用戶輸入進(jìn)行轉(zhuǎn)義存在同樣的問題
目前的很多開源的系統(tǒng)都是通過設(shè)置客戶端的字符集為二進(jìn)制來防止多字節(jié)編碼問題的。
//使用上面這句來替換DEMO中的 mysql_query("SET CHARACTER SET 'gbk'", $conn);
mysql_query("SET character_set_connection=gbk, character_set_results=gbk, character_set_client=binary", $conn);
再次測(cè)試:http://localhost/gbk.php?username=%df%27
OK,這樣一來,多字節(jié)編碼問題就不存在了嗎?不見得
當(dāng)使用mb_convert_encoding、iconv對(duì)字符集進(jìn)行錯(cuò)誤的轉(zhuǎn)換時(shí)候,漏洞再次的出現(xiàn)了(GPC=ON時(shí)問題同樣存在)
例如:
$username = iconv('gbk','utf-8',$username);
或
$username = mb_convert_encoding($username,'utf-8','gbk');
來看下T00ls上看到的ECSHOP 2.6.x/2.7.x GBK版本的漏洞吧
漏洞文件在api/checkorder.php line 28
$sql = "SELECT COUNT(*) ".
" FROM " . $ecs->table('admin_user') .
" WHERE user_name = '" . trim($_REQUEST['username']). "' AND password = '" . md5(trim($_REQUEST['password'])) . "'";
我們來看下$_REQUEST['username'] 的獲取過程
$_REQUEST['username'] = json_str_iconv($_REQUEST['username']);
json_str_iconv()這個(gè)函數(shù)在includes/lib_base.php中定義,其功能是將非UTF-8編碼的字符串進(jìn)行轉(zhuǎn)換,然后return ecs_iconv('utf-8', EC_CHARSET, $str);
ecs_inonv這個(gè)函數(shù)也在 includes/lib_base.php中定義,看下函數(shù)吧:
function ecs_iconv($source_lang, $target_lang, $source_string = '')
{
static $chs = NULL;
/* 如果字符串為空或者字符串不需要轉(zhuǎn)換,直接返回 */
if ($source_lang == $target_lang || $source_string == '' || preg_match("/[\x80-\xFF]+/", $source_string) == 0)
{
return $source_string;
}
if ($chs === NULL)
{ require_once(ROOT_PATH . 'includes/cls_iconv.php');
$chs = new Chinese(ROOT_PATH);
}
return $chs->Convert($source_lang, $target_lang, $source_string);
}
先是引入了includes/cls_iconv.php這個(gè)文件,然后實(shí)例化了Chinese這個(gè)類,在調(diào)用類的Convert的方法見line 127
$string = $this->_convert_iconv_mbstring($this->SourceText, $this->config['target_lang'], $this->config['source_lang']);
又調(diào)用了另外一個(gè)函數(shù)_conver_iconv_mbstring見line 278
//這里錯(cuò)誤的吧字符集從gbk轉(zhuǎn)為了utf8,所以漏洞產(chǎn)生了
$return_string = @mb_convert_encoding($string, $target_lang, $source_lang);
相關(guān)文章
thinkphp代碼執(zhí)行g(shù)etshell的漏洞解決
本文來介紹一下thinkphp官方修復(fù)的一個(gè)getshell漏洞,框架對(duì)控制器沒有進(jìn)行足夠的檢測(cè)導(dǎo)致的一處getshell,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨2018-12-12記 FineUI 官方論壇discuz所遭受的一次真實(shí)網(wǎng)絡(luò)攻擊
這篇文章主要介紹了記 FineUI 官方論壇discuz所遭受的一次真實(shí)網(wǎng)絡(luò)攻擊,需要的朋友可以參考下2018-11-30- 這篇文章主要介紹了Linux 下多種反彈 shell 方法,需要的朋友可以參考下2017-09-06
- 這篇文章主要為大家介紹了基于反射的XSS攻擊,主要依靠站點(diǎn)服務(wù)端返回腳本,在客戶端觸發(fā)執(zhí)行從而發(fā)起Web攻擊,需要的朋友可以參考下2017-05-20
- 這篇文章主要介紹了SQL注入黑客防線網(wǎng)站實(shí)例分析,需要的朋友可以參考下2017-05-19
ASP+PHP 標(biāo)準(zhǔn)sql注入語句(完整版)
這里為大家分享一下sql注入的一些語句,很多情況下由于程序員的安全意識(shí)薄弱或基本功不足就容易導(dǎo)致sql注入安全問題,建議大家多看一下網(wǎng)上的安全文章,最好的防范就是先學(xué)2017-05-19- 對(duì)于目前流行的sql注入,程序員在編寫程序時(shí),都普遍的加入防注入程序,有些防注入程序只要在我們提交一些非法的參數(shù)后,就會(huì)自動(dòng)的記錄下你的IP地址,提交的非法參數(shù)和動(dòng)作等,2017-04-29
XSS繞過技術(shù) XSS插入繞過一些方式總結(jié)
我們友情進(jìn)行XSS檢查,偶然跳出個(gè)小彈窗,其中我們總結(jié)了一些平時(shí)可能用到的XSS插入方式,方便我們以后進(jìn)行快速檢查,也提供了一定的思路,其中XSS有反射、存儲(chǔ)、DOM這三類2016-12-27Python 爬蟲使用動(dòng)態(tài)切換ip防止封殺
這篇文章主要介紹了Python 爬蟲使用動(dòng)態(tài)切換ip防止封殺的相關(guān)資料,需要的朋友可以參考下2016-10-08使用爬蟲采集網(wǎng)站時(shí),解決被封IP的幾種方法
這篇文章主要介紹了使用爬蟲采集網(wǎng)站時(shí),解決被封IP的幾種方法的相關(guān)資料,需要的朋友可以參考下2016-10-08