浅析命令执行漏洞

发布于 2021-08-06  75 次阅读


什么是命令执行漏洞

命令执行漏洞(RCE):指的是攻击者可以直接在Web应用中执行系统命令,从而获取敏感信息或者拿下shell权限等,一系列危害系统安全的行为。

命令执行漏洞形成的原因

在编写Web端代码的时候,我们常常需要调用一些系统自带的命令,与计算机的底层进行交互。由此,很多脚本语言,设置了很多自带的函数,如PHP中的system,exec,shell_exec等,当用户可以控制命令执行函数中的参数时,将可注入恶意系统命令到正常命令中,造成命令执行攻击。

命令执行漏洞的攻击流程

当脚本语言存在可以执行系统命令的函数的地方,例如:

image-20210228022308982

此时即可利用这些函数执行系统操作,从而达到攻击的效果

命令执行漏洞常用函数

1. string system( string $command[, int &$return_var] )

函数执行 command 参数所指定的命令,并且输出执行结果。

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

exec() 执行 command 参数所指定的命令。

3. string shell_exec( string $cmd)

通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。

4. void passthru( string $command[, int &$return_var] )

执行外部程序并且显示原始输出。

5. 反引号

例如ls,反引号的内容会被当做系统命令执行,其中内部就是执行了shell_exec()函数进行处理。

6. void pcntl_exec( string $path[, array $args[, array $envs]] )

pcntl是php的多进程处理扩展,在处理大量任务的情况下会使用到,pcntl需要额外安装。$path为可执行程序路径 (/bin/bash)。$args表示传递给$path程序的参数。 例如pcntl_exec(“/bin/bash” , array(“whoami”));

7. resource popen( string $command, string $mode)

打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。 例如popen(‘whoami >> 123.txt’, ‘r’);

8. resource proc_open( string $cmd, array $descriptorspec, array &$pipes[, string $cwd[, array $env[, array $other_options]]] )

执行一个命令,并且打开用来输入/输出的文件指针。类似 popen() 函数,但是 proc_open() 提供了更加强大的控制程序执行的能力

命令执行漏洞的危害(只要是系统命令能够产生的操作)

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

命令执行漏洞利用

  1. 存在回显示的话,可以直接读取各种配置文件,密码文件,数据库连接文件等等
  2. 遇到不回显的情况,最可靠的方法使用时间延迟推断,类似与盲注的方法。通过一些命令的延时作用来判断漏洞的存在,例如ping命令
  3. 不能在浏览器直接看到回显,可将命令重定向到当前目录下的文件中并查看。或者用TFTP上传工具到服务器,用telnet和netcat建立反向shell,用mail通过SMTP发送结果给自己的计算机
  4. 查看自己的权限,可以提升自己权限,访问敏感数据或控制服务器。
  5. 文件写入,上传一句话木马,得到服务器权限

命令执行利用的小技巧

白盒测试

可以代码审计的话,直接搜索含有常用的调用函数system、exec、shell_exec、passthru、pcntl_exec、popen、proc_open,以及反引号也可以执行命令。然后联系上下文看看有没有课控制的输入参数,可控制的点指的是,我们可以传入参数,如果在代码里写死了命令<?php system("ipconfig"):?>就是无法利用的,针对可控制的参数,在进一步绕过过滤限制。

黑盒测试

黑盒挖掘任意命令执行漏洞要点在于找到可能调用第三方命令的业务场景,很多时候要半蒙半猜的去想后台代码是什么样的。通常在图片处理、大文件压缩、文件格式转化、日志处理以及数据库导出等功能比较容易调用一些小脚本进行辅助处理。能够确定某个业务模块使用到了第三方工具,就可以进一步对命令注入语句进行分析,是否存在各种限制,最常见的用各种fuzz推测后端对输入进行了哪些限制,对其进行相应的绕过。构造出可以利用的payload。

命令执行防护的方法

  1. 尽量少用执行命令的函数或者直接禁用
  2. 参数值尽量使用引号包括
  3. 在使用动态函数之前,确保使用的函数是指定的函数之一
  4. 在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义
  5. 能使用脚本解决的工作,不要调用其他程序处理。尽量少用执行命令的函数,并在disable_functions中禁用
  6. 对于可控点是程序参数的情况下,使用escapeshellcmd函数进行过滤,对于可控点是程序参数值的情况下,使用escapeshellarg函数进行过滤
  7. 参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义而针对由特定第三方组件引发的漏洞,我们要做的就是及时打补丁,修改安装时的默认配置。