1 |
|
与前面的题相比,没有了 eval()
函数,但可通过 data://
伪协议解决。
什么是 data://
伪协议:
data://
伪协议允许直接在 URI 中嵌入数据(如文本或 Base64 编码的内容),常用于动态生成数据流。
tips:
URI 统一资源标识符,URI 包括 URL 和 URN,或其他特殊形式,比如此处的 data://
伪协议。URL 通过协议、位置等标识资源;URN 仅通过名称标识资源。
人话:data://
伪协议相当于在 data://
后写入数据, data://
及其后的数据会被当作文件处理。
看看实例就明白了:
1 | $uri = 'data://text/plain;base64,SGVsbG8gV29ybGQh' |
1 | data://<MIME类型>[;charset=<编码>][;base64],<数据> |
核心参数:MIME类型、
charset
(可选)、base64
(可选)、数据内容。分隔符:用分号
;
分隔参数,逗号,
分隔参数和数据。参数选项:
MIME类型:指定数据的媒体类型(Multipurpose Internet Mail Extensions)。常见的MIME类型有:
类型 示例值 说明 文本类 text/plain
纯文本(默认值,可省略但建议显式声明) text/html
HTML 内容 text/css
CSS 样式表 text/javascript
JavaScript 代码 图像类 image/png
PNG 图片 image/jpeg
JPEG 图片 image/gif
GIF 图片 应用类 application/json
JSON 数据 application/xml
XML 数据 application/pdf
PDF 文档 其他 audio/mpeg
MP3 音频 video/mp4
MP4 视频 charset(字符编码):指定数据的字符编码(仅对文本类 MIME 类型有效)。如UTF-8 与 GBK。
base64:声明数据部分使用 Base64 编码(显而易见非文本类数据必须使用)。(可用于绕过过滤)
适用场景:
- 数据包含特殊字符(如
,
;
\n
)。 - 二进制数据(如图片、音频)。
- 数据包含特殊字符(如
数据部分:实际内容,可以是明文或 Base64 编码的字符串。未启用 Base64 编码,数据按明文处理时,需对特殊字符(
,
/;
/%
)进行 URL 编码(本身作为参数、数据的分隔符)。
本题解析
1 | ?c=data://text/plain,<?php system("tac fla*.php")?> |
就是让 data://text/plain,<?php system("tac fla*.php")?>
作为被包含的文件,它将会因为 <?php
被识别为 PHP 文件,被解析并执行。于是$flag
被赋值并回显,OK。
变体
将正则表达式修改为
"/flag|php|file/i"
,<?php ?>
没法用,但可用短标签<? ?>
、**短输出标签<?= ?>
**或者 Base64 编码绕过。(<? ?>
就是简化版的<?php ?>
;<?= ?>
用于直接输出内容,如<?= "Hello" ?>
等价于<?php echo "Hello"; ?>
。此外<? ?>
仅在 PHP 配置文件php.ini
里short_open_tag
选项设置为On
时有效;<?= ?>
则无需配置即生效)将文件包含改为
include($c.".php");
的情况(往data://
数据的最后拼接了.php
)。其实只有<?php ?>
中的内容会被解析,文件中 PHP 代码以外的文本会直接回显到网页(例如,此处如果$c
要执行的命令无任何返回值,则网页上只会出现.php
,因为.php
在 PHP 代码以外)