<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/11757

            0x00 PHP擴展進行代碼分析(動態分析)


            一.基礎環境

            #!bash
            apt-get install php5
            apt-get install php5-dev
            apt-get install apache
            apt-get install mysql
            

            二.使用PHPTracert

            #!bash
            mkdir godhead
            wget https://github.com/Qihoo360/phptrace/archive/v0.3.0.zip
            unzip v0.3.0.zip
            cd ./phptrace-0.3.0/extension
            phpize5
            ./configure --with-php-config=/usr/bin/php-config
            make & make install
            cd ../cmdtool
            make 
            

            編輯php.ini,增加:

            #!bash
            extension=trace.so
            

            三.測試

            #!php
            <?php 
            for($i=0;$i<100;$i++){
                echo $I;
                sleep(1);
            }
            ?>
            

            CLI

            #!shell
            php test.php &
            ps -axu|grep php
            ./phptrace -p pid
            

            apache

            #!bash
            curl 127.0.0.1/test.php
            ps -aux|grep apache
            ./phptrace -p pid
            

            四.phptrace分析

            執行的代碼如下:

            #!php
            <?php
            function c(){
                echo 1;
            }
            function b(){
                c();
            }
            function a(){
                b();
            }
            a();
            ?>
            

            執行順序是:

            #!bash
            a>b>c>echo
            

            參數含義:

            名稱 意義
            seq int|執行的函數的次數
            type 1/2 1是代表調用函數,2是代表該函數返回
            level -10 執行深度,比如a函數調用b,那么a的level就是1,b的level就是2,依次遞增
            func eval 調用的函數名稱
            st 1448387651119460 時間戳
            params string 函數的參數
            file c.php 執行的文件
            lineno 1 此函數對應的行號

            日志輸出:

            #!js
            {"seq":0, "type":1, "level":1, "func":"{main}", "st":1448387651119445, "params":"", "file":"/var/www/html/2.php", "lineno":11 }
            {"seq":1, "type":1, "level":2, "func":"a", "st":1448387651119451, "params":"", "file":"/var/www/html/2.php", "lineno":11 }
            {"seq":2, "type":1, "level":3, "func":"b", "st":1448387651119452, "params":"", "file":"/var/www/html/2.php", "lineno":9 }
            {"seq":3, "type":1, "level":4, "func":"c", "st":1448387651119453, "params":"", "file":"/var/www/html/2.php", "lineno":6 }
            {"seq":4, "type":2, "level":4, "func":"c, "st":1448387651119457, "return":"NULL", "wt":4, "ct":4, "mem":48, "pmem":144 }
            {"seq":5, "type":2, "level":3, "func":"b, "st":1448387651119459, "return":"NULL", "wt":7, "ct":6, "mem":48, "pmem":144 }
            {"seq":6, "type":2, "level":2, "func":"a, "st":1448387651119459, "return":"NULL", "wt":8, "ct":8, "mem":80, "pmem":176 }
            {"seq":7, "type":2, "level":1, "func":"{main}, "st":1448387651119460, "return":"1", "wt":15, "ct":14, "mem":112, "pmem":208 }
            

            五.邏輯分析

            1.解析監控進程

            開一個后臺進程一直刷新進程列表,如果出現沒有tracer的進程就立即進行托管

            2.json提取

            通過對每一個文件的json進行提取,提取過程如下:

            1. 便利所有文件
            2. 讀讀取文件
            3. 提取json,按照seq排序
            4. 提取type=2的與type=1的進行合并
            5. 按照level梳理上下級關系存儲同一個字典
            6. 按照seq排序,取出頭函數進行輸出
            7. 提取惡意函數往上提取level直到level=0

            函數對應如下:

            #!python
            list1={
                 level1:[seq,type,func,param,return]
                 level2:[seq,type,func,param,return]
                 level3:[seq,type,func,param,return] #eval 
                 level4:[seq,type,func,param,return]
            
            }
            list2=
            

            3.數據查看

            通過追蹤危險函數,然后將其函數執行之前的關系梳理出來進行輸出,然后再進行人工審查。

            放上demo

            p1

            p2

            六.使用XDEBUG

            安裝

            #!bash
            apt-get install php5-xdebug
            

            修改php.ini

            #!bash
            [xdebug]
            zend_extension = "/usr/lib/php5/20131226/xdebug.so"
            xdebug.auto_trace = on
            xdebug.auto_profile = on
            xdebug.collect_params = on
            xdebug.collect_return = on
            xdebug.profiler_enable = on
            xdebug.trace_output_dir = "/tmp/ad/xdebug_log"
            xdebug.profiler_output_dir = "/tmp/ad/xdebug_log"
            

            放上幾個demo圖片:

            p3

            七.優缺點

            缺點

            人為參與力度較大,無法進行脫離人工的操作進行獨立執行。

            優點

            精準度高,對于面向對象和面向過程的代碼都可以進行分析。

            0x01 語法分析(靜態分析)


            案例:

            一.使用php-parser

            介紹:

            二.安裝

            #!shell
            git clone https://github.com/nikic/PHP-Parser.git & cd PHP-Parser
            curl -sS https://getcomposer.org/installer | php
            

            PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6

            #!bash
            php composer.phar require nikic/php-parser
            

            PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0

            #!bash
            php composer.phar require nikic/php-parser 2.0.x-dev
            

            三.測試

            #!php
            <?php
            include 'autoload.php';
            use PhpParser\Error;
            use PhpParser\ParserFactory;
            
            $code = '<?php  eval($_POST[c][/c])?>';
            $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
            
            try {
                $stmts = $parser->parse($code);
                print_r($stmts);
                // $stmts is an array of statement nodes
            } catch (Error $e) {
                echo 'Parse Error: ', $e->getMessage();
            }
            

            輸出如下:

            #!js
            Array
            (
                [0] => PhpParser\Node\Expr\Eval_ Object
                    (
                        [expr] => PhpParser\Node\Expr\ArrayDimFetch Object
                            (
                                [var] => PhpParser\Node\Expr\Variable Object
                                    (
                                        [name] => _POST
                                        [attributes:protected] => Array
                                            (
                                                [startLine] => 1
                                                [endLine] => 1
                                            )
            
                                    )
            
                                [dim] => PhpParser\Node\Expr\ConstFetch Object
                                    (
                                        [name] => PhpParser\Node\Name Object
                                            (
                                                [parts] => Array
                                                    (
                                                        [0] => c
                                                    )
            
                                                [attributes:protected] => Array
                                                    (
                                                        [startLine] => 1
                                                        [endLine] => 1
                                                    )
            
                                            )
            
                                        [attributes:protected] => Array
                                            (
                                                [startLine] => 1
                                                [endLine] => 1
                                            )
            
                                    )
            
                                [attributes:protected] => Array
                                    (
                                        [startLine] => 1
                                        [endLine] => 1
                                    )
            
                            )
            
                        [attributes:protected] => Array
                            (
                                [startLine] => 1
                                [endLine] => 1
                            )
            
                    )
            
            )
            

            由此可見,我們需要提取出

            #!js
            [0] => PhpParser\Node\Expr\Eval_ Object
            [name] => _POST
            [parts] => Array
                                                    (
                                                        [0] => c
                                                    )
            

            然后進行拼接之后即可發現原始語句是:

            #!php
            eval($_POST[c][/c])
            

            四.邏輯分析

            代碼解析

            1. 通過該庫進行語法分析
            2. 提取結果
            3. 提取危險函數
            4. 提取危險函數中存在的變量
            5. 從上文中提取此變量的賦值方式
            6. 分析出可控結果
            7. 輸出結果

            五.優缺點

            缺點

            對于面向對象的程序進行分析比較弱。

            優點

            適合大批量的自動化分析,可以脫離人工操作進行獨立執行

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线