命令执行漏洞

命令注入是一种攻击,其目标是通过易受攻击的应用程序在主机操作系统上执行任意命令。当应用程序将不安全的用户提供的数据(表单,Cookie,HTTP头等)传递给系统shell时,命令注入攻击是可能的。在这种攻击中,攻击者提供的操作系统命令通常以易受攻击的应用程序的特权执行。命令注入攻击可能很大程度上是由于输入验证不足。

挖掘思路

  • 用户能够控制函数输入
  • 存在可执行代码的危险函数

命令执行和代码执行的区别

代码执行:执行的效果完全受限于语言本身
命令执行:执行的效果不受限于语言语法本身,不受命令本身限制

命令执行类型

  • 代码层过滤不严
  • 系统的漏洞造成命令注入
  • 调用的第三方组件存在代码执行漏洞

常见危险函数

system()、exec()、shell_exec()、passthru()

System()函数

原型:string system ( string $command [, int &$return_var ] )
$command 要执行的命令
$return_var 如果提供此参数,则外部命令执行后的返回状态将会被设置到此变量中

实例

  1. // system.php
  2. <?php
  3. $cmd = $_GET['cmd'];
  4. echo "<pre>";
  5. system($cmd);
  6. ?>

image.png

写文件到本地(可以写马)
image.png

Passthru()函数

原型:string passthru ( string $command [, int &$return_var ] )
$command 要执行的命令
$return_var 如果提供此参数,Unix命令的返回状态会被记录到此参数

实例

  1. // passthru.php
  2. <?php
  3. $cmd = $_GET['cmd'];
  4. echo "<pre>";
  5. passthru($cmd);
  6. ?>

image.png
写文件到本地
image.png

Exec函数

原型:string exec ( string $command [, array &$output [, int &$return_var ]] )
$command 要执行的命令
$output 如果提供此参数,会有命令执行的输出填充此数组
$return_var 如果同时提供$output和$return_var参数,命令执行后的返回状态会被写入到此变量

实例

无回显,需要echo输出,并且只显示一行内容

  1. // exec.php
  2. <?php
  3. $cmd = $_GET['cmd'];
  4. echo "<pre>";
  5. echo exec($cmd);
  6. ?>

image.png

Shell_exec()函数

原型:string shell_exec ( string $cmd )
$cmd 要执行的命令
反引号(`)则调用此函数

实例

无回显,需要echo输出

  1. // shell_exec.php
  2. <?php
  3. $cmd = $_GET['cmd'];
  4. echo "<pre>";
  5. echo shell_exec($cmd);
  6. ?>

image.png

变形-反引号(`)

修改php.ini中的safe_mode=off

  1. // shell_exec.php
  2. <?php
  3. $cmd = $_GET['cmd'];
  4. echo "<pre>";
  5. echo `$cmd`;
  6. ?>

image.png

过滤函数

Escapeshellcmd() 过滤整条命令
Escapeshellarg() 过滤整个参数

修复方案

  • 尽量少用执行命令的函数或者直接禁用参数值尽量使用引号包括
  • 在使用动态函数之前,确保使用的函数是指定的函数之一
  • 在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义
  • 尽量少用执行命令的函数
  • 对于可控点是程序参数的情况下,使用escapeshellcmd函数进行过滤;对于可控点是程序参数值的情况下,使用escapeshellarg函数进行过滤
  • 参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义

而针对由特定第三方组件引发的漏洞,我们要做的就是及时打补丁,修改安装时的默认配置。