文件包含漏洞原理与实践

Posted 士别三日wyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件包含漏洞原理与实践相关的知识,希望对你有一定的参考价值。

「作者主页」:士别三日wyx
「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者

文件包含漏洞

一、什么是文件包含漏洞?

文件包含漏洞常出现在php语言」中。

PHP为了提高「代码复用性」,提供了文件包含函数 include()require(),被包含的文件内容会被当做代码来执行。

就像造轮子一样:把「重复使用」的一段代码,单独写到一个文件里,再用文件包含函数来包含这个文件。

为了灵活的包含文件,一些程序员会把文件名通过「参数」的形式传递给文件包含函数。

当传递文件名的参数可以被用户「修改」时,用户就可以包含任意文件,而文件中的代码就会被服务器执行,这就造成了文件包含漏洞。


二、文件包含函数

PHP提供了四个文件包含函数:

  1. include() :当被包含的文件不存在时,会报错(Error),后面的代码不被执行。
  2. include_once() :只包含一次,包含过的文件不会被重复包含。
  3. require() :当被包含的文件不存在时,会告警(Wrainng),后面的代码可以继续执行。
  4. require_once() :只包含一次,包含过的文件不会被重复包含。

文件包含函数「不关心」文件的「后缀名」,它只是简单的执行被包含的文件,如果文件的内容是代码,就会执行代码;如果不是代码,就当做文本输出到页面。这个特点在后面的练习中可以体现出来。


三、两种文件包含

文件包含漏洞根据包含文件的「位置」可以分为「本地文件包含」「远程文件包含」

1、本地文件包含

本地文件包含是指:包含「服务器本地」的文件。

本地文件包含的payload通常以根目录(/)或文件名开头。也就是绝对路径和相对路径。

利用条件:

  1. 配置文件开启fopen(allow_url_fopen=On
  2. 用户可控参数,后台未过滤包含的文件。

1.1 使用教程演示

我们拿DVWA中的 File Injection 模块,简单了解一下本地文件包含的使用。

功能很简单:点不同的链接,跳转到对应的文件。

在地址栏中,手动修改page的参数为 file1.phpfile2.php,页面也会跳转到对应的页面,本质上是后台用文件包含函数 包含了这个文件。

这意味着「参数可控」,我们可以通过修改page的参数,让页面包含指定的文件,前提是文件存在。

我们提交账号文件的路径,在地址栏输入 /etc/passwd

可以看到,页面显示了passwd文件的内容。我们可以修改成其他的文件名,来包含服务器上其他的文件。


2、远程文件包含

远程文件包含是指:包含「远端」的文件。

远程文件包含的payload通常以 http://ftp:// 开头。

利用条件:

  1. 配置文件开启 fopen 和 include(allow_url_include=On)
  2. 用户参数可控,且后台没有过滤包含的文件。

1.1 使用教程演示

还是拿DVWA中的 File Injection 模块,简单了解一下远程文件包含的使用。

地址栏提交一个某牛的主页文件:

可以看到,页面包含了这个文件,网下滑可以看到,DVWA的页面被顶到下面去了:

这意味着,我们包含的远端文件,被执行了。我们可以更换其他远端文件

四、配置文件

PHP的配置文件 php.ini 中,有两个文件包含相关的配置:allow_url_fopen、allow_url_include。

可以根据这两个配置项来判断,文件包含漏洞是否存在。

1、allow_url_fopen

所有版本默认开启。

开启后,可以把 http://ftp:// 形式的URL当成文件打开。

allow_url_fopen=On,允许打开URL文件。
allow_url_fopen=Off,禁止打开URL文件。

2、allow_url_include

PHP5.2开始默认关闭。

开启后,文件包含函数 include()require() 可以把 http://ftp:// 形式的URL当成文件打开。

allow_url_include=On,允许包含URL文件。
allow_url_include=Off,禁止包含URL文件。

禁用 fopen 和 include,只能防止 http://ftp:// 这种URL文件的,对5.2版本提供的php和data则无能为力。


五、PHP伪协议

PHP提供了一些「伪协议」,这些伪协议可以帮助我们更好的使用文件包含。

1、php://filter

php://filter 常用来「读取文件源码」

php文件被包含时,里面的代码会被执行,我们就看不到文件中的内容了。

1)用 php://filter 把文件内容进行base64编码,编码后的内容不会被当做代码执行,而是在页面中显示出来。我们复制下来用工具解码,就能拿到文件的源码了。使用格式如下:

