代码审计
PHP
前期准备
SQL注入篇
文件操作函数汇总
命令执行篇
XML实体注入篇
前端漏洞篇
反序列化篇
小技巧篇
其它资料
本文档使用 MrDoc 发布
-
+
首页
命令执行篇
# 命令执行篇 - 命令执行执行的是系统命令 - 代码执行执行的是编程语言代码 ## PHP命令执行漏洞 ### PHP命令执行函数 - system - passthru - exec - shell_exec - popen - proc_open - pcntl_exec - dl - \`xx\` - 最常见的是上面的五种。 - PHP命令执行的本质:**用户输入无过滤,拼接到了系统命令中。** ### PHP命令执行案例 - **Discuz!2.5 命令执行漏洞** ```php #!php function Cropper_IM() { $exec_str = $this->param['imageimpath'].'/convert -quality 100' . '-crop '. $this->param['srcwidth'].'x'.$this->param['srcheight'].'+'.$this->param['srex'] . '+'.$this->param['srey'].' '. '-geometry '.$this->param['dstwidth'].'x'.$this->param['dstheight'].' '.$this->source.' '.$this->target; exec($exec_str); if(!file_exists($this->target)){ return -3; } } ``` - **如果CMS中有处理图片的功能,则关注一下是使用哪个方式来处理图片。**PHP中通常使用两种方式处理图片: - `GD`:用的最多,是个PHP扩展,用起来方便,缺点是功能不够强大。 - `Imagemgagick`:功能强大,复杂处理使用这个扩展。上述的案例中就是用的Imagemgagick下的convert命令,但是直接将用户命令拼接到这里了。 ### 如何防御PHP命令注入漏洞 - 假设是获取图片长宽,然后传入参数中,如下 ```php <?php $x = intval($_GET['x']); $y = intval($_GET['y']); $filename = $GET['filename']; exec("convert -crop {$x}x{$y} {$filename}"); ?> ``` - 这里的filename就很难通过黑白名单限制。 - 也最好不能禁用高危命令,安全对业务的影响越小越好。比如 ```php $to_email =$_POST['email']; $title =$_POST['title']; $content = $_POST['content']; exec("mail --title $title --cantent $content --to-email $to_enail"); ``` - 这里内容如果限制死了,就无了。 - 命令执行过滤函数 - **escapeshellcmd**:这两个本质上都是转义 - **escapeshellarg** - PHP中只能使用escapeshellcmd和escapeshellarg进行命令参数的过滤 - 区分escapeshellcmd和escapeshellarg的角色差异 - escapeshellcmd - `"/usr/bin/tail " . escapeshellcmd($filename);` - escapeshellarg - `"/usr/bin/tail -n ". escapeshellarg($filename)."/etc/passwd"` - **escapeshellcmd是不允许用户传入新的命令**。传入后的内容是`/usr/bin/tail -n 5 /etc/passwd`用`escapeshellcmd`是没有任何问题。但是如果传入后是`/usr/bin/tail -n 5 /etc/passwd; id`就不行。**这里的分号会被转义。** - **escapeshellarg一般是用来过滤给-n这样的【选项】的值传入的内容。**传入后的内容是`/usr/bin/tail -n 5 /etc/passwd`用`escapeshellarg`就不行。**这个函数会给传入内容的两边加上单引号包裹起来。试图逃逸也会被转义。** - 这两个函数用错了也会产生漏洞。比如arg的位置使用了cmd,是会出现问题的,如下: - **PHPMailer(CVE-2016-10033)任意文件写入漏洞** > https://www.leavesongs.com/PENETRATION/PHPMailer-CVE-2016-10033.html - PHPMailer中使用了mail(...)函数,这里面实际上调用了系统的`mail`命令,这里面用户传入mail函数的第五个参数使用了`escapeshellcmd`函数。 - 工具网站`explainshell.com`,可以用来分析命令,现在直接用GPT了。 - mail函数最终是调用的系统的sendmail进行邮件发送,而sendmail支持-X参数,通过这个参数可以将日志写入指定文件。可以写文件,当然就可以写shell,造成RCE了。 - 从payload看起 ```php $address = "aaa( -X/home/www/success.php )@qq.com"; $mail = new PHPMailer; $mail->setFrom($from); $mail->addAddress("joe@example.net","Jow User"); $mail->Subject='<?=phpinfo()?>'; $mail->send(); ``` - PHP Mail函数本质:sedmail命令执行 - main("joe@example.net",'<?=phpinfo()?>','...',"-f$from"); - sendmail joe@example.com ... -f$from - sendmail joe@example.com ... -flol -x/var/www/html/s.php - PHP内部对mail的第四个参数使用escapeshellcmd进行过滤 - escapeshellcmd允许插入额外参数 - sendmail-x参数写入任意文件 - **escapeshellarg真的安全吗** - gitlist 0.6.0 远程命令执行漏洞 > https://www.leavesongs.com/PENETRATION/escapeshellarg-and-parameter-injection.html - $query=escapeshellarg($query); - $results=$this->getClient()->run($this,"grep -i --line-number {$query} master"); - 又一个参数注入的案例:escapeshellarg仍无法防御参数注入漏洞 - **理论上,在经过$query = escapeshellarg($query);处理后,$query将变成一个由单引号包裹的字符串。但不出漏洞的前提是,这个字符串应该出现在“参数值”的位置,而不是出现在参数选项(option)中。** - 如果用户输入的值是`--open-files-in-pager=id;`,则执行的命令是:`grep -i --line-number '--open-files-in-pager=id;' master`。这里就没有什么影响,grep命令就有这个参数,把这个文件用=号后面的命令打开,这样理论上就能执行任意命令了。 - 两种修复方式 - $results=$this->getClient()->run($this,"grep -i --line-number -e {$query} master"); - $results=$this->getClient()->run($this,"grep -i --line-number -- {$query} master"); - 我将$query放在了-e参数的值的位置,此时它就仅仅是一个字符串而已,并不会被当成参数--open-files-in-pager。 - **linux下的--会被当作成一个选项**,如果给文件命名为--xx,使用cat '--xx'也无法读取,这个时候使用`cat -- "--xx"`或者 cat ./--xx 就可以读取了。 - 后续如果发现这个**函数过滤的位置是键值对或者键的位置,那实际上过滤并无法解决执行问题。**
别卷了
2024年9月29日 16:42
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码