[CISCN 2019 初赛]Love Math【国赛】

[CISCN 2019 初赛]Love Math【国赛】

不经一番寒彻骨,怎得梅花扑鼻香。

若教眼底无离恨,不信人间有白头。

这道国赛题看着题目【初赛】觉得还行~就简单的记录一下

进入题目就给了源码,不愧是初赛的题目,也不需要你扫后台了;

[CISCN 2019 初赛]Love Math【国赛】

进行简单的代码审计,发现我们需要GET传参一个c,然后黑名单过滤了很多,然后它会循环遍历你的内容,看看是否存在黑名单的内容,如果存在,就给你返回“请不要输入奇奇怪怪的字符”;如果没有就继续向下执行;

后面是一个白名单的过滤,我们在实际操作的时候程序员往往是白名单过滤,因为黑名单总有很大的概率可以绕过去,所以现在程序员往往使用白名单,我们看到,白名单里有很多的函数可以使用,下面一句是个正则的匹配,意思就是我们在c传入的内容里进行循环遍历并匹配,如果我们用了除白名单以外的函数,就会返回(“请不要输入奇奇怪怪的函数”);如果我们两个都绕过了,就会帮我们执行;{简直就是rce啊!!!}

我们开始,首先看看白名单里面的函数,看到有一个base_convert;这个php函数的作用是在任意的进制之间转换数字;一般的用法都是【base_convert(xxxx,8,16)就是将八进制转化为十六进制】,既然有了这个函数,那就是我们的突破点;这个题有两种方法,我都分别介绍一下:

方法一:我们就使用_GET进行传参,

方法二:我们使用header进行传参;

先来方法一,

首先,我们应该知道php函数的动态特性;php函数可以通过赋值,将函数名赋给变量,举个简单的例子:$a=system;$a();这样就实现了函数名的转化,对于这道题来说是很好的,因为它限制了字符的总长度,80是个临界;还有一点就是在php中我们的函数名将会被默认为字符串!!!

其次我们再来看看我们需要的函数第一个是base_convert;第二个我们想要用到dechex;这个函数很明显就是将十进制转化为十六进制,都是我们可以利用的,既然有这个函数,我们就希望可以通过十六进制转化为字符,最后服务器得到的就是一串字符,就可以执行命令了;那么有没有这样的函数呢?答案是有的比如hex2bin这个函数就可以将十六进制转化为ascii的字符,所以我们的思路就来了,想办法做出hex2bin,然后让它和dechex相结合,最后输出字符串,有了思路就开始干!

重点:

我们首先明确转化后的字符是什么,肯定是 '_GET'这个,所以我们就开始构造;先反解出的的十六进制,需要达成hex2bin(xxxxxxx)是上面的GET;所以我们要做出hex2bin这就利用了base-convert{是下划线}这个函数了,我们可以直接进行进制的转化,【这里解释一下为什么需要36进制:因为36进制涵盖最广,它涵盖了0-9,A-Z(大小写通用,不区分),又因为我们的函数hex2bin是由数字和字母组成的,所以我们需要用36进制来进行转化】这里将36进制转化为10进制,所以我们的写法就是base-convert{是下划线}(37907361743,10,36);所以我们的hex2bin就转化出来了,接下来就是用dechex了,是16进制转化为字符,所以我们使用逆向的思维,我们先将-GET{是下划线}转化为十六进制;转化结果入下,再将十六进制转化为字符即可;

[CISCN 2019 初赛]Love Math【国赛】

[CISCN 2019 初赛]Love Math【国赛】

[CISCN 2019 初赛]Love Math【国赛】

base-convert{是下划线}(37907361743,10,36)(dechex(1598506324))这样一来,我们就转化成了hex2bin(dechex(1598506324))=>_GET,ok现在开始用到我上面讲过的php函数的动态特性了可以让$pi=base-convert{是下划线}(37907361743,10,36)(dechex(1598506324));后面就可以直接使用了,所以最终构造的语句如下:$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat%20/flag 因为黑名单黑了[ ] 所以这里使用{}来代替;最后就是

(_GET){system}((-GET{cat /flag})) 这里其实和我们平常的木马是一样的(如果你理解了本质的话<?s1mple @eval($ _GET["1"])xx?>&1=system("cat /flag")

我们就用get的方式传入了命令;

[CISCN 2019 初赛]Love Math【国赛】

ok flag到手 美滋滋~~~~~

下面来介绍方法二:

出了get传参以外,我们也可以使用header进行传参。

这里介绍一个函数,getallheaders()这个函数适用于提取所有的HTTP请求标头;用法则是getallheaders(void):数组,这个数组就是我们需要在header里面加入的,所以我们按照方法一的方法进行构造

base_convert(696468,10,36) => "exec" $pi(8768397090111664438,10,30) => "getallheaders" exec(getallheaders(){1}) 中间用逗号隔开;

我写出apyload: $pi=base_convert,$pi(696468,10,36),($pi(8768397090111664438,10,30)(){1})

然后你只需要抓包,点击重发,在header中加入 1:cat /flag 就可以;[CISCN 2019 初赛]Love Math【国赛】

ok flag到手,美滋滋~~~~

上一篇:字符串的格式化


下一篇:Shell 运算符/条件判断/流程控制