PS:PHP中繞過GPC的情況有很多,本文僅僅是總結了一些比較常見的,而且寫的很淺[因為本人水平有限],歡迎大家積極拍磚:)
1.通過數據庫(文本)中轉
通過數據庫中轉:
[注意存入數據庫和select出的數據]
用戶輸入===>gpc\addslashes()==========>數據庫=========>執行sql語句\include\寫入緩存文件
insert\update select
這個問題是程序員容易忽略的,往往只是依靠gpc或addslashes函數對用戶直接輸入的數據進行處理,這樣數據中的'"等都會被\轉義,這樣就能正確的執行sql語句,有效防止注入攻擊了。但存入數據庫的數據呢?在執行完sql語句存入數據庫的是經過gpc處理前的原始數據,那么當程序再select出的就是受污染的數據了,如果把select出的數據再執行sql語句,那么就觸發了sqlinj,如果直接寫入緩存文件的話就有可能直接拿shell了:)
通過文本中轉:
用戶輸入===>gpc\addslashes()===>寫入文本文件===>include===>再次寫入文本文件\執行sql語句
這個和通過數據庫中轉大致是一樣的,對於寫文件的操作如果處理不當是有可能被攻擊者直接拿shell的,我們來看看php168的一個代碼片段:
function login_logs($username,$password) { global $timestamp,$onlineip; $logdb[]="$username\t$password\t$timestamp\t$onlineip"; @include(PHP168_PATH."cache/adminlogin_logs.php"); $writefile="<?php \r\n"; $jj=0; foreach($logdb AS $key=>$value) { $jj++; $writefile.="\$logdb[]=\"$value\";\r\n"; if($jj>200) { break; } } write_file(PHP168_PATH."cache/adminlogin_logs.php",$writefile); }
php168在登錄后台時如果輸入的用戶名或密碼有誤就會執行這個login_logs函數把登錄者的信息記錄在adminlogin_logs.php,如果用戶輸入的$username的數據是“";eval($_POST[cmd]); //”,前面的"被閉合了,成功的寫入了shell。但如果gpc為on的話,"會被轉義成\",無法利用了。但注意這里會先包含adminlogin_logs.php,並循環數組把數據再次寫入adminlogin_logs.php,要知道,這里的\僅僅是轉義字符,所以include后$logdb依舊是受污染的原數據,再次寫入文件時"就起作用了,成功寫入了shell。
2.通過編碼
UTF-7(+ACc-)===>gpc\addslashes()===>mb_convert_encoding()===>UTF-8(')
這個問題的具體例子可見:http://superhei.blogbus.com/logs/4255503.html
0xbf27===>gpc\addslashes()===>0xbf5c27===>執行sql語句[數據庫編碼支持多字節]
PHP里的函數大多是把字符串作為單字節進行處理的,那么如果數據庫編碼支持多字節呢,我們可以利用這個特性引入',而這里,gpc不但沒起作用還幫了我們的忙:)
詳見:http://shiflett.org/blog/2006/jan/addsl … ape-string
用戶輸入(經過urlencode\rawurlencode\base64_encode等函數處理)===>gpc\addslashes()===>urldecode\rawurldecode\base64_decode等函數===>執行SQL語句\include
通過二次編碼繞過gpc\addslashes,比如'的URL編碼二次編碼%25%27。
3.一些函數的錯誤處理
看看下面的函數處理的字符串:
substr($_GET['a'], 1);
假設輸入的$_GET['a']為'haha,經過gpc\addslashes()會變為\'haha,再經過substr處理后又變回了'haha.
處理字符串的函數有很多,往往程序員的一個不注意就能給我們帶來很多有意思的利用:)
4.字符串和數組
看看下面的代碼:
$a = $_GET['a'];
echo $a[1];
輸入$_GET['a']為'haha,經過gpc\addslashes()會變為\'haha,看看手冊里對字符串的一段描述:
字符串中的字符可以通過在字符串之后用花括號指定所要字符從零開始的偏移量來訪問和修改
這里也可以用方括號替代花括號[這是為了兼容較早的PHP版本,其實就是把字符串當數組處理的],有了這個特性我們能做很多事啊,比如這里$a[1]的輸出就是'了:),當然具體大的利用要看具體的代碼。
5.PHP自身的一些缺陷
PHP5的GPC對$_SERVER的忽略
見劍心的《PHP5繞過缺陷》
PHP某些版本對%00的錯誤轉義