一.文件包含漏洞
1.文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。
文件包含漏洞是一种常见的Web应用程序安全漏洞,它发生在应用程序中动态包含文件的过程中。这种漏洞允许攻击者通过操纵文件包含的机制来执行恶意代读取敏感信息。
2.文件包含漏洞的成因:大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。 但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。 攻击者会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。
3.配置要求
allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据;
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件;
4.常见文件包含函数
php常见包含文件函数包括:
- include() 当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行
- include_once() 功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次
- require() require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行 。使用require()函数包含文件时,只要程序一执行,立即调用文件,require()在php程序执行前执行,会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。
- require_once() 它的功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
5.存在可控利用点
文件包含漏洞的关键点是应用程序未正确验证用户可控输入的文件路径或参数。例include(‘$filename=flag.txt’)。用户可控输入可以是URL参数、表单输入、Cookie等,被包含的文件可被当前页面访问
6.文件包含类型
- 本地文件包含(LFI):
攻击者通过传递本地文件路径,使应用程序包含本地文件系统上的文件。
- 远程文件包含(RFI):
攻击者通过传递远程文件URL,使应用程序包含外部服务器上的文件。
例如:C:\\Windows\\system.ini文件。
(1)使用绝对路径\n使用绝对路径直接读取
(2)使用相对路径进行读取,通过./表示当前位置路径,…/表示上一级路径位置
二.PHP封装协议的应用
1.常见的PHP伪协议:
- file://:用于读取本地文件系统中的文件。可以通过该伪协议读取文件的内容,也可以写入或修改文件。
- http://和https://:用于通过HTTP或HTTPS协议访问远程资源。可以使用这些伪协议来获取远程服务器上的文件内容或执行HTTP请求。
- ftp://:用于通过FTP协议访问远程FTP服务器上的文件。可以使用这个伪协议来上传、下载或管理FTP服务器上的文件。
- data://:用于直接处理数据流,而无需物理文件。可以通过这个伪协议将数据流(如变量、字符串)作为文件来处理。
- php://:用于访问各种输入输出流。它提供了一种访问标准输入、输出和错误流的方式,以及其他特定流,如php://input用于访问请求的原始数据。
- zip://:用于访问ZIP压缩文件中的内容。可以通过这个伪协议读取ZIP文件中的文件,或者在ZIP文件中创建、修改或删除文件。
2.php://filter
读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容
poc:?file=php://filter/resource=xxx.php
?file=php://filter/read=convert.base64-encode/resource=xxxx.php
例如有一些敏感信息会保存在php文件中,如果我们直接利用文件包含去打开一个php文件,php代码是不会显示在页面上的,例如打开当前目录下的2.php
显示了一条语句,这时候我们可以以base64编码的方式读取指定文件的源码:
输入php://filter/convert.base64-encode/resource=2.php(文件路径),得到2.php加密后的源码
再进行base64解码,获取到2.php的完整源码信息
3.php://input
php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
poc: Index.php?filename=php://input
- 题目需存在file参数,伪协议过滤中并未过滤php://input
先看Index.php?filename=php://input,在执行
使用系统命令函数system,查看当前目录所有文件
- 我们可以直接写入php文件,输入file=php://input,然后使用burp抓包,然后蚁剑连接shell文件,获取flag文件
4.zip://
zip:// 协议可以访问压缩包里面的文件。当它与包含函数结合时,zip://数据流同样也可以被当作php文件执行。从而实现任意代码执行。
- zip://中只能传入绝对路径。
- 要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23
- 只需要是zip的压缩包即可,后缀名可以任意更改。
- 相同的类型的还有zlib://和bzip2://
poc:zip://[压缩包绝对路径]%23[压缩包内文件]
?file=zip://D:\zip.jpg%23phpinfo.txt
5.data://
data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。
n利用data:// 伪协议可以直接达到执行php代码的效果,例如执行phpinfo()函数
poc:data://text/plain,
data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
6.phar://
phar://压缩包/内部文件 phar://xxx.png/shell.php 注意: PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。 步骤: 写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。
POC: phar://archive.zip/file.txt