一、PHP擴展進行代碼分析(動態分析)
基礎環境
apt-get install php5
apt-get install php5-dev
apt-get install apache
apt-get install mysql
使用PHPTracert
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,增加
extension=trace.so
測試
<?php
for($i=0;$i<100;$i++){
echo $I;
sleep(1);
}
?>
CLI
php test.php &
ps -axu|grep php
./phptrace -p pid
apache
curl 127.0.0.1/test.php
ps -aux|grep apache
./phptrace -p pid
phptrace分析
執行的代碼如下
<?php
function c(){
echo 1;
}
function b(){
c();
}
function a(){
b();
}
a();
?>
執行順序是
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 | 此函數對應的行號 |
邏輯分析
1.解析監控進程
開一個后台進程一直刷新進程列表,如果出現沒有tracer的進程就立即進行托管
2.json提取
通過對每一個文件的json進行提取,提取過程如下
1.便利所有文件
2.讀讀取文件
3.提取json,按照seq排序
4.提取type=2的與type=1的進行合並
5.按照level梳理上下級關系存儲同一個字典
6.按照seq排序,取出頭函數進行輸出
7.提取惡意函數往上提取level直到level=0
函數對應如下
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
使用XDEBUG
安裝
apt-get install php5-xdebug
修改php.ini
[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圖片
優缺點
缺點
人為參與力度較大,無法進行脫離人工的操作進行獨立執行。
優點
精准度高,對於面向對象和面向過程的代碼都可以進行分析。
二、語法分析(靜態分析)
案例:
http://php-grinder.com/
http://rips-scanner.sourceforge.net/
使用php-parser
介紹:
http://www.oschina.net/p/php-parser
https://github.com/nikic/PHP-Parser/
安裝
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
php composer.phar require nikic/php-parser
PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0
php composer.phar require nikic/php-parser 2.0.x-dev
測試
<?php
include 'autoload.php';
use PhpParser\Error;
use PhpParser\ParserFactory;
$code = '<?php eval($_POST[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();
}
輸出如下
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
)
)
)
由此可見,我們需要提取出
[0] => PhpParser\Node\Expr\Eval_ Object
[name] => _POST
[parts] => Array
(
[0] => c
)
然后進行拼接之后即可發現原始語句是:
eval($_POST[c])
邏輯分析
代碼解析
1.通過該庫進行語法分析
2.提取結果
3.提取危險函數
4.提取危險函數中存在的變量
5.從上文中提取此變量的賦值方式
6.分析出可控結果
7.輸出結果
優缺點
缺點
對於面向對象的程序進行分析比較弱。
優點
適合大批量的自動化分析,可以脫離人工操作進行獨立執行