题目链接:[BJDCTF2020]ZJCTF,不过如此
解题思路
访问靶场链接,出现的是一段php源码,接下来做一下代码审阅,发现这是一道涉及文件包含的题
主要PHP代码语义:
file_get_contents($text,'r');
把$text变量所制定的文件读入一个字符串中
'r'表示只读
preg_match("/flag/",$file);
正则表达式,判断文件中是否包含"flag"字符串
include($file);
文件包含函数,如果文件中是普通字符串,则输出
如果有php代码,则会执行
通过代码审计,发现我们可以将text
设置为I have a dream
,来进入循环,并利用伪协议读取并加密next.php
文件源码,利用include
函数输出从而得到next.php
文件源码。
接下来尝试从url
中设置text=I have a dream
,试图通过get
赋值,但无果,因为这样会变成将text
变量的值赋为I have a dream
。我们的目的是使text
这个变量所制定的文件中写入I have a dream
,进而通过比较判断语句,此时就要想想办法,怎么做到?
利用PHP中的伪协议可以做到:
1、php://input
:php中的特殊输入流,用于读取POST中的值
2、data:///变量名/plain,明文
:php中的数据传输协议,与php://input类似,将plain后的明文或是Base64密文传入字符串
Base64密文语法:?text=data://text/plain;base64,密文
以上两种方法都能够通过比较。此处涉及PHP伪协议知识,详见:CTF文件包含教程
回到源码,通过比较语句后,下一步就是利用include函数得到next.php文件源码了,我们可以用php://filter/
协议来读取源码:
php://filter/read=convert.Base64-encode/resource=next.php
其中:
php://filter表示php过滤器
/read后面跟上要使用的过滤器,这里的convert.Base64-encode就是调用Base64过滤器对文件内容进行编码
/resource后面是输入的文件名
构造好的url如上文所示,访问即可得到密文,解码后得到next.php源码:
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
function getFlag(){
@eval($_GET['cmd']);
}
至此先告一段落,主要掌握文件包含漏洞知识点,详见:文件包含详解,后续知识点还未学习,待学习后继续解析。