應用安全系列之一 SQL注入

2021-10-19 22:33:39 字數 3809 閱讀 1235

本系列文章主旨在於介紹一些漏洞型別產生的基本原理,探索最基礎的解決問題的措施,不排除有些語言或者系統提供的安全的api可以更好地更直接地解決問題,也不排除可以嚴格地輸入驗證來解決。

根據it研究與顧問諮詢公司gartner統計資料顯示,75%的黑客攻擊發生在應用層。而由nist的統計顯示92%的漏洞屬於應用層而非網路層,52%的**應用程式都存在sql注入、xss跨站指令碼和輸入驗證問題。注入攻擊產生的後果比較嚴重,輕則導致資料洩露,嚴重的會導致資料被篡改,根偉嚴重的可能會導致dos攻擊或者主機被接管。由於注入攻擊容易被利用而且導致的後果是非嚴重,因此,注入攻擊已經連續多次排在owasp top 10的第一名,在cwe的排名這種,也一直名列前茅。

owasp top 10對注入攻擊的定義:注入攻擊漏洞,例如sql,os以及ldap注入。這些攻擊發生在當不可信的資料作為命 令或者查詢語句的一部分,被傳送給直譯器的時候。攻擊者傳送的惡意資料可以欺騙直譯器,以執行計畫外的命令或者在未被恰當授權時訪問資料。首先需要確認一下,sql注入產生的原因:第

一、輸入的引數可以被攻擊者控制,第二,輸入的引數被作為sql語句的一部分用來組裝sql語句,此兩種條件缺一不可。

根據sql的作用,我把sql注入攻擊分成兩種型別,第一種是資料操作注入攻擊, 第二種型別是查詢注入攻擊;。之所以分成這兩種,主要還是從產生的原因和預防措施的不同來分別講解。

第一種,資料操作注入攻擊

資料操作攻擊主要是就是進行增(insert)刪(delete)改(update)操作時導致的注入攻擊。在進行資料操作時,例如修改,乙個典型的修改語句如下:  

update product set price=9.0 where productid='1'
這裡的productid和price的值都是從客戶端發過來的,攻擊者可以通過各種攔截或者**工具攔截對值進行修改。如果將prodcutid的值修改為:1『 or '1'='1 ,再將price的值改為1.0,sql語句就會變為如下:

update product set price=1.0 where productid='1' or '1'='1'
這樣就可以把所有的產品的**修改,而且修改為更便宜的產品。

