PHP代码审计----代码注入

本文阅读 4 分钟
PHP 可能出现代码注入的函数:eval()、preg_replace+/e()、assert()、call_user_func()、call_user_func_array()、create_function()等
查找程序中程序中使用这些函数的地方,检查提交变量是否用户可控,有无做输入验证。

1、eval()函数

eval 函数将输入的字符串参数当作 PHP 程序代码来执行
函数原型:
mixed eval(string code_str) //eval 注入一般发生在攻击者能控制输入的字符串的时候
//test.php
<?php
$var = "var";
if (isset($_GET["arg"]))
{ 
$arg = $_GET["arg"];
eval("\$var = $arg;");
echo "\$var =".$var;
}
?>

当我们提交 http://www.sectop.com/test3.php?arg=phpinfo();漏洞就产生了.

2、preg_replace+/e()函数

preg_replace — 执行正则表达式的搜索和替换
mixed preg_replace( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )
在subject中搜索pattern模式的匹配项并替换为replacement。如果指定了limit,则仅替换limit个匹配,如果省略limit或者其值为-1,则所有的匹配项都会被替换。

/e 修正符使preg_replace()将replacement参数当作PHP代码(在适当的逆向引用替换完之后)。提示:要确保replacement构成一个合法的PHP代码字符串,否则PHP会在报告在包含preg_replace()的行中出现语法解析错误。
<?php
function test($str){ 
        //......
        //......
        return $str;
}
echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", 'test("\1")', $_GET["h"]);
?>

提交?h=[php]{${phpinfo()}}[/php],phpinfo()就会被执行。 在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。注意:双引号中的函数不会被执行和替换。 在这里我们需要通过{
<!-- -->KaTeX parse error: Expected 'EOF', got '}' at position 3: {}}̲构造出了一个特殊的变量,'t…{phpinfo()}}")’,达到让函数被执行的效果 ${phpinfo()} 会被解释执行。

3、assert()

编写程序时,常会做出一定的假设,那断言就是用来捕获假设的异常,我们也可以认为断言是异常的一种特殊形式。 断言一般用于程序执行结构的判断,不可让断言处理业务流程。用的最多的场景就是单元测试,一般的单元测试框架都采用了断言。 在 PHP 中,采用 assert()函数对表达式进行断言。 1、先看一个正常使用断言assert()

try { 
    assert('a +== 1');
} catch (Throwable $e) {   
    echo $e->getMessage(), "\n";
}

运行结果为:

Failure evaluating code:
a +== 1

2、但是assert()与eval()函数一样,都会执行任何的PHP代码,我们按照如下方式,便可造成代码注入。

function demo(){ 
    file_put_contents('data.log', 'shockerli.net');
    return true;
}
$func = $_GET["func"];
assert("$func()");

4、call_user_func()

all_user_func — 把第一个参数作为回调函数调用
call_user_func(callable $callback, mixed $parameter = ?, mixed $... = ?): mixed
第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
callback:将被调用的回调函数(callable)。
parameter:0个或以上的参数,被传入回调函数。

如下示例:把完整的函数作为回调传入call_user_func()

test1.php
<?php
call_user_func(function($arg) {  print "[$arg]\n"; }, 'test'); 
?>

5、call_user_func_array()

用一个数组作为参数调用一个回调函数·返回值为回调函数执行的结果或者为false,要传递参数给函数,作为一个索引数组。 call_user_func_array的作用和call_user_func的作用一样,不同的是call_user_func用回调函数处理字符,而call_user_func_array用回调处理数组,也就是说call_user_func_array的参数二只能为数组。

6、create_function()

适用范围:PHP 4> = 4.0.1,PHP 5,PHP 7
功能:根据传递的参数创建匿名函数,并为其返回唯一名称。
语法:
create_function(string $args,string $code)
string $args 声明的函数变量部分
string $code 执行的方法代码部分

示例:WordPress <= 4.6.1的任意代码执行漏洞

function make_plural_form_function($nplurals, $expression) { 
    $expression = str_replace('n', '$n', $expression);
    $func_body = " \$index = (int)($expression); return (\$index < $nplurals)? \$index : $nplurals - 1;";
    return create_function('$n', $func_body);
}

不过从PHP 7.2.0开始,create_function()被废弃了。

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/118549257
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复