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


代码注入

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()被废弃了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李沉肩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值