内容
文件包含漏洞:
PHP文件包含分类:1、本地文件包含;2、远程文件包含
PHP包含漏洞上传技巧
PHP文件包含读写文件
PHP包含日志文件
PHP包含截断0x01 PHP文件包含简介及分类
php文件包含会把任何后缀的文件当做php文件来执行,php对于包含文件提供的功能太强大,太灵活,所以包含漏洞经常出现在php中,但并不意味其他语言没有文件包含漏洞。
php文件包含的函数:include();include_once();require();require_once()
。
include()
与require()
的区别:require()
遇到错误将不再往下执行,include()
反之。后面加_once()
是为了防止重复包含。
分类:1、本地文件包含LFI;2、远程文件包含RFI(需在php.ini中开启allow_url_include
)
0x02 PHP文件包含利用
一、与文件上传结合使用:通过文件上传功能上传任意后缀的文件通过../切换目录进行包含即可;
在php中一些目录切换
../表示上一层目录
./表示当前目录
/单独使用不能表示当前目录,只用xx/这样才能表示xx这个目录
二、文件包含两种典型的格式:
1、需要截断的文件包含
代码原型:include($_GET['xx'].'.php');
或者 include(“$_GET['xx']/test.php”);
想要突破限制就需要截断,通常截断有三种方法。
(1)使用%00来截断
适合场合:Magic_quote
为off的情况下
(2)使用?截断
适合场合:远程文件包含(RFI),相当于又构造了一次Get请求。http://127.0.0.1:81/include.php?xx=http://127.0.0.1:81/shell.txt?
(3)通过使路径长度达到一定长度限制时截断
通常Windows的截断长度为259,Linux的截断长度为4096
使用场合:均适用
由于Windows和Linux的文件名都有一个最大路径长度(MAX_PATH)的限制,因此当提交文件名的长度超过了最大路劲长度限制是就会截断后面的内容,从而达到文件包含的效果include.php?xx=http://127.0.0.1:81/shell.txt//////////////////////////////////////////////////////////////////////
还可以用字符.或者/.,或者./(注意顺序)来截断
2.直接包含的类型
include(“$_GET['xx']“);
可以直接在dir中指定文件名就能实现文件包含,而不需要经过截断处理。
在register_globals为on的情况下,如果变量未初始化则可以达到文件包含的效果,通常网上发的文件包含 漏洞都没有上面两种那么直接,大部分需要register_globals的配合才能实现文件包含。
详见:http://www.2cto.com/Article/201304/204158.html
http://www.2cto.com/Article/201304/201062.html
过滤器
三、php://filter过滤器的利用
1、php文件包含读文件
可以用此方式把源代码以base64编码的方式读出来,然后对源代码进行代码审计127.0.0.1/index?a=php://filter/read=convert.base64-encode/resource=./xxe.php
2、php文件包含写文件
127.0.0.1/index?a=php://input
,然后以post的方式提交要写入的内容,如<?php phpinfo();?>
利用的前提条件:和远程文件包含一样必须开启allow_url_include
才行,且一些能够执行系统命令的函数启用了才行如proc-open、open、oppen、exec、system
所以相对于php文件包含写文件的防护就很明显了,将利用条件关闭或者禁用即可!
更多的思路请参考:php://filter的妙用
四、包含日志文件的利用
当我们碰到无法上传文件,无法写文件这样的一个本地文件包含漏洞时候,我们能有两种方法继续往下渗透1、挖掘新的漏洞,这明显很难,我们还有第二种方法,那就是包含日志文件(在运行切换目录的情况下)
Apache会生成两个日志文件,一个是access.log(用来记录访问日志)和error.log(用来记录错误日志),只要在地址栏访问时加入恶意的代码就会记录到日志文件,最后包含日志文件即可利用。
0x03 php文件包含的防御
1、服务器配置层的防御
设定php.ini中open_basedir的值将允许包含的文件限定在某一特定目录内,这样可以有效的避免利用文件包含漏洞进行的攻击。需要注意的是,open_basedir的值是目录的前缀,因此假设设置如下值:open_basedir=/var/www/test
,那么实际上以下目录都是在允许范围内的:
/var/www/test
/var/www/test123
/var/www/testabc
如果要限定一个指定的目录,需要在最后加上”/“,这一点需要特别注意。
正确写法:open_basedir=/var/www/test/
如果有多个目录,在Windows下目录间用分号隔开,在Linux下面则用冒号隔开。
尽可能的关闭一些不用的函数或者模块,防止文件包含时利用到。
2、代码层的防御
从代码层来讲,在开发过程中应该尽量避免动态的变量,尤其是用户可以控制的变量。一种保险的做法是采用“白名单”的方式将允许包含的文件列出来,只允许包含白名单中的文件,这样就可以避免任意文件包含的风险。
`$filename = $_GET['filename'];`
`switch($filename){`
`case 'one';`
`case 'two';`
`case 'three';`
`include '/var/www/html'.$file.'php';`
`break;`
`default:`
`include '/var/www/html/main.php';`
`}`
还有一种做法是将文件包含漏洞利用过程中的一些特殊字符定义在黑名单中,对传入的参数进行过滤,但这样有时会因为过滤不全,导致被有经验的攻击者绕过。
从这两个方面来防御文件包含,几乎可以防御住文件包含了。
### 0x04 php的一些内置协议
php的内置协议在文件包含漏洞中能起着非常重要的作用,从前面的php://filter读文件就可以看出它是多么强大,把代码读出来相当于白盒测试了。
php的内置协议大概有以下几种:
file:///var/www/html 访问本地文件系统
ftp://:@ 访问FTP(s) URLs
data:// 数据流
http:// — 访问 HTTP(s) URLs
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流
zlib:// — 压缩流
data:// — Data (RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP Archive
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — Audio streams
expect:// — 处理交互式的流
内置协议利用的相关链接:
相关利用一、php://filter的妙用、PHP封装协议安全问题学习
0x05 补充
php文件包含姿势
- 如果网站存在文件上传功能,比如前台传头像之类,可以尝试包含上传的文件,当然文件可控。
- 利用php封装协议php://input和data://,包含post数据造成php命令执行,当然allowurlinclude选项需要打开
- 因为包含的可以是任意文件,log文件也是可以,当我们提交恶意代码时也会被记录,于是包含记录了恶意代码的log文件是个好主意
- 包含/proc/self/environ文件: 这需要PHP运行作为一个具有cgion /proc伪文件的系统且PHP脚本有权访问这些伪文件
- 包含会话文件-这需要攻击者能控制会话中的任何字符串值(注入代码,例如
phpinfo()
),会话文件必须存放在serializedsession文件且PHP脚本能够访问会话文件(通常是/tmp/ sessSESSIONID文件 - 包含其他由php应用创建的文件,只要你能想到的,都可以尝试创建 然后包含他,比如数据库文件,缓存文件,应用程序级别的日志
注意:在包含日志文件时一直不成功,主要是由于直接在浏览器请求的URL会URL编码后才记录到日志文件中,可通过burp来访问网站,即可绕过浏览器URL编码。文件包含和文件上传更配哦
一些姿势:
LFI通过proc/self/environ直接获取webshell
如何优雅的把lfi转化为rce
时间竞争文件包含