用户
搜索
  • TA的每日心情
    开心
    2016-10-30 16:15
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋-见习白帽

    Rank: 3Rank: 3

    23

    主题

    38

    帖子

    254

    魔法币
    收听
    0
    粉丝
    2
    注册时间
    2016-6-6
    发表于 2017-8-30 10:28:33 498105
    0x00 背景
    看了之前Gr36_前辈在先知上的议题,其中有提到排序注入,这个在最近经常遇到这样的问题,所以先总结下order by 排序注入的知识。

    0x01 环境信息
    测试环境:操作系统ubuntu0.14.04.1 MYSQL:5.5.55-0
    测试代码:
    [PHP] 纯文本查看 复制代码
    <?php
    $mysql_server="10.10.10.136";
    $mysql_username="root";
    $mysql_userpass="xxxxx";
    $mysql_select_db="test";
    $config=mysql_connect($mysql_server,$mysql_username,$mysql_userpass)or die (mysql_error());
    $db=mysql_select_db($mysql_select_db)or die (mysql_error());
    if( isset( $_REQUEST[ 'evil' ]) ) {
    $evil = $_REQUEST[ 'evil' ];
    $query  = "select * from test order by user_id $evil;";
    //$query  = "(select * from test order by user_id $evil);";
    $result = mysql_query( $query,$config) or die( $query.'<pre>' . mysql_error() . '</pre>');
    
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
    $user_id = mysql_result( $result, $i, "user_id" );
    $user = mysql_result( $result, $i, "user" );
    $password  = mysql_result( $result, $i, "password" );
    $html .= "<pre>user_id: {$user_id} user: {$user} password: {$password}</pre>";
    $i++;
    }
    mysql_close();
    echo $query;
    echo $html;
    }
    ?>


    0x02 注入方法介绍
    正常页面:


    页面.png


    1.order by 与 报错注入:

    当页面会展示出MYSQL的错误信息时,可以使用报错注入。

    ?evil=and(updatexml(1,concat(0x7e,(select user())),0))


    报错.png


    2.order by 与 盲注:

    当页面并没有展示MYSQL的错误信息时,且只能根据页面的回显数据的状态进行判断时,可使用布尔盲注。

    《当然雨师傅也提到了可以使用时间盲注 select * from test order by user_id,(select 1 from (select sleep(3))a)》


    这里使用位运算符的^(位异或),当然MySQL还有|(位或),&(位与),~(位取反),>>(位右移),<<(位左移)操作符号,位符号感觉有很多妙用目前还没想好:-)。

    ^(位异或会将前后的数字转换成2进制然后进行异或。


    因为正则进行匹配时,匹配到数据返回1(00000001)的时候,此时返回的1会和user_id中的数据的二进制进行异或,然后按照异或的结果升序排列,所以显示的排列会发生变化。

    当正则进行匹配时,未匹配到数据返回0(00000000)的时候,任意数字和0异或的结果还是本身,所以user_id中的数据和0进行异或后排序是不变的。

    因此,当页面排序紊乱时候则说明正则匹配到正确数据,页面排序未发生紊乱时则说明正则没有匹配到数据。



    通过排列顺序的变化来判断返回的结果是否正确,这里的MYSQL版本是:5.5.55-0, 所以使用如下语句可以匹配到数据,因此排序发生变化了,这里'^5'也可以转换成^5的16进制,这样语句中就没了引号。


    ?evil=^(select (select version()) regexp '^5'), 正则返回结果为1,然后与user_id后面的值进行异或,得到如下结果。


      
    排序前
      




    排序后



    user_id
    user_id的二进制
    正则(1)二进制
    user_id^1

    user_id
    user_id的二进制
    正则(1)二进制
    user_id^1
    1
    00000001
    00000001
    00000000

    1
    00000001
    00000001
    00000000
    2
    00000010
    00000001
    00000011

    3
    00000011
    00000001
    00000010
    3
    00000011
    00000001
    00000010

    2
    00000010
    00000001
    00000011
    4
    00000100
    00000001
    00000101

    5
    00000101
    00000001
    00000100
    5
    00000101
    00000001
    00000100

    4
    00000100
    00000001
    00000101
    6
    00000110
    00000001
    00000111

    7
    00000111
    00000001
    00000110
    7
    00000111
    00000001
    00000110

    6
    00000110
    00000001
    00000111


    因为order by 默认是升序排列的,所以页面显示的是如下的效果:

    333.png

    ?evil=^(select (select version()) regexp '^aaaaaa') 未能匹配到数据,因此返回0。
    当正则未匹配到数据时候返回的结果是0, 0和任意数字异或的结果都是数字本身,所以排序是不变的。

      
    user_id
      
    user_id的二进制
    正则(0)二进制
    user_id^0
    1
    00000001
    00000000
    00000001
    2
    00000010
    00000000
    00000010
    3
    00000011
    00000000
    00000011
    4
    00000100
    00000000
    00000100
    5
    00000101
    00000000
    00000101
    6
    00000110
    00000000
    00000110
    7
    00000111
    00000000
    00000111


    666.png


    3.order by 与union 查询:

    当$query  = "select * from test order by user_id $evil;";没有使用括号包裹的时候,是无法直接使用union查询的。


    sql.png


    当 $query  = "(select * from test order by user_id $evil);";使用括号进行包裹的时候,此时是可以进行union查询的。

    这个在MySQL的官方文档上也有进行说明<来自 MySQL 5.5参考手册>,文档中说道并把ORDER BY或LIMIT放到最后一个的后面,

    经过测试MYSQL:5.5.55-0放在前面也是可以执行的。当然这种情况不大常见。


    777.png


    2222.png


    0x03 小小的总结

    由于采用预编译执行SQL语句时传入的参数不能作为SQL语句,所以像order by xxx desc这里的排序规则还是只能用拼接,

    因此order by后的注入或许能够成为后续漏洞挖掘重点关注的SQL注入点。


    640.webp.jpg

    表哥  学会上述知识 需要看什么书
    使用道具 举报 回复
    发表于 2017-9-21 14:49:55
    使用道具 举报 回复
    求解你的数据库的表是怎么构建的 里面的数据可共享下吗?
    使用道具 举报 回复
    发表于 2017-9-22 17:11:23
    意思是说预编译无法防御这种SQL注入攻击?
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册