[红日安全]代码审计Day5 - escapeshellarg与escapeshellcmd使用不当
字数 1536 2025-08-18 11:37:33
PHP escapeshellarg与escapeshellcmd使用不当导致的命令执行漏洞分析
1. 漏洞背景
本教学文档分析PHP中escapeshellarg与escapeshellcmd函数使用不当导致的命令执行漏洞,主要涉及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 漏洞触发链
filter_var($email, FILTER_VALIDATE_EMAIL)绕过escapeshellcmd与escapeshellarg联合使用导致参数逃逸- 通过
-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
- escapeshellarg处理:
'127.0.0.1'\'' -v -d a=1' - escapeshellcmd处理:
'127.0.0.1'\\'' -v -d a=1\' - 最终解析为:
curl 127.0.0.1\ -v -d a=1'
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
漏洞利用:
a( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com
漏洞原理:
validateAddress函数仅简单检查@符号$params参数未严格过滤- 通过
-X参数写入Webshell
3.2 CVE-2016-10045
改进的payload:
a'( -OQueueDirectory=/tmp -X/var/www/html/x.php )@a.com
漏洞原理:
- 修复代码增加了
escapeshellcmd函数 - 与
mail()底层调用的escapeshellarg函数产生冲突 - 导致单引号逃逸
4. 修复建议
- 避免同时使用
escapeshellcmd和escapeshellarg函数 - 对用户输入进行严格验证
- PHPMailer官方修复方案:检测转义字符,不传递
-f参数
5. 相关CTF题目分析
题目代码关键点:
$url = escapeshellarg($url);
$url = escapeshellcmd($url);
system("curl ".$url);
利用方法:
- 利用
escapeshellarg和escapeshellcmd联合使用的参数逃逸特性 - 构造特殊URL实现命令注入
6. 总结
filter_var()的邮件验证可被特殊构造的payload绕过escapeshellarg和escapeshellcmd联合使用会导致参数逃逸- PHP mail()函数的第五个参数
additional_parameters是潜在的攻击面 - 安全函数的不当组合可能引入新的漏洞
7. 防御措施
- 严格验证所有用户输入
- 避免将用户输入直接传递给系统命令
- 使用白名单而非黑名单进行输入验证
- 保持PHP和相关库的最新版本
- 在生产环境中禁用危险函数