PHP中GPC繞過的一些總結

cnbird發表於2008-07-15
 
PS:PHP中繞過GPC的情況有很多,本文僅僅是總結了一些比較常見的,而且寫的很淺(因為本人水平有限),歡迎大家積極拍磚:)

ryat[at]wolvez.org
http://www.wolvez.org
2007-10-18

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/ja … -real-escape-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繞過缺陷》:http://www.xfocus.net/articles/200608/878.html

PHP某些版本對%00的錯誤轉義
http://www.securiteam.com/windowsntfocus/6M00K0AC1I.html


相關文章