1.文件包含
文件包含:开发人员将可重复使用的内容写到单个文件中,使用时直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。这样编写代码能减少代码冗余,降低代码后期维护难度,保证网站整体风格统一,比如:导航栏、底部栏等。
2.文件包含漏洞
文件包含漏洞:开发人员希望代码更加灵活,有时会将包含的文件设置为变量,用来动态调用,由于这种灵活性,可能导致攻击者调用恶意文件,造成文件包含漏洞。
漏洞产生原因:
- 存在一些和文件包含有关的函数
- 这些参数由用户可控
- 没有对用户的输入执行严格的过滤
- 如果是远程文件包含的话,有一些危险的配置 例如allow_url_include='on'
3.文件包含相关的函数
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web应用中居多,而在JSP、ASP程序中却非常少,甚至没有。PHP中提供了四个文件包含的函数,分别是inc1ude()、include_once()、require()和 require_once()。它们的特点为:
include:出现错误时,会抛出一个警告,程序继续运行。
include_once:出现错误时,会抛出警告,且仅包含一次。
require:出现错误时,会直接报错并退出程序执行。
require_once:出错时直接退出;且仅包含一次。
4.php文件包含的特性
只要被包含文件的文件内容符合PHP语法,不管文件类型是什么,该文件都会被php解释器去解析执行;如果文件内容不符合PHP语法,就会将该文件内容读取出来。
5.漏洞利用思路
- 包含一些敏感的配置文件,获取目标敏感信息
- 配合图片马getshel
- 包含临时文件getshell
- 包含session文件getshel
- 包含日志文件getshell(Apache等)
- 利用php伪协议进行攻击。
6.文件包含类型
6.1本地文件包含
概念:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,更多的会包含一些固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合网站的文件上传功能,从而形成更大的威力,
简单来说:当包含的文件在服务器本地时,就形成了本地文件包含
6.1.1利用方式
1)上传图片马,包含图片马GetShell
2)读取网站源码以及配置文件
3)包含日志文件GetShell
6.1.2读取敏感信息
利用file伪协议读取
例如:http://example.com/file.php?file=file://c:/windows/win.ini
windows常见敏感文件
C:\boot.ini | 查看系统版本 |
C:windowslsystem32linetsrMetaBase.xm | iis配置文件 |
C:lwindowslrepairsame | 存储windows系统初次安装密码 |
C:ProgramFileslmysqllmy.ini | mysql配置信息 |
C:\ProgramFileslmysqldatalmysqluser.MYD | mysql root密码 |
C:lwindowslwin.ini | 系统信息,常用于注入木马 |
Linux常见敏感文件
/etc/passwd | 账户信息 |
/etc/shadow | 账户密码文件 |
/etc/apache2/apache2.conf | Apache2默认配置文件 |
/etc/my.conf | mysql配置文件 |
/etc/php/5.6/apache2/php.ini | php相关配置 |
/etc/httpd/conf/httpd.conf | apache配置信息 |
6.2远程文件包含
概念:如果应用程序的配置还允许包含远程的其它服务器上的文件,恶意攻击者就有可能构造恶意的脚本然后通过包含并予以执行,进而获取WEB应用的敏感数据或控制权,这种方式称为远程文件包含。
简单来说:当包含的文件在远程服务器上时,就形成了远程文件包含。
利用前提:a1low_ur1_fopen=on((默认开启)并且a11ow_ur]_include=on(默认关闭),可在\phpstudy\PHPTutorial\php\php-5.2.17\php.ini中配置。
7.PHP伪协议
● file:// — 访问本地文件系统
● http:// — 访问 HTTP(s) 网址
● ftp:// — 访问 FTP(s) URLs
● php:// — 访问各个输入/输出流(I/O streams)
● zlib:// — 压缩流
● data:// — 数据(RFC 2397)
● glob:// — 查找匹配的文件路径模式
● phar:// — PHP 归档
● ssh2:// — 安全外壳协议 2
● rar:// — RAR
● ogg:// — 音频流
● expect:// — 处理交互式的流
7.1file:
作用:用于访问本地文件系统,常用来读取本地文件使用方法:file://文件的绝对路径和文件名
示例:
绝对路径:http://127.0.0.1/include.php?file=file://c:/windows/win.ini
相对路径:http://127.0.0.1/include.php?file=./phpinfo.txt
7.2PHP://input
php://input 可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行,如果存在文件包含漏洞,可将php://input作为文件名传入,同时在post中设置想要注入的代码,php执行时就会将post的内容作为php代码执行。
前提条件:
allow_url_fopen : off/on
a1low_url_include: on
形式:
php://input
post:php代码
如果要写文件,则可以把php代码换成以下(该代码的意思为打开shel.php执行写入的操作,写入的内容为一句话木马):
<?php fputs(fopen('shel1.php','w'),'<?php@eval($_PosT["a"])?>');?>
7.3 php://filter
php://filter是一种元封装器,设计用于数据流打开时的筛选过滤。主要用来查看源码。
用 法:php://filter/read=convert.base64-encode/resource=filepath,表示以base64编码的方式进行读取指定路径的文件。
resource=<要过滤的数据流> | 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
read=<读链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(1)分隔。 |
write=<写链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(T)分隔 |
7.4 phar://
作用:属于压缩流,可以访问压缩文件中的子文件,不需要指定后缀名,可修改为任意后缀,比如:jpg png gif xxx 等等
可以使用相对路径也可以使用绝对路径
举例:
http://127.0.0.1/03web17/include/test.php?file=phar://./phpinfo.zip/phpinfo.txt
7.5zip://
zip://、bzip2://、zlib:// 协议
作用:属于压缩流,可以访问压缩文件中的子文件,可以不需要指定后缀名,可修改为任意后缀。比如:jpg png gif xxx 等等。
优缺点:优点是可以绕过包含的固定后缀。缺点是需要知道文件的绝对路径。
举例:
zip://[压缩文件绝对路径]%23[压缩文件内的子文件名](#编码为%23)
压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg
http://127.0.0.1/03web17/include/test.php?file=zip://D:/phpstudy/PHPTutorial/www/03web17/inc1ude/phpinfo.jpg%23phpinfo.txt
7.6 data://
数据流封装器,以传递相应格式的数据
使用条件:
alow_url_fopen:onallow_url_include :on
作用:自PHP>=5.2.0起,可以使用 data://数据流封装器,以传递相应格式的数据,通常可以用来执行PHP代码
用法:
data://text/plain,[php代码]data://text/plain;base64,[base64编码的php代码]
举例:
file=data://text/plain,<?php phpinfo();?>file=data://text/plain;base64,Pp9waHAgcGhwaw5mbygpoz8+//ur]中+要改成%2B
8.防御方案
- 设置白名单:代码在进行文件包含时,如果文件名可以确定,可以设置白名单对传入的参数进行比较。
- 路径限制:限制被包含的文件只能在某一文件夹内,PHP配置文件中有open_basedir选项可以设置用户需要执行的文件目录,如果设置目录的话,PHP仅仅在该目录内搜索文件。
- 关闭危险配置:PHP配置中的allow ur include选项如果打开PHP会通过Include/Require进行远程文件包含,由于远程文件的不可信任性及不确定性,在开发中禁止打开此选项,PHP默认是关闭的。
- 过滤危险字符:严格检查用户输入,参数中不允许出现 ./ 之类的目录跳转符。
- 尽量不要使用动态包含,可以在需要包含的页面固定写好,如:include('head.php')。