文件包含漏洞
文件包含漏洞也是一种注入型漏洞,与SQL注入等攻击方式一样,其本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行。有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。
例如:通过PHP函数引入文件时,传入的文件名没有经过合理的验证,从而操作了预想之外的文件,就可能导致意外的文件泄漏甚至恶意代码注入。
分类
文件包含分为远程包含(RFI)和本地包含(LFI)
本地包含就是通过相对路径/绝对路径 的方式能打开并包含 本地文件的漏洞,大部分情况遇到的文件包含漏洞都是 LFI用户可以 动态控制变量
远程包含就是能够包含远程服务器上的文件并执行,可以通过 http(s)或者 ftp 等方式,远程加载文件
条件
allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件
PHP伪协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
Php://input任意代码执行;这种伪协议用于读取原始的HTTP POST数据,可以用于处理上传的文件和表单数据。
data://text/plain 任意代码执行
php://filter
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。它可以可以在访问数据流之前进行过滤,并指定过滤方式例如base64等。
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter经常会被当作php文件被执行,所以我们通常会对他进行编码处理,让它不被执行,从而读取任意文件。(在写题过程中经常用到)
利用条件:
allow_url_fopen=on
allow_url_include没有要求
php://filter有四个可用的参数:
resource="要过滤的数据流" 这个参数是必须的,因为它指定了你要过滤的数据流
read="读链的筛选列表" 可选,可设定一个或者多个过滤器名称,过滤器名称之间用|相隔
write="写链的筛选列表" 可选,与read一样,可设过滤器,用|隔开
";两个链的筛选列表" 任何没有以read=或 write=作前缀 的筛选器列表会视情况应用 于读或写链。
read和write可以不用,直接使用过滤器
php://filter/convert.base64-encode/resource=flag.php
有时也可以直接不要过滤器
php://filter/resource=flag.php
在写题过程中,最常用的是
php://filter/read=convert.base64-encode/resource=flag.php
常见过滤器
1、convert.base64-encode
对数据流进行ba64编码,相当于base64_encode()函数,输出后再进行base64解码,就可以得到我们想要的内容
2、string.rot13
PHP4.3.0及以后版本,对数据流的内容进行rot13编码,等于用str_rot13()函数编码
3、string.toupper和string.tolower
string.toupper,PHP5.0.0及以后版本,将数据流转换成大写,类似于strupper() 函数。
string.tolowerHP5.0.0及以后版本,将数据流转换成小写,类似strtolower() 函数。
4、string.strip_tags
string.strip_tags用来处理掉读入的所有标签,例如XML的等等。在绕过死亡exit大有用处。
php://input
php://input其实很复杂,在官方手册中是这样说的
“php://input allows you to read raw POST data. It is a less memoryintensive alternative to $HTTP_RAW_POST_DATA and does not need any specialphp.ini directives. php://input is not available withenctype=”multipart/form-data”.
他的意思就是“php://input允许您读取原始POST数据。它是$HTTP_RAW_POST_DATA的内存密集度较低的替代方案,不需要任何特殊的php.ini指令。php://input在enctype=“multipart/form data”的情况下不可用。
在伪协议中我们只用理解他是读取POST数据流就行了(个人是这样觉得的)
利用条件:
allow_url_fopen=on
allow_url_include=on
php版本小于等于5.3.0
zip://
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
案列:
Php://input
第一步:
使用url:?file=php://input查看源代码
第二步:
使用BP进行抓包,使用POST传参传入伪协议<?php system(‘ls /’)?>
第三步:
看到了flag,使用cat,得到flag
读取源代码
第一步:
提示了flag在/flag里
第二步:
构造url:?file=php://filter/resource=/flag 得到flag
远程包含
第一步:
使用php://input
使用BP传参,用POST传参传入PHP伪协议,得到flag