web基础漏洞-文件包含漏洞
1、定义
文件包含是一种常用编程技巧,即一个文件中可以包含引入其他文件,以方便代码的复用。
文件包含漏洞,是因为用户可以控制包含的文件路径,从而造成危害。
- 包含远程php文件,然后执行代码
- 包含远程一般文件,进行网站篡改
- 包含本地文件,暴露信息,比如系统账号密码
2、相关语言和函数
文件包含可能出现在PHP、ASP、JSP等语言中,常见的进行文件包含的函数包括:
- php:include()、include_once()、require()、require_once()、fopen()、readfile()等
- asp:include file、include virtual等
- jsp:ava.io.File()、java.io.FileReader等
其中,php由于本身特性以及该语言文件包含功能更常用,导致文件包含漏洞更常见。
实际上,shell、python等其他语言也可能存在文件包含。
3、分类
主要可以分为本地文件包含(Local File Inclusion,LFI)和远程文件包含(Remote File Inclusion, RFI)。
(1)本地文件包含
即用户可控文件参数是指定一个本地主机的文件
- 直接指定路径,可能是相对路径,也可能是绝对路径。
- 在php中可能要求file协议,则必须是绝对路径,且不能指定php文件
(2)远程文件包含
即通过http协议指定一个远程主机上的文件
php默认是不允许远程包含的,需要配置allow_url_include为true才可以使用。
4、危害
(1)远程包含php文件或者可解析的文件
(2)包含配置文件读取敏感信息
由于是非源码文件,可以直接读取
- 操作系统配置文件,如/etc/passwd、hosts、boot.ini、日志文件等
- 数据库配置文件,如my.ini、my.cnf等
- web中间件配置文件,如httpd.conf、php.ini等
(2)读取web应用程序源代码
由于是程序代码,无法直接读取,需要借用php Wrapper功能,其是php内置的类URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数。
file:// 访问本地文件系统
http:// 防护http/https网址
ftp:// 访问ftp/ftps urls
php:// 访问各个输入、输出流
zlib:// 压缩流
data:// 数据
glob:// 查找匹配的文件路径模式
phar:// php归档
ssh2://
rar:// rar文件
ogg:// 处理交互式的流
expect:// 用于数据流打开时的筛选过滤应用
filter://
利用php://filter的数据流读写过滤应用来获取的源码文件进行加密处理,这样就不会被解析器解析执行了。
http://ip/lfi/lfi.php?file=php://filter/read=convert.base64-encode/resource=lfi.php%00
(3)包含用户上传文件
php的一个重要特性,就是在php程序中包含一个新的文件时,php解析程序并不会检查被保护文件的类型,而是直接将其作为php代码执行。也就是说,任何类型的文件,只有其被一个php文件包含,其内容就可以被当做php代码执行。
比如上传图片马。
(4)包含特殊的服务器文件
无法通过上传点上传文件时,可以通过构造特定的http请求包,向服务器的几类特殊文件写入特定的php脚本。
- 服务器日志文件:客户端的所有http请求都会被服务端容器记录到访问日志文件中,比如apacheroot/logs/access.log。ftp等协议和软件也可以被利用。
- php临时文件:php特性,当向服务器上任意的php文件提交post请求并上传数据时,服务端生成临时文件,虽然文件名是随机的,但根据phpinfo()的一些特性可以找茬生成的临时文件名称,以及专用python脚本lfi_tmp.py。
- session文件:一般保存在/tmp/、/var/lib/php/session/等目录下,文件名一般是sess_SESSIONID的形式
- linux下的环境变量文件:用户请求的user-agent信息保存在/proc/self/environ文件。
5、防护
(1)参数审查
- 一般尽量避免用户控制文件包含的参数
- 禁止敏感字符,比如%00
- 通过黑白名单严格检查参数值
(2)防止变量覆盖
某些情况下,用户控制的变量可能覆盖开发者构建的其他变量,需要避免这种情况,对变量的生命周期和作用范围进行严格管理
(3)环境配置
- allow_url_include,尽量配置为false,避免远程包含
- magic_quotes_gpc选项决定了参数是否可以使用%00等特殊字符
- register_globals,建议设为Off
- open_basedir:可以限制php只能操作指定目录下的文件
- display_errors:用于设置是否打开错误回显,建议关闭
- log_errors:建议关闭