1. 程式人生 > >PHP動態函式執行與匿名函式執行

PHP動態函式執行與匿名函式執行

<?php
/**

 * 動態函式執行與匿名函式執行\\

技術QQ交流群:294088839

 */
//動態函式執行
function a(){
    echo  'a';
}
function b(){
    echo 'b';
}
function c($c){
    echo 'c';
    $c();
}
//C($_GET['c']);
echo '<hr>';
//把一個函式名作為引數傳進另一個函式中 然後呼叫相對應的函式
// 例如 如果傳過來個a 就會呼叫a函式從而輸出a
// 如果傳過來一個PHP自帶函式就會立刻執行  比如  phpinfo
// 利用性不高


// 匿名函式執行 也叫閉包函式  create_function這個匿名函式目前還沒搞明白
// 貌似通過這個函式可以關閉要觸發的函式 從而執行些我們想要執行的程式碼
// 有興趣研究的可以探討下
$id=$_GET['id'];
$str='echo  '.$a.'test'.$id.";";
$la=create_function('$a',$str);
//var_dump($la);
/*$array=array('reall long string here,boy','this','midding length','larcet');
usort($array,$la);*/

//print_r($array);

在PHP中使用create_function()建立匿名函式,如果沒有嚴格對引數傳遞進行過濾,攻擊者可以構造特殊字串傳遞給create_function()執行任意命令。

以如下程式碼為例: <?php //how to exp this code $sort_by=$_GET[‘sort_by’]; $sorter=’strnatcasecmp’; $databases=array(‘test’,’test’); $sort_function = ‘ return 1 * ‘ . $sorter . ‘($a[“‘ . $sort_by . ‘”], $b[“‘ . $sort_by . ‘”]);’; usort($databases, create_function(‘$a, $b’, $sort_function)); ?> 程式碼中$sort_by直接用$_GET取值未做過濾,create_function()中的函式體部分$sort_function只是簡單的字串拼接,利用注入將我們的程式碼寫進去。 這裡我們首先測試將phpinfo();注入到create_function()的函式體部分$sort_function中。 儲存以上程式碼為func.php,然後提交func.php?sort_by=”]);}phpinfo();/*執行結果如圖所示:
如圖所示phpinfo()函式執行了。 在具體分析細節之前,先說一下create_function()。 create_function返回一個字串的函式名, 這個函式名的格式是: “\000_lambda_” . count(anonymous_functions)++ 我們來看看create_function的實現步驟: 1. 獲取引數, 函式體; 2. 拼湊一個”function __lambda_func (引數) { 函式體;} “的字串; 3. eval; 4. 通過__lambda_func在函式表中找到eval後得到的函式體, 找不到就出錯; 5. 定義一個函式名:”\000_lambda_” . count(anonymous_functions)++; 6. 用新的函式名替換__lambda_func; 7. 返回新的函式。 實際上,create_functions是一個ZEND_FUNCTION,它被定義在./Zend/zend_builtin_functions.c中。 eval_code = (char *) emalloc(eval_code_length); sprintf(eval_code, “function ” LAMBDA_TEMP_FUNCNAME “(%s){%s}”, Z_STRVAL_PP(z_function_args), Z_STRVAL_PP(z_function_code)); eval_name = zend_make_compiled_string_description(“runtime-created function” TSRMLS_CC); retval = zend_eval_string(eval_code, NULL, eval_name TSRMLS_CC); 可以看到這裡只是簡單利用zend_eval_string來生成匿名函式,此處”function ” LAMBDA_TEMP_FUNCNAME “(%s){%s}”,我們可以控制函式主體部分閉合前面的“{”,後面跟上我們的phpinfo()函式,將提交的引數sort_by=”]);}phpinfo();/*放到函式中去,如圖所示:
可以看到提交sort_by引數中的“}”閉合生成的匿名函式的“{”,所以這裡的phpinfo()會被zend_eval_string執行。 測試執行系統命令,如下所示:
轉自:https://www.t00ls.net/viewthread.php?tid=20774