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

web:[GXYCTF2019]禁止套娃

题目

打开页面显示为

没有其他信息,查看源代码也是空的

用dirsearch扫一下

可能是git源码泄露,可以用githack获取源码

python Githack.py http://5063c85b-a33d-4b6f-ae67-262231a4582e.node4.buuoj.cn:81/.git/

去工具所在的目录找到index.php文件

打开文件显示如下,需要代码审计

代码为简单的php脚本,接受名为‘exp’的get参数。

  1. data://协议用于访问数据(如base64编码的数据)。
  2. filter://协议用于过滤数据。
  3. php://协议用于访问各种内置的PHP流(如输入、输出、文件等)。
  4. phar://协议用于访问PHAR(PHP归档文件)。
  5. /i标志表示不区分大小写。

首先使用了正则表达式匹配来检查exp参数中是否包含“data://”,"fliter://","php://","phar://"等协议,日若包含其中任何一个协议,会输出

后使用正则表达式替换的方式检查参数中是否存在类似函数调用的语法,即以字母和下划线开头,后跟括号内可以由递归调用。若检查结果为“;”,代码会执行“eval($_GET['exp'])”,即执行exp中的代码

最后代码会检查参数中是否包含特定字符串,如"et", "na", "info", "dec", "bin", "hex", "oct", "pi", "log"等。如果存在这些字符串中的任意一个,代码将输出"还差一点哦!"并终止执行。

总结上述代码审计可知,被过滤掉了data://、filter://、php://、phar://、et、na、info、dec

bin、hex、oct、pi、log

对第二个if

 (?R)是引用当前表达式,(?R)? 这里多一个?表示可以有引用,也可以没有。引用一次正则则变成了[a-z,_]+\([a-z,_]+\((?R)?\)\),可以迭代下去,那么它所匹配的就是print(echo(1))、a(b(c()));类似这种可以括号和字符组成的,这其实是无参数RCE比较典型的例子

if(';' === preg_replace('/[a-z,_]+(?R)?(?�)?/', NULL, $_GET['exp']))可以看出这是典型的无参数rce

因为不能传参,所以只能利用函数回显套娃来代替目标参数

解法一:

scandir() :将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称(glob()可替换)
localeconv() :返回一包含本地数字及货币格式信息的二维数组。(但是这里数组第一项就是‘.’,这个.的用处很大)
current() :返回数组中的单元,默认取第一个值。pos()和current()是同一个东西

逐步解析构造payload

var_dump(localeconv());能发现string[1]就是一个“.”,这个点是由localeconv()产生的

var_dump(localeconv()):是一个PHP函数调用,用于打印当前的本地化信息。它返回一个关联数组,包含了与当前地区相关的数字格式、货币格式、日期格式等信息。

array(19) {["decimal_point"]=>string(1) "."["thousands_sep"]=>string(1) ","["int_curr_symbol"]=>string(3) "USD"// ...
}

 利用current()函数将这个点取出来的,点代表的是当前目录,那接下来就很好理解了,我们可以利用这个点完成遍历目录的操作,相当于就是linux中的ls指令


current()取第一个值,那么current(localeconv())就能构造一个‘.’,'.' 表示当前目录,scandir('.') 将返回当前目录中的文件和子目录,从代码审计得知flag所在的文件名就是flag.php

flag的文件名在比较后端我们可以通过array_reverse()将数组内容反转,让它从倒数第二的位置变成正数第二

移动指针读取第二个数组,参照下列数组移动操作可知我们应选用next()函数

end() : 将内部指针指向数组中的最后一个元素,并输出
next() :将内部指针指向数组中的下一个元素,并输出
prev() :将内部指针指向数组中的上一个元素,并输出
reset() : 将内部指针指向数组中的第一个元素,并输出
each() : 返回当前元素的键名和键值,并将内部指针向前移动

highlight_file()返回文件内容

所以最终的payload为

?exp=highligth_file(next(array_reverse(scandir(current(localeconv())))));
解法二:

在已知文件名flag.php的情况下直接读文件

已知文件名,改包手动添加cookie头把文件名写在PHPSESSIONID后

构造payload为

readfile(session_id(session_start()));

session_start()是PHP的一个函数,用于启动一个新的会话或者恢复一个已存在的会话。session_id()函数返回当前会话的ID。

readfile()是PHP的另一个函数,用于读取文件内容并将其输出到浏览器。

参考文章链接:

BuuCTF [GXYCTF2019]禁止套娃详解(两种方法)-CSDN博客

BuuCTF [GXYCTF2019]禁止套娃详解(两种方法)-CSDN博客

相关文章:

  • gwas数据获取如何获取完整的GWAS summary数据(1)------GWAS catalog数据库
  • 【JavaEE初阶】 JavaScript基础语法——贰
  • R语言——taxize(第三部分)
  • Linux 常用命令学习笔记
  • Postgresql常用命令函数
  • 目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】目标视觉检测
  • 二百零七、Flume——Flume实时采集5分钟频率的Kafka数据直接写入ODS层表的HDFS文件路径下
  • 使用 AWS boto3 库从 s3 桶中批量下载数据
  • UE TransformVector 学习笔记
  • Go 语言中的map和内存泄漏
  • 5-什么是猴子补丁,有什么用途?什么是反射,python中如何使用反射?http和https的区别?
  • 算法训练 第八周
  • 11 月 11 日 ROS 学习笔记——ROS 架构及概念
  • 五分钟,Docker安装kafka 3.5,kafka-map图形化管理工具
  • 【C++ Primer Plus学习记录】for循环
  • [PHP内核探索]PHP中的哈希表
  • @jsonView过滤属性
  • [ JavaScript ] 数据结构与算法 —— 链表
  • “大数据应用场景”之隔壁老王(连载四)
  • 【刷算法】从上往下打印二叉树
  • Fabric架构演变之路
  • gcc介绍及安装
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • java2019面试题北京
  • JavaScript学习总结——原型
  • Linux链接文件
  • Octave 入门
  • react-native 安卓真机环境搭建
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 翻译--Thinking in React
  • 解决iview多表头动态更改列元素发生的错误
  • 力扣(LeetCode)22
  • 微信小程序开发问题汇总
  • 线性表及其算法(java实现)
  • ​​​​​​​​​​​​​​Γ函数
  • ​iOS实时查看App运行日志
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • #Java第九次作业--输入输出流和文件操作
  • (WSI分类)WSI分类文献小综述 2024
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)计算机毕业设计大学生兼职系统
  • (九)One-Wire总线-DS18B20
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • .chm格式文件如何阅读
  • .CSS-hover 的解释
  • .gitignore文件---让git自动忽略指定文件
  • .NET CLR Hosting 简介
  • .net2005怎么读string形的xml,不是xml文件。
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .Net下的签名与混淆
  • @javax.ws.rs Webservice注解
  • @property @synthesize @dynamic 及相关属性作用探究
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