⽂件包含——本地⽂件包含和远程⽂件包含
⽂件包含漏洞的出现及危害
⽂件包含漏洞是⼀种最常见的漏洞类型,它会影响依赖于脚本运⾏时的web应⽤程序。当应⽤程序使⽤攻击者控制的变量构建可执⾏代码的路径时,⽂件包含漏洞会导致攻击者任意控制运⾏时执⾏的⽂件。如果⼀个⽂件包含这个漏洞,为了⽅便起见,经常在开发阶段就实施。由于它经常⽤于程序开发阶段,所以这就为后来的攻击埋下了伏笔并导致了各种基于⽂件的攻击。
⽂件包含漏洞主要是程序员把⼀些公⽤的代码写在⼀个单独的⽂件中,然后使⽤其他⽂件进⾏包含调⽤,如果需要包含的⽂件使⽤硬编码,⼀般是不会出现安全问题,但是有时可能不确定需要包含哪些具体⽂件,所以就会采⽤变量的形式来传递需要包含的⽂件,但是在使⽤包含⽂件的过程中,未对包含的变量进⾏检查及过滤,导致外部提交的恶意数据作为变量进⼊到了⽂件包含的过程中,从⽽导致提交的恶意数据被执⾏。
⽂件包含漏洞分为本地⽂件包含(Loacl File Inclusion,LFI)和远程⽂件包含(Remote File Inclusion,RFI)。这种漏洞貌不惊⼈,却危害很⼤。通过⽂件包含漏洞,可以读取系统中的敏感⽂件,源代码⽂件等,如密码⽂件,通过对密码⽂件进⾏暴⼒破解。若破解成功则可获取操作系统的⽤户账户,甚⾄可通过开放的远程连接服务进⾏连接控制。另外不管是本地⽂件包含还是远程⽂件包含,⽂件包含漏洞还可能导致
执⾏任意代码。
本地⽂件包含
本地⽂件包含就是通过浏览器包含web服务器上的⽂件,这种漏洞是因为浏览器包含⽂件时没有进⾏严格的过滤允许遍历⽬录的字符注⼊浏览器并执⾏。
⾸先,当值可以直接被控制时,你就会有⼀个⾮常类似的如下的代码⽚段。
<? php $ file = $ _GET ['file']; include ($ file);
如果你可以到上⾯的代码,那么就有⼀个直接包含的$⽂件,你可以控制它。
请注意:该⽂件可以是任何类型,⽆论它是被删除的⽂件类型、图⽚还是任意的内容,都包括在内。
⾸先,在当前⽂件夹中创建任意后缀的任意⽂件,如:(即使是像file.jpg这样的图⽚格式,则会产⽣以下效果)。
将⽂件的内容设置为:
<? php phpinfo ();
此时,⽂件包含漏洞还包含当前服务器中的其他⽂件,同时⽀持包含Web应⽤程序的⽬录,如下所⽰:
尝试包括你的硬盘的⼀些内容,例如:C:\WINDOWS\system.ini。
如果你这样做,就可以在浏览器上看到任何⽂件的输出内容。
这只有当你有完全控制和⽂件类型没有进⼀步指定时才有效。
那么,如果代码⽚段变成如下这样,你该怎么做?
<?php $file = $_GET['file'] . '.php'; echo $file; include($file);
在这种情况下,你可以尝试按照上⾯的⽅法:
这将导致以下的输出:
你可以看到,如果后缀是固定的,就像上图⼀样,你不会到前⾯包含的⽂件。
搜索的⽂件名是:./php。
所以这⾥有另⼀种⽅法:%00到达时截断⼀个字符串。这个技巧也被⼴泛应⽤于不同的领域,我不会在这⾥再详述,如果想详细了解,请。
在PHP中使⽤%00:
1.PHP版本<5.3(不包括5.3);
2. PHP `magic_quotes_gpc = off`;
3.PHP不会在收到的参数中使⽤addslashes函数,例如上⾯代码中的$ _GET ['file'],不过在PHP版本5.3或更⾼版本中,此问题已得到解决。
如果打开gpc或者使⽤了加法器函数,序列将被正确地转义。
⾸先,你可以尝试如果gpc打开会发⽣什么(效果与使⽤该函数相同)。
如果你启⽤了gpc标志,你可以直接看到这个过程是如何发⽣的。
接下来可以看看5.3版本中的情况:
这⾥也没有明显的效果。
所以你可以看到,只要满⾜上述三个条件,就可以使⽤%00。
⾸先,你要将PHP版本更改为5.2,并在php.ini更改为 magic_quotes_gpc = on tomagic_quotes_gpc = off.后重新启动Apache。
这使你就能够在尝试时使⽤截断。
php初学者项目这时可以看到,你已经成功地使⽤了其中的截断。
那么⽂件只包含了包含的功能吗?当然不是,之所以会这样,是因为你可以控制可以包含的内容。
你可以创建⼀个⽂件:来进⼀步利⽤这个漏洞。
你可以看到,其中也包括了shell。
那么两者有什么区别呢?其实没有什么区别,原理是⼀样的,但是第⼀个是⽤后缀来介绍的,第⼆个是固定在程序后缀后⾯的。但是可以使⽤%00,因为当程序流(program stream )遇到%00终⽌符(terminator)时它会直接终⽌。
远程⽂件包含
远程⽂件包含就是允许攻击者包含⼀个远程的⽂件,⼀般是在远程服务器上预先设置好的脚本。此漏洞是因为浏览器对⽤户的输⼊没有进⾏检查,导致不同程度的信息泄露、拒绝服务攻击甚⾄在⽬标服务器上执⾏代码。
本地⽂件包含与远程⽂件有着相同的原理,但前者只能包含服务器上存在的⽂件,⽽后者可以包含远程服务器上的⽂件。
对于远程⽂件,你需要考虑以下2点:
1.在php.ini中需要allow_url_include = on和allow_url_fopen= on
2.所需的远程⽂件后缀不能与⽬标服务器的语⾔相同,如⽬标服务器解析PHP代码,则远程⽂件后缀不能为.php。
让我解释⼀下第⼆点,如果你的远程⽂件具有.php后缀,并且你的远程⽂件内容如下所⽰:
<? php phpinfo ();
那么在远程服务器执⾏phpinfo()之后,你就可以获得⽬标服务器的内容。由于它不会运⾏代码,所以包含的信息不是⽬标服务器,⽽是远程
服务器。
如下所⽰:
这是我的PHP5.6版本的远程设备信息,⽬标设备是5.2版本。
接下来是包含⽂件:
你可以看到,包含⽂件后,你的远程设备发⽣了变化,这是为什么呢?
由于⽬标服务器不包含此代码:
<? php phpinfo ();?>
此时,远程服务器会执⾏此代码的源代码,如下所⽰:
所以为了使这个攻击开始运⾏,你需要做⼀些修改:
1.修改配置
2.修改⽂件后缀
此时,你可以再来尝试⼀下包含的攻击向量:
那么你可以看到所需的信息在此包含之后返回,并且你的⽬标设备信息不再改变。
接下来,你要再次为远程⽂件包含做⼀个shell⽰例。
远程⽂件包含使⽤的前提是,符合本地⽂件包含的前提并符合远程⽂件包含其可⽤性的前提。⽂件包含许多伪协议
⽂件中可以包含不同的伪协议,我将在下⾯演⽰其中的⼀些:
1.data:text/plain or data: text/plain; base64
2.php://input
3.php://filter
4.file://
5.zip://
其他协议可以在中到。
data:text/plain
输出直接显⽰在相应的URL中,显⽰参数:data:text / plain。
然后你需要执⾏如下所⽰的php代码:
data:text/plain; BASE64
有另⼀种⽅法来使⽤data: text/plain; base64,不过此时你需要使⽤base64编码来执⾏PHP代码,base64php代码如下所⽰:
## php://input
php://input访问请求的原始数据的只读流(read-only stream),会将post请求中的数据作为php代码执⾏。
你可以看到程序⾃动添加了⼀个.php后缀,因此使⽤包括php://input,将⾃动添加.php,所以它肯定不能正常⼯作。
此时,你可以参考以上的%00技巧来截断⽂件路径。
你可以看到终⽌符(terminator)是⾮常强⼤的。
php://filter
php://filter可以读取php⽂件的代码base64编码的输出并将其返回给你。
例如,你想读取⼀个PHP⽂件,但不希望它是正常的PHP。你可以通过php://filter/read=convert.base64-encode/resource=
../ 读取⽂件代码的内容。
解码base64后,你可以像正常情况⼀样获取内容:
file://
file://⽤于访问本地⽂件系统,不受allow_url_fopen orallow_url_include的影响,你可以使⽤file:// absolute / path / to / file来获取。
zip://
zip://可以访问zip⽂件中的⽂件,但它需要⼀个绝对路径。你可以使⽤zip://[archive absolute path] # [c
ompressed file name]在本地创建⼀个⽂件并将其压缩到⼀个zip压缩⽂件中。
此时,你就可以填⼊绝对路径和⽂件的名称了。那么,你可能会有两个疑问?
为什么你不能成功显⽰包括zip://的错误?
这其中就包含zip://C:/phpStudy/WWW/include/phpinfo.zip.php,这是因为你不想包含这个⽂件,⽽是想把这个⽂件包含在zip⾥。
为什么是#以后的值?
因为#会忽略它后⾯的参数,所以你需要在表单中使⽤%23。还有⼀点就是,包含的⽂件以.php结尾,但你压缩了php后缀的⽂件。
所以如下所⽰,你不需要这个后缀。
⽂件包含攻击初学者指南(LFI / RFI)
0.112019.01.14 15:44:31字数 2,614阅读 2,428
⽂件包含
程序开发⼈员⼀般会把重复使⽤的函数写到单个⽂件中,需要使⽤某个函数时直接调⽤此⽂件,⽽⽆需再次编写,这中⽂件调⽤的过程⼀般被称为⽂件包含。
程序开发⼈员⼀般希望代码更灵活,所以将被包含的⽂件设置为变量,⽤来进⾏动态调⽤,但正是由于这种灵活性,从⽽导致客户端可以调⽤⼀个恶意⽂件,造成⽂件包含漏洞。
⼏乎所有脚本语⾔都会提供⽂件包含的功能,但⽂件包含漏洞在PHP Web Application中居多,⽽在JSP、ASP、程序中却⾮常少,甚⾄没有,这是有些语⾔设计的弊端。
在PHP中经常出现包含漏洞,但这并不意味这其他语⾔不存在。
来张图⽚压压惊
image.png
php中引起⽂件包含漏洞的4个函数:
include()、include_once()、require()、require_once()
区别如下:
include:包含并运⾏指定的⽂件,包含⽂件发⽣错误时,程序警告,但会继续执⾏。
image.png
require:包含并运⾏指定的⽂件,包含⽂件发⽣错误时,程序直接终⽌执⾏。
image.png
require_once() 和 include_once() 功能与require() 和 include() 类似。但如果⼀个⽂件已经被包含过了,则 require_once() 和 include_once()则不会再包含它,以避免函数重定义或变量重赋值等问题。
当利⽤这四个函数来包含⽂件时,不管⽂件是什么类型(图⽚、txt等等),都会直接作为php⽂件进⾏解析。测试代码:
<?php
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论