文件包含 任意文件读取
文件处理漏洞--文件包含 - wizard骑士 - 博客园
1,什么是文件包含
程序开发人员一般会吧重复使用的函数写道单个文件中,需要使用某个函数时直接调用此文件,无需再次编写,文件调用的过程就是文件包含,所以将包含的文件设置为变量,用来动态调用,但是这种灵活性,导致客户端可以调用一个恶意文件,造成文件包含漏洞 。
下面的代码通过get获取file的值,并用include包含此文件。
<?phperror_reporting(0);$file = $_GET["file"];include $file;>
而文件包含除了有include,还能用其他的函数
include
include()在包含的过程中如果出现错误,只产生警告,并且脚本会继续
require
require()在包含的过程中如果出现错误,会生成致命错误,并停止脚本
include_once、require_once
如果文件已包含,则不会包含,以避免函数重复定义,变量重新赋值等问题
在写法上 include('xx') ==== include 'xx'
2,文件包含漏洞利用
1,任意文件读取
当文件包含的文件没有被php标签包裹时,会直接显示包含文件的内容,否子会被先解析为php代码。直接包含本地php文件,只能得到运行后的结果,如果想要得到具体内容可以利用php中的filter伪协议将文件编码成base64后输出。
php://filter/read=convert.base64-encode/resource=xxx
什么是伪协议?
PHP 伪协议(PHP Pseudo Protocols)是 PHP 提供的一种特殊的协议机制,用于在 PHP 脚本中实现一些特殊的文件操作功能。这些伪协议并不是真正的网络协议,而是 PHP 内部定义的、用于特定用途的协议。它们通常用于处理文件路径、数据流、内存操作等。
这里用到的伪协议就是filter伪协议,后续的文件包含漏洞都与这个伪协议有关。
而这里的使用原理就是将php源码编码输出,这样php代码就不会被执行,再通过base64解码即可获得php源码。
payload中的各种组成部分
2,执行php代码
这里有两种伪协议php://input和data://
两种方式都有条件,它们都需要满足一个条件 allow_url_include=on
data://还需满足另一个条件 allow_url_fopen=on
php://input可以获取POST的数据流,当与包含函数结合时,php://input流会被当做php文件执行,从而导致任意代码执行
data://同样类似于php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当做php文件执行。从而导致任意代码执行
这里的input用法简单,只需用post的方法上传要执行的php代码即可。
但data比较吃操作
比如需要执行phpinfo函数
php://input (post内容 <?php phpinfo;?>)
data://[<MIME-type>][;charset=<encoding>][;base64],<data>
?file=data://text/plain,<?php phpinfo();?>
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
还可以用zip://伪协议(zlib://和bzip2://)
zip://可以访问压缩包里的文件,当与包含函数结合时,zip://流会被当作php文件执行,从而实现任意代码执行
只需要是zip压缩包即可
条件:allow_url_fopen=off/on、allow_url_include=off/on
zip://[压缩包绝对路径]#[压缩包内文件]
?file=zip.jpg#phpinfo.txt
还有几种利用方法
3,做题
[SWPUCTF 2021 新生赛]include
此题虽说没有任何过滤和保护,而且明确告诉了flag的文件名。如果没学文件包含漏洞利用可能就只有目录遍历找了,但学了文件包含漏洞我们就可以用php://input来执行代码
但是没成功,后面又尝试遍历目录看能不能找到,发现也没有
突然想起来包含php文件会被解析,所以用fliter看下
[HNCTF 2022 Week1]Interesting_include
参数中必须包含flag,然后就没有其他的了。
用fliter伪协议读取
[HNCTF 2022 WEEK2]easy_include
正则表达式过滤了flag,php,data和一些特殊字符
由于php被过滤(此处正则表达式忽略大小写),所以可以用日志文件包含
可以看到ua头被存储在这个日志文件中
写这个一定要小心,因为一但写错就删不了了
这个还要注意发送后包含不会立即执行,需要在包含一次