?url=php://filter/read=convert.base64-encode/resource=phpinfo.php

前面是固定格式,只需要把后面的 phpinfo.php换成其他文件就可以了。


2、php://input

php://input 会把「post请求体」的内容当做文件执行,导致任意代码执行。

1)GET请求参数中使用 php://input 伪协议:

?url=php://input

2)(配合其他工具)post请求体中,写需要执行的代码:

<?php system('ls'); ?>

enctype=multipart/form-data 时,php:/input 无法使用。


3、phar://

phar:// 可以「读取压缩文件」

1)把代码文件压缩成zip格式,再上传到服务器(配合文件上传漏洞)。

2)用 phar:// 从服务器中读取压缩文件中的文件。

?url=phar://temp/shell.zip/shell.txt

提示:读取时,注意压缩文件中,目录的层级关系。


4、zip://

zip:// 可以「读取压缩文件」

1)把代码文件压缩成zip格式,再上传到服务器(配合文件上传漏洞)。

2)用zip:// 从服务器中读取压缩文件中的文件。

?url=phar://temp/shell.zip%23shell.txt

提示:zip:// 与 phar:// 相似,他们有两个区别

  1. zip:// 只能读取单级目录,而 phar:// 可以读取多级目录
  2. 压缩文件中的分隔符 / 需要换成 %23 (/ 换成 # 后 再url编码成 %23)

5、data://

data:// 常用来「任意代码执行」

与php://input 相似,不同的是,php://input是将post请求体中的内容当做文件执行,而data://将GET请求中,逗号后面的内容当做文件执行。

方式一:data://text/plain,

逗号后面的内容,以纯文本形式执行

?url=data://text/plain,<?php phpinfo();?>

方式二:data://text/html,

逗号后面的内容,以html形式解析

?url=data://text/html,<?php phpinfo();?>

方式三:data://text/plain;base64,

先把需要执行的命令进行base64编码;

逗号后面的内容,先base64解码,再以纯文本形式执行(一种绕过方式)

?url=data://text/plain;base64,JTNDJTNGcGhwJTIwcGhwaW5mbyUyOCUyOSUzQg==

提示:JTNDJTNGcGhwJTIwcGhwaW5mbyUyOCUyOSUzQg==<?php phpinfo(); base64加密的结果,加密代码时,后面不要加 ?> ,否则会报语法错误。


六、包含日志

包含日志文件,文件内容会显示到页面中,如果日志中包含代码,则会被执行。

1、包含Web访问日志

1)包含Web日志(nginx日志路径:/usr/local/nginx//access_log),页面显示出日志内容。

2)Burp Suite修改访问请求,将代码写入Web日志。

3)再次访问Web日志,日志中的代码将被执行。


2、包含ssh登录日志

1)ssh登录 ssh "<?php phpinfo();?>"@192.168.0.1 ,代码被记录到登录日志中。

2)包含日志文件,默认路径 /var/log/auth.log/var/log/secure,日志中的代码将被执行。


以上是关于文件包含漏洞原理与实践的主要内容,如果未能解决你的问题,请参考以下文章

文件包含漏洞原理与实践

文件包含漏洞原理与实践

web安全原理-文件包含漏洞

20155308《网络对抗》Exp9 Web安全基础实践

文件包含漏洞

#20155232《网络对抗》Exp9 Web安全基础