php代码审计命令执行漏洞

命令执行漏洞,用户通过浏览器在远程服务器上执行任意系统命令,严格意义上,与代码执行漏洞还是有一定的区别。

 常用命令执行函数

exec()、system()、popen()、passthru()、proc_open()、pcntl_exec()、shell_exec() 、反引号` 实际上是使用shell_exec()函数

system() 输出并返回最后一行shell结果。 
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。 
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。

popen()、proc_open() 不会直接返回执行结果,而是返回一个文件指针

漏洞利用及绕过姿势  

| 命令管道符

<>>> 文件重定向符

测试: 0 | dir c:

  代码只过滤了部分特殊字符,可以考虑用其他字符进行测试,这边列举一下Window/Linux可利用的特殊字符:

windows支持:

|     ,不管前面为真还是假 ,直接执行后面的语句      ping 127.0.0.1|whoami          

||    前面出错执行后面的 ,前面为假 ,若前面为真则不执行后面的      ping  2 || whoami 

&   前面的语句为假执行后面的,前面可真可假 ,如前面为真,前面后面的都会被执行  ping 127.0.0.1&whoami

&&前面的语句为假则直接出错,后面的也不执行,前面只能为真    ping 127.0.0.1&&whoami

Linux支持:

;     前面的执行完执行后面的 (不管前面的是真是假)     ping 127.0.0.1;whoami  

|     管道符,显示后面的执行结果   ping 127.0.0.1|whoami            

|| 表示上一条命令执行失败后,才执行下一条命令   ping 1||whoami  

&   前面的语句为假则直接执行后面的,前面可真可假                       ping 127.0.0.1&whoami

&&前面的语句为假则直接出错,后面的也不执行,前面只能为真    ping 127.0.0.1&&whoami

参考链接 :https://blog.csdn.net/chinabestchina/article/details/72686002

利用条件

  1. 应用调用执行系统命令的函数
  2. 将用户输入作为系统命令的参数拼接到了命令行中
  3. 没有对用户输入进行过滤或过滤不严

漏洞分类

  1. 代码层过滤不严
    商业应用的一些核心代码封装在二进制文件中,在web应用中通过system函数来调用:
    system("/bin/program --arg $arg");
  2. 系统的漏洞造成命令注入
    bash破壳漏洞(CVE-2014-6271)
  3. 调用的第三方组件存在代码执行漏洞
    如WordPress中用来处理图片的ImageMagick组件
    JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等)
    ThinkPHP命令执行

漏洞危害

  1. 继承Web服务程序的权限去执行系统命令或读写文件
  2. 反弹shell
  3. 控制整个网站甚至控制服务器
  4. 进一步内网渗透
  5. 等等

漏洞可能代码(以system为例)

1. system("$arg"); //直接输入即可

2. system("/bin/prog $arg"); //直接输入;ls

3. system("/bin/prog -p $arg"); //和2一样

4. system("/bin/prog --p=\"$arg\""); //可以输入";ls;"

5. system("/bin/prog --p='$arg'"); //可以输入';ls;'

在Linux上,上面的;也可以用|、||代替 ;前面的执行完执行后面的 |是管道符,显示后面的执行结果 ||当前面的执行出错时执行后面

在Windows上,不能用;可以用&、&&、|、||代替 &前面的语句为假则直接执行后面的 &&前面的语句为假则直接出错,后面的也不执行 |直接执行后面的语句 ||前面出错执行后面的

防御命令执行漏洞

PHP内置的两个函数可以有效防止命令执行:

   escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。资料参考:http://cn.php.net/manual/zh /function.escapeshellarg.php

   escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。资料参考:http://cn.php.net/manual/zh/function.escapeshellcmd.php

  当然,修复方法还有很多方式,修复方式一般有两种思维:

  1、黑名单:过滤特殊字符或替换字符  2、白名单:只允许特殊输入的类型/长度

修复代码示例一:

<?php
    $target=$_REQUEST['ip'];
    $octet = explode( ".", $target );
    if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
        $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
        $cmd = shell_exec('ping '.$target);
        echo "<pre>{$cmd}</pre>";
    }
    else {
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
?>

修复代码示例二:

<?php
    $target=$_REQUEST['ip'];
    $cmd = shell_exec('ping '. escapeshellcmd($target));
    echo "<pre>{$cmd}</pre>";
?>

参考链接 :https://www.cnblogs.com/xiaozi/p/7831529.html

                   https://www.jianshu.com/p/1e706f13b088


 

猜你喜欢

转载自blog.csdn.net/qq_40491569/article/details/83211727