之所以,資料操作注入攻擊單獨列出來,是因為它會很容易地篡改資料。不過,預防的方法也比較簡單。 由於增刪改資料時,一般不會使用特別複雜的條件語句,一般也不會使用模糊的條件語句,所以預防就很簡單,只要把標示字串的開始和結束的字元單引號(')轉義即可。不過,不同型別的資料,轉義的方法會不一樣。下面**列出幾種常用的資料庫和轉義方法:

攻擊型別

危險字元

編碼方法

例子

資料庫型別

sql注入

『新增乙個單引號轉義

例如:' -> ''

oracle

' \ 

新增乙個\轉義

例如:『 -> \'

mysql

'新增乙個單引號轉義

例如:' -> ''

sql server

經過轉義處理過的值,再組裝sql語句,就可以保證sql語句的安全性了。 對於一些資料庫,如:oracle和mysql,可以通過escape語句定義轉義的字元,則需要使用escape語句中的字元進行轉義,一般不建議這麼用。

第二種,查詢注入攻擊

顧名思義,查詢攻擊就是輸入的引數作為查詢sql語句的一部分用於查詢資料。最經典的查詢操作的例子,是根據輸入的條件查詢符合條件的記錄,例如,在產品列表頁面根據輸入的產品名稱查詢所有符合產品,可能的sql語句如下:

精確查詢

select * from product where name = '輸入的值'
關於精確查詢,注入和典型的注入類似,需要注入攻擊向量:name' or '1'='1, 就可以查詢到所有產品,也可以通過注入額外的sql語句進行額外的破壞,不過這樣做需要花更多的功夫和時間,即使有了sqlmap這樣的工具。

不過,這種精確查詢的預防原理和資料操作注入攻擊的原理很像,只要將單引號(')進行轉義處理就可以了。

模糊查詢

select * from product where name like '輸入的值+%'
模糊查詢和精確查詢不同的地方就是,除了要處理單引號(')這個特殊字元之外,模糊查詢有額外的特殊的字元,例如: 

字元

描述

%表示零個或多個字元的任意字串,例如:like 'aa%',可以匹配aa以及aa開頭的字串。 

_表示任何單個字元,例如:like'_aa',只匹配包含aa工三個字元字串,例如:aaa,1aa。 oracle也可以使用?表示任何單個字元。

[ ]表示指定範圍,例如: ([a-z]) 是指所有小寫字母,或者 集合 [abc])中的任何單個字元,結合like使用 like '[hh]ello [ww]orld' 

*表示零個或者多個字元,和%的區別是,當需要兩端都匹配時,要用%而不能用*,例如:like '%aaaa%',而不能使用'*aaaa*' ,一般都用於查詢內容而又不列出具體字段,例如:select * from product。

#表示單個數字,例如:like 『a#b』 匹配  'a1b'.

{}有的資料庫使用的是大括號,作用同

針對這些特殊的字元的處理和單引號的處理是不同的,處理的主要方式使用一對括號將特殊字元括起來,例如:查詢的字串中含有%,假設查詢字串是a%b,就可以使用a[%]b,這樣查詢的內容就會含有'a%b' 而不是a開頭和b結尾的所有串。不同的資料庫使用不同的括號,統計如下表:

攻擊型別

危險字元

編碼方法

例子

資料庫型別

sql注入

# % _ [ ]

使用中括號轉義

例如:% -> [%]

mysql

# % _

使用大括號{}轉義

例如:% ->

oracle

# % _ [ ]

使用中括號轉義

例如:% -> [%]

sql server

最後,還有一種sql注入的地方是排序時 group by的字段的排序,一般這裡都比較好處理,因為排序的字段都是資料庫表的字段,都有固定的值的範圍,通過輸入驗證是比較好的方法。當然,如果客戶端傳的不是字串,而是,通過數字對應某個字段,例如:1->name,2->address等,就更容易做輸入驗證了,只要驗證是否是數字或者數字list即可,然後,再對映成具體的字段。關於公升序還是降序,那就就只有asc或者desc,無論怎麼處理都比較方便。

總之,無論何時何地,想要把內容作為sql的一部分,都不必須小心。即使在使用框架的時候,例如:mybatis或者ibatis,有些情況下(使用$帶入變數而不是使用#時),把輸入的內容作為sql的一部分也還是會有sql注入。 

綜上所述,可以了解sql注入之所以發生的根本原理和最基本的預防原理。 當然,預防的方法有多種,使用編譯的sql、輸入驗證等,這些預防方法都有一定的缺陷不一定適用所有的情況。 如果掌握了sql注入的最基本的原理,了解預防發生的基本原理,就可以使用這一招處理所有的sql注入的情況。

參考:

應用安全系列之十七 xQuery注入

本系列文章主旨在於介紹一些漏洞型別產生的基本原理,探索最基礎的解決問題的措施。關於xquery標準的詳細資訊可以參考 這裡只做簡單介紹。xquery語言是用於查詢儲存在xml資料庫的資料的語言,它可以看做是xpath語言的乙個超集。主要用到的xquery的功能包括 還是用員工資訊的例子,employ...

Flash應用安全系列 5

qq郵箱對於跨域請求過濾不嚴,可能導致使用者郵件被持久劫持 我們知道,在瀏覽器的安全模型中,同源策略 sop same origin policy 是最為基礎的一環,它決定了web上的哪些資源是可以被指令碼訪問的,哪些資源則是被拒絕的。撇開html5中的 access control allow o...

網路安全系列之四 手工SQL注入 ASP

1 尋找注入點 隨便開啟乙個網頁,注意觀察url。注入點必定是類似 這類存在命令呼叫的頁面,shownews.asp?id 7 是頁面傳值,就是將 id 7 傳到 shownews.asp 頁面裡進行處理。我們可以在這個url後面加上and 1 1和and 1 2進行測試。and 1 1 網頁仍能正...