条件上传文件上传配合文件包含提高命中率
本篇博客是看P神博客的学习笔记https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html
这里我主要使用了session.upload_progress与Session文件包含
通过session progress功能实现临时文件的写入。
这种利用呢需要几个条件
- 目标环境开启了seesion.upload_progress.enable选项
- 发送一个文件上传请求,其中包含一个文件表单和一个名字是
PHP_SESSION_UPLOAD_PROGRESS
的字段 - 请求的Cookie中包含Session ID
这个方法的原理是,PHP在开启了session.upload_progress.enable
后(在包括Docker的大部分环境下默认是开启的),将会把用户上传文件的信息保存在Session中,而PHP的Session默认是保存在文件里的。
所以当攻击者发送满足上述条件的数据包时,就等于能够控制Session文件内容。
我们可以尝试发送满足上述条件的数据包来测试一下,但会发现虽然我们可以让PHP开启Session,从而在/tmp目录下遗留下Session文件,但这个文件内容是空的。
原因是,PHP中还有另外一个配置项session.upload_progress.cleanup,默认开启。在这个选项开启时,PHP会在上传请求被读取完成后自动清理掉这个Session,如果我们尝试把这个选项关闭,就可以读取到Session文件的内容了
注意的是,如果我们只上传一个文件,这里也是不会遗留下Session文件的,所以表单里必须有两个以上的文件上传。
所以,默认情况下,我们需要在Session文件被清理前利用它,这也会用到条件竞争(Race Condition)。
因为这里的Session文件名是可控的所以就不用担心读文件名的问题
那么,如果关闭了session.upload_progress.enable,是否还有其他利用方法呢?
我们的目的是在服务器上留下一个内容可控的文件,最简单的方法就是利用上传包的临时文件。但这个临时文件之所以不能直接利用,原因有两点:
- 临时文件名是随机的
- 临时文件在请求结束后会被删除
如果说第一点我们可以通过爆破来解决,那么第二点是一定无法同时解决的——我们不可能在请求结束前爆破出临时文件名。
经过上面的分析,我们很容易想到一种解决方案:如果我们可以让PHP进程在请求结束前出现异常退出执行,那么临时文件就可以免于被删除了。
PHP底层是C语言开发的,不少内存错误都会导致进程异常退出,当然不论是Apache还是PHP-FPM都会存在master进程,在某一个子进程异常退出后会拉起新的进程来处理用户请求,不用担心搞挂服务器。
include 'php://filter/string.strip_tags/resource=/etc/passwd';
<?php
file(urldecode('php://filter/convert.quoted-printable_encode/resource=data://,%bfAAAAAAAAFAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA'));
这些文件包含的就会导致php程序内存出错从而使php挂掉线程重启从而我们上传上去的文件就不会被删掉了