1ndex
0x00 Review
a.关于php流封装
每个流都有一个协议和一个目标。指定协议和目标的方法是使用流标识符。其格式如下
<scheme>://<target>
<scheme>是流的封装协议,<target>是流的数据源
此处有一个误区
我们使用file_get_contents()、fopen()、fwrite()和fclose()函数读写文件系统。因为PHP默认使用的流封装协议是file://,所以我们很少认为这些函数使用的是PHP流。
但这些其实都算是使用php流了
封装协议 ¶
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
引用自:https://shadowdragons.github.io/2019/06/10/php-stream/
Q:file_get_contents()可以读取其他封装协议的数据流吗
(写的有些基础,师傅们可以直接跳过了
实操一下
显然是可行的,需修改配置文件
extension=php_openssl.dll
allow_url_include = On
也就是说此函数可以处理除file之外的封装协议数据流
include
关于include与file_get_contents
include引入的会成为源码的一部分,而file_get_contents单纯返回字符串,不会被解释器解析
php://filter
糊一下手册
我觉得光看documentation可能会有些抽象
php://filter可以对你使用的数据流做过滤作用
php://filter/xxx(你使用的过滤器)/resource=(后接要过滤的数据流)
这边的过滤器你可以自己设定若干个
https://blog.csdn.net/destiny1507/article/details/82347371
可以再看看这个师傅的blog
实操中file_get_contents与include的区别(顿悟…!为什么还得麻烦的加个base64-encode)
发现同样是使用过滤器读链
include可以直接在前端弹出源码,但file_get_contents则需要echo出来
后来问了一下dl,才意识到我是真彩笔哈
先前我们说过file_get_contents只是单纯返回字符串
而include是将其包含至文件源码的一部分
有同学可能疑惑为什么读源码还要麻烦的加个base64-encode??
因为这边不想让服务端把这些源码解释掉,我们在访问不同网站时都不需要配置对应的解释器或运行环境,因为我们的客户端只是能理解html的浏览器罢了。
php是服务器端解释的语言,http提交请求给服务器,由服务器对php文件进行解释,最终生成相应的html,作为响应返回到浏览器,所以你看到的就是html。我们在读链中进行base64编码后,php解释器就认不出源码了,也不会去解析它。
实操一下
如果include一个纯文本,php解释器没有去解析他,就直接呈现在前端了。
所以这里过滤器的作用就是骗过服务端。
0x01 开冲
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
有了上述铺垫这边可以直接秒了哈
file_get_contents直接接data://封装就够
payload:
data://text/plain,welcome to the zjctf
file提示useless.php
用 php://filter/convert.base64-encode/resource=useless.php读一下源码
后面有点ez不说了
0x02 rethink
LFI和php封装协议这些在我一开始做ctf-web时就已经接触了,但当时做的笔记都是非常的急功近利,完全没有去反思为什么用这个封装协议,为什么能这么用。Anyway,CTF绝不是为了刷题而刷题,每次做完都应该去反思一下,自己真的弄明白没,出题人的思路你是否都能明白地捋顺。
可能很多师傅会觉得我写的很小儿科…(别骂了别骂了
我争取早日上岸成功当上菜鸡⑧!