引言~
老规矩,介绍一波原理先
PHP文件包含原理:
文件包含漏洞的产生原因是在通过 PHP 的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。
php 中引发文件包含漏洞的通常是以下四个函数:
1、include() 当使用该函数包含文件时,只有代码执行到 include() 函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。
2、include_once() 功能和 include() 相同,区别在于当重复调用同一文件时,程序只调用一次。
3、require() 只要程序一执行就会立即调用文件,发生错误的时候会输出错误信息,并且终止脚本的运行
4、require_once() 它的功能与 require() 相同,区别在于当重复调用同一文件时,程序只调用一次。
当使用这四个函数包含一个新文件时,该文件将作为 PHP 代码执行,php 内核并不在意该被包含的文件是什么类型。所以如果被包含的是 txt 文件、图片文件、远程 url、也都将作为 PHP 代码执行
再谈谈文件包含的分类
文件包含漏洞可以分为 RFI (远程文件包含)和 LFI(本地文件包含漏洞)两种。而区分他们最简单的方法就是 php.ini 中是否开启了allow_url_include。如果开启 了我们就有可能包含远程文件。
1、本地文件包含 LFI(Local File Include)
2、远程文件包含 RFI(Remote File Include)(需要 php.ini 中 allow_url_include=on、allow_url_fopen = On)
在 php.ini 中,allow_url_fopen 默认一直是 On,而 allow_url_include 从 php5.2 之后就默认为 Off。
因为要测试的服务器并没有文件包含漏洞代码,而这个漏洞是必须服务器端自带的,也就是说如果你要攻击的网站没有文件包含漏洞,图片马就是用不了的,所以为了方便我们实验的进行,我们需要先上传一个带有文件解析漏洞代码的PHP文件到服务器上
需要用到的php函数为include()
include()函数对文件后缀名无要求,而对其中的语法有要求,即使后缀名为txt,jpg也会被当做php文件解析,只要文件内是<?php ?>形式就可以执行,但是如果不是php语法的形式,即使后缀为php,也无法执行。
一.开始验证
1.先把我们的文件包含漏洞代码上传到服务器的根目录里,要记住上传的位置,因为到时候还要调用这个还是来解析小马!!
本地文件包含exp:
<?php
$file = $_GET['file'];
include $file;
?>
具体利用方法:
浏览器输入刚刚上传php文件解析漏洞代码的地址 并且在url地址后面加上file=upload/1.jpg来调用小马
比如:127.0.0.1/upload-labs-master/upload//include.php?file=upload/1.jpg
当然,PHP文件包含不可能只有包含图片马这一种攻击手法,利用文件包含漏洞的攻击方法五花八门,如果当你有一天渗透测试发现图片马用不了了,不妨试试以下几种思路:
1.包含日志,但是需要知道服务器日志的存储路径,且日志文件可读
2.远程文件包含,如curl
先把我们要上传的php文件包含代码改为jpg格式,不然过不了检测,当然,改后缀名只是其中的一种方法,也可用采用禁用浏览器js来屏蔽后缀名的检测,从而达到文件上传的效果
2.抓包改包
打开burp设置浏览器代理,准备抓取浏览器与服务端通讯的数据包
推荐使用火狐的 foxy proxy 插件
抓取数据包后,我们来修改数据包里面的内容,把刚刚上传的jpg文件改为用来的php后缀名
接下来验证一下文件是否上传成功,浏览器复制刚刚上传的图片链接,然后新建窗口打开
文件能成功打开,虽然报错了,不过证明我们成功上传了文件解析漏洞的php代码,其实出现报错信息的是一件有趣的事情,因为它直接把服务器的物理路径给报出来了,省的我们花无谓的时间再去探测服务器的目录,这对我们往后的文件上传很有帮助!!
3.制作图片马
1.准备好一张图片,个人觉得小一点的图片比较好,因为有些网站会做限制,不让传输过大的文件,而且上传的图片太大了,容易引起网站管理员的注意,所以准备的图片大小适中就好,这里做演示所以选了一张小一点的图片
2.准备好一句话代码,这是我们远程控制对方服务器的关键!!
PHP一句话代码:
3.合并两个文件,我这里准备的是bat处理文件,这样子比较高效
先把这串代码复制到记事本里,然后把后缀名改为bat即可
copy *.jpg /b + *.php /a 1.jpg
要记住的一点,图片要放在前面,木马放后面 不然会图片无法显示!!
制作成功的图片马是能够成功显示的,如果无法显示,建议重新找一张图片合并,不然一张无法显示的图片在一个网站里面太过显眼,会引起怀疑
右击图片马,使用文本编辑器打开,可以发现我们的一句话木马位于文件的最后面
准备完毕图片马,接下来我们可以上传了
4.上传图片马
可以看到,上传成功得图片马是能够正常显示的
接着,我们就要利用刚刚上传的PHP文件解析漏洞代码来执行图片马的功能了
浏览器打开我们上传的图片马
可以看到图片是非常正常的,完全看不出有木马。
接着,我们就要利用刚刚上传的PHP文件解析漏洞代码来执行图片马的功能了
5.漏洞利用
浏览器输入刚刚上传php文件解析漏洞代码的地址 并且在url地址后面加上file=upload/1.jpg来调用小马
127.0.0.1/upload-labs-master/upload//include.php?file=upload/1.jpg
可以看到页面出现了一堆乱码,而且刚刚我图片马加在这个位置,可是现在缺没有被打印出来,而是跟图片一起被执行了
6.蚁剑链接getshell
打开蚁剑,右键添加数据,把刚刚的url地址复制过去,然后输入链接的密码
双击打开,成功拿到网站的webshell
至此,PHP文件包含漏洞验证完毕
这里说说漏洞的解决方案吧
做到以下几点虽说不是能完全杜绝漏洞的复现,但是抵挡普通的php文件包含漏洞攻击却也是可以的
1.严格检查变量是否已经初始化。
2.严格判断包含中的参数是否外部可控。
3.基于白名单的包含文件验证,验证被包含的文件是否在白名单中。
4.尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include(“func.php”)。
5.对所有输入提交可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现…/之类的目录跳转符。
6.可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。
最后送上一波PHP伪协议:
file:///var/www/html 访问本地文件系统 (常用)
ftp://<login>:<password>@<ftpserveraddress> 访问 FTP(s) URLs
data:// 数据流
http:// — 访问 HTTP(s) URLs (常用)
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流
zlib:// — 压缩流
data:// — Data (RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP Archive
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — Audio streams
expect:// — 处理交互式的流