[红日安全]代码审计Day5 - escapeshellarg与escapeshellcmd使用不当
字数 1536 2025-08-18 11:37:33

PHP escapeshellarg与escapeshellcmd使用不当导致的命令执行漏洞分析

1. 漏洞背景

本教学文档分析PHP中escapeshellargescapeshellcmd函数使用不当导致的命令执行漏洞,主要涉及PHP的mail()函数实现细节以及相关安全函数的使用注意事项。

2. 核心漏洞原理

2.1 PHP mail()函数参数分析

PHP的mail()函数签名:

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]])

关键参数:

  • additional_parameters:传递给发送程序sendmail的额外参数,支持以下选项:
    • -O option=value:设置队列目录
    • -X logfile:指定日志文件路径
    • -f from_email:指定发件人邮箱地址

2.2 漏洞触发链

  1. filter_var($email, FILTER_VALIDATE_EMAIL)绕过
  2. escapeshellcmdescapeshellarg联合使用导致参数逃逸
  3. 通过-X参数写入Webshell

2.3 关键函数分析

filter_var()函数

mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
  • FILTER_VALIDATE_EMAIL选项存在问题:特殊字符必须放在双引号中,但可以通过转义空格和重叠引号绕过检测

escapeshellarg()函数

  • 功能:将字符串转码为可以在shell命令里使用的参数
  • 实现:给字符串增加单引号并转义已存在的单引号
  • 示例:
    escapeshellarg("127.0.0.1' -v -d a=1") 
    // 结果为:'127.0.0.1'\'' -v -d a=1'
    

escapeshellcmd()函数

  • 功能:对字符串中的shell元字符进行转义
  • 实现:转义\'等特殊字符
  • 与escapeshellarg联合使用时会产生参数逃逸

2.4 参数逃逸过程分析

输入payload:127.0.0.1' -v -d a=1

  1. escapeshellarg处理:
    '127.0.0.1'\'' -v -d a=1'
    
  2. escapeshellcmd处理:
    '127.0.0.1'\\'' -v -d a=1\'
    
  3. 最终解析为:
    curl 127.0.0.1\ -v -d a=1'
    

3. 实例分析:PHPMailer漏洞(CVE-2016-10033和CVE-2016-10045)

3.1 CVE-2016-10033

漏洞条件

  1. PHP版本 < 5.2.0
  2. PHPMailer < 5.2.18
  3. PHP未安装pcre扩展
  4. safe_mode = false

漏洞利用

a( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com

漏洞原理

  1. validateAddress函数仅简单检查@符号
  2. $params参数未严格过滤
  3. 通过-X参数写入Webshell

3.2 CVE-2016-10045

改进的payload

a'( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com

漏洞原理

  1. 修复代码增加了escapeshellcmd函数
  2. mail()底层调用的escapeshellarg函数产生冲突
  3. 导致单引号逃逸

4. 修复建议

  1. 避免同时使用escapeshellcmdescapeshellarg函数
  2. 对用户输入进行严格验证
  3. PHPMailer官方修复方案:检测转义字符,不传递-f参数

5. 相关CTF题目分析

题目代码关键点:

$url = escapeshellarg($url);
$url = escapeshellcmd($url);
system("curl ".$url);

利用方法

  1. 利用escapeshellargescapeshellcmd联合使用的参数逃逸特性
  2. 构造特殊URL实现命令注入

6. 总结

  1. filter_var()的邮件验证可被特殊构造的payload绕过
  2. escapeshellargescapeshellcmd联合使用会导致参数逃逸
  3. PHP mail()函数的第五个参数additional_parameters是潜在的攻击面
  4. 安全函数的不当组合可能引入新的漏洞

7. 防御措施

  1. 严格验证所有用户输入
  2. 避免将用户输入直接传递给系统命令
  3. 使用白名单而非黑名单进行输入验证
  4. 保持PHP和相关库的最新版本
  5. 在生产环境中禁用危险函数
PHP escapeshellarg与escapeshellcmd使用不当导致的命令执行漏洞分析 1. 漏洞背景 本教学文档分析PHP中 escapeshellarg 与 escapeshellcmd 函数使用不当导致的命令执行漏洞,主要涉及PHP的 mail() 函数实现细节以及相关安全函数的使用注意事项。 2. 核心漏洞原理 2.1 PHP mail()函数参数分析 PHP的 mail() 函数签名: 关键参数: additional_parameters :传递给发送程序sendmail的额外参数,支持以下选项: -O option=value :设置队列目录 -X logfile :指定日志文件路径 -f from_email :指定发件人邮箱地址 2.2 漏洞触发链 filter_var($email, FILTER_VALIDATE_EMAIL) 绕过 escapeshellcmd 与 escapeshellarg 联合使用导致参数逃逸 通过 -X 参数写入Webshell 2.3 关键函数分析 filter_ var()函数 FILTER_VALIDATE_EMAIL 选项存在问题:特殊字符必须放在双引号中,但可以通过转义空格和重叠引号绕过检测 escapeshellarg()函数 功能:将字符串转码为可以在shell命令里使用的参数 实现:给字符串增加单引号并转义已存在的单引号 示例: escapeshellcmd()函数 功能:对字符串中的shell元字符进行转义 实现:转义 \ 、 ' 等特殊字符 与escapeshellarg联合使用时会产生参数逃逸 2.4 参数逃逸过程分析 输入payload: 127.0.0.1' -v -d a=1 escapeshellarg处理: escapeshellcmd处理: 最终解析为: 3. 实例分析:PHPMailer漏洞(CVE-2016-10033和CVE-2016-10045) 3.1 CVE-2016-10033 漏洞条件 : PHP版本 < 5.2.0 PHPMailer < 5.2.18 PHP未安装pcre扩展 safe_ mode = false 漏洞利用 : 漏洞原理 : validateAddress 函数仅简单检查 @ 符号 $params 参数未严格过滤 通过 -X 参数写入Webshell 3.2 CVE-2016-10045 改进的payload : 漏洞原理 : 修复代码增加了 escapeshellcmd 函数 与 mail() 底层调用的 escapeshellarg 函数产生冲突 导致单引号逃逸 4. 修复建议 避免同时使用 escapeshellcmd 和 escapeshellarg 函数 对用户输入进行严格验证 PHPMailer官方修复方案:检测转义字符,不传递 -f 参数 5. 相关CTF题目分析 题目代码关键点: 利用方法 : 利用 escapeshellarg 和 escapeshellcmd 联合使用的参数逃逸特性 构造特殊URL实现命令注入 6. 总结 filter_var() 的邮件验证可被特殊构造的payload绕过 escapeshellarg 和 escapeshellcmd 联合使用会导致参数逃逸 PHP mail()函数的第五个参数 additional_parameters 是潜在的攻击面 安全函数的不当组合可能引入新的漏洞 7. 防御措施 严格验证所有用户输入 避免将用户输入直接传递给系统命令 使用白名单而非黑名单进行输入验证 保持PHP和相关库的最新版本 在生产环境中禁用危险函数