• SQL注入之order by注入与limit注入


    order by注入

    什么是order by

    在MySQL支持使用ORDER BY语句对查询结果集进行排序处理,使用ORDER BY语句不仅支持对单列数据的排序,还支持对数据表中多列数据的排序。语法格式如下

    select * from 表名 order by 列名(或者数字) asc;升序(默认升序) 
    select * from 表名 order by 列名(或者数字) desc;降序
    
    • 1
    • 2

    假设有以下用户表
    在这里插入图片描述
    当我们使用命令 select * from users order by username asc;的时候,是将users这张表按照username这一列进行升序,结果就变成了;可以看到username那一列是按照字母从小到大的方式进行排序。
    在这里插入图片描述
    将asc修改desc后,它就会按username降序打印。
    在这里插入图片描述
    mysql中order by还支持多个字段自定义排序,通过逗号隔开,但只能在数字之间进行自定义排序,若选择字符类型则会根据第一个列名的排序规则进行排序。
    语法格式如下

    select * from 表名 order by 列名(或者数字) asc;升序(默认升序) ,列名(或者数字) desc;降序(默认升序)
    
    • 1

    在这里插入图片描述

    而order by注入就是通过可控制的位置在order by子句后,如下order参数可控:
    select * from goods order by $_GET['order']

    判断注入类型

    数字型order by注入时,语句order by=2 and 1=2,和order by=2 and 1=1 显示的结果一样,所以无法用来判断注入点类型

    而用rand()会显示不同的排序结果

    当在字符型中用?sort=rand(),则不会有效果,排序不会改变

    因此用rand()可判断注入点类型

    注入方式

    1.和union查询一块使用

    前面经常利用order by子句进行快速猜解表中的列数

    测试时,测试者可以通过修改order参数值,比如调整为较大的整型数,再依据回显情况来判断具体表中包含的列数。

    再配合使用union select语句进行回显。

    2.基于if语句盲注(数字型)

    下面的语句只有order=$id,数字型注入时才能生效,

    order ='$id'导致if语句变成字符串,功能失效

    如下图为演示

    字符串型时if()失效,排列顺序不改变
    在这里插入图片描述
    数字型时排列顺序改变
    在这里插入图片描述
    知道列名情况下
    if语句返回的是字符类型,不是整型, 因此如果使用数字代替列名是不行的,如下图语句没有根据password排序。
    在这里插入图片描述
    这是在知道列名的前提下使用

    ?order=if(表达式,id,username)
    
    • 1
    • 表达式为true时,根据id排序
    • 表达式为false是,根据username排序

    不知道列名的情况
    id总知道吧

    ?order=if(表达式,1,(select id from information_schema.tables))
    
    • 1
    • 如果表达式为true时,则会返回正常的页面
    • 如果表达式为false,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空

    在这里插入图片描述

    3.基于时间的盲注

    order by if(表达式,1sleep(1))
    
    • 1
    • 表达式为true时,正常时间显示
    • 表达式为false时,会延迟一段时间显示

    延迟的时间并不是sleep(1)中的1秒,而是大于1秒。 它与所查询的数据的条数是成倍数关系的。
    在这里插入图片描述

    计算公式:延迟时间=sleep(1)的秒数*所查询数据条数

    如果查询的数据很多时,延迟的时间就会特别长

    在写脚本时,可以添加timeout这一参数来避免延迟时间过长这一情况。

    4.基于rand()的盲注(数字型)

    rand() 函数可以产生随机数介于0和1之间的一个数

    当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数,

    种子固定,则生成的数固定

    order by rand:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同

    order by rand(表达式)
    
    • 1

    当表达式true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。
    例:

    order by rand(ascii(mid((select database()),1,1))>96)
    
    • 1

    5.报错注入

    order by updatexml(1,if(1=2,1,(表达式)),1)
    order by extractvalue(1,if(1=2,1,(表达式)));
    
    • 1
    • 2

    因为1=2,所以执行表达式内容

    例如order by updatexml(1,if(1=2,1,concat(0x7e,database(),0x7e)),1)获取数据库名
    在这里插入图片描述

    若改成1=1,则页面正常显示
    在这里插入图片描述

    limit注入

    什么是limit

    在mysql中limit ,主要用于提取前几条或者中间某几行数据。
    使用语法:

    select * from table limit m,n
    其中m是指记录开始的index,从0开始,表示第一条记录
    n是指从第m+1条开始,取n条。
    select * from tablename limit 2,4
    即取出第3条至第6条,4条记录
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    limit注入:注入点出现在limit后面的即可称为limit注入。

    注入方式

    procedure analyse()报错注入

    此方法适用于<=MySQL 5.5中,在limit语句后面的注入
    在mysql语法中limit后面只能跟PROCEDUREINTO OUTFILEFOR UPDATE | LOCK IN SHARE MODE三个函数。

    现今的5.7版本后limit 关键字后面就不能和union联合查询一起使用了,但是还可跟PROCEDURE和 INTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,这里就只演示使用procedure analyse()函数来实现错误注入,这个函数下有ANALYSE支持两个参数,首先尝试一下默认两个参数

    select * from users order by id limit 0,1 procedure analyse(1,1);
    
    • 1

    在这里插入图片描述

    #limit结合procedure analyse()报错注入
    select * from users order by id limit 0,1 procedure analyse(extractvalue(1,concat(version())));
    
    • 1
    • 2

    特别注意:在5.7.26中我执行时会报错原因是官方在mysql5.7.18版本起就将它弃用了,所以我这里无法执行
    在这里插入图片描述

  • 相关阅读:
    20 _ 散列表(下):为什么散列表和链表经常会一起使用?
    MongoDB索引覆盖查询
    请问签过版权转让 协议后,接下来是不是要在 author gateway 等待?
    JDK对String操作优化
    Aroid问题笔记 - ViewPager嵌套RecyclerView,降低ViewPager灵敏度
    函数:计算数组的元素和
    [重庆思庄每日技术分享]-ORA-16525 dg broker不可用
    shell小练习
    grpc和thrift的概念及区别
    【Django】 rest_framework接口开发流程及接口功能组成
  • 原文地址:https://blog.csdn.net/m0_46467017/article/details/126242055