PHP特性(其二)

        第一题:

        双美元号涉及到一个变量的覆盖,题目中有die($suces)、die($error),如果我们能将suces覆盖成$flag,或者error覆盖成$flag,那麽我们就可以得到flag了。

        按照这个思路去构造payload,题目中有foreach去循环遍历GET数组中的数据,key代表键,value代表值,通过阅读发现,不能给GET传入error,也就是?error=xxx这是不可以的。那麽题目为什么会加这句代码限制我们传入变量的名称呢(数组中的键),这就提到了第一段说的变量覆盖问题。如果不加这句话,我们可以这样做:?error=flag。再加上下面$$key=$$value,就变成了$error=$flag,接下来我们只要想办法让die($error)执行就可以拿到flag了。现在,题目显然不想让我们这样做。我们可以利用一下suces,我们可以试试?suces=flag,这样最后还是走到了die($error)这里,因为我们post的flag变量必须要为flag,这样构造没法绕过这里,只能想别的思路了。   

        第一个foreach这里我们所能想的只有这些,再往下看代码,第二个foreach这里,它不允许我们将$flag的值给别的变量,但是在第一个foreach里我们已经把flag给suces了,接下来,我们再把suces给error不就可以了。所以payload:

     flag变量不post也可以,只要想办法让代码走到die(error)即可,因为现在error已经变成flag了。

        第二题:

        看题目,我们需要给两个变量post值,这里注意把第二个变量改成CTF[SHOW.COM传值(空格,点,[传值时,会变成下划线,并且如果是[,后面不合法的字符会保持原状,关于这点下个题也会体现),并且不能传入fl0g变量,也就是不能?fl0g=xxx。

        之后会过一个匹配,不能有这些东西,后面字符串和数字比较时,参照字符串和数字的弱等于,会先intval(),再进行比较,只要我们传入字符串,那麽就是0,肯定能过这个,所以不用太在意。

        扩展:在弱等于比较时,若两个字符串都是数字字符串(数字的字符串,科学计数法),就会先将他们转化成数字再比较(和本题无关,后面的题会用到,这里先讲一下),如下图,答案为true。

        回到题目,我们可以尝试一下?fun=phpinfo(),结果没有回显,按理来说是可以过判断的,说明很可能被禁用了。如果我们不利于这里的eval,下面的if语句只要$fl0g等于这个字符串,那麽一样可以拿到flag。但是这里都没有定义$fl0g,我们怎么想办法传入它呢?这里需要用到extract()函数,它的参数是一个数组,它能将里面所有的键变成变量,键对应的值变成这个变量的值。那麽,我们构造payload:post一个fl0g=flag_give_me,这样fl0g就变成了$fl0g,并且值也成为了这个字符串,即可拿到flag。

        这个题还有个非预期解法,题目过滤了很多函数,但是没有过滤echo函数,

        发现有回显,这里我们可以利用echo和其它函数做点什么,我们发现这里已经包含了flag.php,那麽$flag肯定存在,可以考虑试试get_defined_vars函数,(以此函数返回多维数组。包含调用 get_defined_vars() 作用域内所有已定义的变量、环境变量、服务器变量、用户定义变量列表)。返回值是一个数组,只能print_r来看,但是这个函数也被禁用,echo的话只能返回Array,不能看到里面的变量。这时,还有一个把数组转化成字符串的函数,implode()函数是将数组元素组合成字符串的最简单方法。它接受两个参数,第一个参数是用于分隔数组元素的字符串,第二个参数是要转换为字符串的数组,我echo一个字符串总可以了吧,我们试一试,发现可以。

        第三题:

$_SERVER['QUERY_STRING']就是url中?后面的部分,可以理解我们get传的参数名,这里传入的url不能有这一堆东西,但是要让变量ctf_show为这个字符串,这里我们不能传入下划线,因为被过滤了,[也不行,只有空格了,这三个传进去会变成下划线,所以payload:

        第四题:

        这个题的考点是is_numeric的一些绕过和弱比较。

        首先我们要过if语句,num要是字符型数字,或者是数字,这时我们传入?num=36,自然可以过第一个,但是第二个不能过。注意,这里是!==,而不是!=,前者相当于===的不等于,也就是强不等于,所以我们想办法把36加点什么,可以过is_numeric同时过第二个,经过查阅:在数字面前加%0c(换页符好像是),%09(tab),%20(空格),%0b(垂直制表符),%0a(换行),%0d(回车),经过is_numeric后为true,加在后面则不可以。后面trim会过滤$num左右的一些字符,除了上方的%0c,全部过滤。所以我们只需要输入%0c36就可以过全部条件。

        接下来还有一个if语句,这里是弱比较,我们加入了%0c后,php依旧认为这是一个数字型字符串,所以它和36比时会先转换成数字,这里%0c36也被转成了36(上图所有的符号加数字都会认为是数字),本地上测试一下:

但是别的符号就不行了,比如%0e,

        所以该题的payload:%0c36

第五题:

ereg,传入的c要行首,行尾都是字母,这里我们试试a1b,中间夹个字母试试,

error了,经过尝试,只能是纯字母才可以。strrev函数则是反转字符串,然后intval之后要等于0x36d,这里0x36d没有引号,所以php会计算出来是877,这里问题来了,c不能有任何数字,现在反转后还要是877,这不是矛盾吗。这里,我们可以尝试%00截断:

第六题:

        call_user_func也是我们制造漏洞的好手了,它是传入函数的名字来调用函数,第一个参数传函数的名字,第二个传变量。这里明显是利用它来形成漏洞。但是,我们传入的f1也就是函数名字不能有字母数字,这就比较无语了。看了wp,php里有个函数叫_(),这函数确实很适合出题哈~

它是gettext()函数的别名,也就它特殊,还有别名,这个函数要确定 PHP 已安装且已启用gettext拓展(现在机器基本都已安装且启用)。可以翻译字符串,和echo差不多。所以我们构造payload:

?f1=_&f2=get_defined_vars

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值