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);
$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绝不是为了刷题而刷题,每次做完都应该去反思一下,自己真的弄明白没,出题人的思路你是否都能明白地捋顺。 可能很多师傅会觉得我写的很小儿科…(别骂了别骂了 我争取早日上岸成功当上菜鸡⑧!
|