第一关

查看源码,开启题目第一关:

各种绕过----[MRCTF2020]套娃 - 图1

这很明显是要让我们绕过的,但是怎么绕呢?

$_SERVER[‘QUERY_STRING’]就是意思是直接检测你url?,就是?后面的所有

第一个if判断语句,如果获得的参数QUERYSTRING里存在 ‘‘ 这个字符则直接die出局,并且%5f就是他的unending编码也给ban了。

这不禁让我回忆起之前在一篇文章中提到的一个特殊情况关于php特殊字符转下划线

这里面哪个是利用点呢?

经过测试后发现,’+’,’ ‘(空格),’.’都可以转义为下划线,但是上文提到的]却不行,我也不知道为啥。。。

参数名搞定了,还有参数值呢?要我们匹配到不全等于2333,又要匹配23333开头23333结尾。

各种绕过----[MRCTF2020]套娃 - 图2

用%0a进行绕过吧。第一关就这样通过了

各种绕过----[MRCTF2020]套娃 - 图3

第二关

一进来说我们的ip被ban了,只有本地才能访问

各种绕过----[MRCTF2020]套娃 - 图4

既然刚刚网页源码有提示,我们也看看这个有什么吧

各种绕过----[MRCTF2020]套娃 - 图5

我又想到一个东西。。在攻防世界里有个fuck啥的东西,在网页控制台可以解析。

让我们post一个Merak过去。。

各种绕过----[MRCTF2020]套娃 - 图6

POST过去后得到一长串的php代码

各种绕过----[MRCTF2020]套娃 - 图7

第三关

源代码如下

各种绕过----[MRCTF2020]套娃 - 图8

前面也分析了只有本地才能访问,所以这里给了我们一个getIp函数去调取我们的ip是否等于127.0.0.1,这里无所谓,因为我们用burp抓包修改xff或者client-ip都可以绕过这个判定条件

下面的file_get_contents($_GET[‘2333’])这个点的意思是我们传入一个2333的参数,file_get_contentes是将整个数据读入一个字符串中。这在我写过的一个伪协议的引用[ZJCTF 2019]NiZhuanSiWei中有个知识点提到

所以也就是php://input和data://都可以进行写入。

那我们如何选择呢?其实我用得比较多的是php://input,但是如果看过上面这个文章就发现不太对劲了。为什么?上面文章写到的是只有一个参数,也就是

各种绕过----[MRCTF2020]套娃 - 图9

但是我们现在还有post一个参数是merak,所以这样比较尴尬,我上传不了(或者说我不会),所以这次我们使用data://来上传。

**2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=**

用心观察的人会发现,他包含了了一个flag.php,那大胆猜测flag就在这个flag.php里了

各种绕过----[MRCTF2020]套娃 - 图10

file_get_contents()可以帮助我们显示文件的内容,那么现在有个问题来了,这change函数是干啥用的。

解释一下change函数的两个核心

各种绕过----[MRCTF2020]套娃 - 图11

chr() 函数从指定的 ASCII 值返回字符。

ASCII 值可被指定为十进制值、八进制值或十六进制值。八进制值被定义为带前置 0,而十六进制值被定义为带前置 0x。

各种绕过----[MRCTF2020]套娃 - 图12

ord() 函数返回字符串的首个字符的 ASCII 值。

各种绕过----[MRCTF2020]套娃 - 图13

首先定义用法,然后将变量进行base64解码(这说明后面POST参数file的值必须先进行base64编码),然后通过一段for循环,这段for循环的作用是先将字符转换为ASCII码,再将ASCII码逐步+$i*2$i初始值为0,然后再转回字符

其中strlen函数作用是计算字符的数目,chr是把ASCII转成字符,ord是把字符转成ASCII数字

经过对照ASCII码表和计算,我们需要传递到file参数的值为“fj]a&fb(flag.php经过change函数转换为fj]a&fb)”的base64值,也就是ZmpdYSZmXGI=

(可费劲了。。)

所以,我们最终提交的两个get参数为

各种绕过----[MRCTF2020]套娃 - 图14

记得把merak这个参数去掉,不然会被die出去

然后查看源码即可

各种绕过----[MRCTF2020]套娃 - 图15