【正文】
第五章 腳本攻擊與防御 1 SQL注入技術(shù) ?什么是 SQL注入技術(shù)? SQL注入即是指攻擊者通過(guò)在應(yīng)用程序中預(yù)先定義好的查詢(xún)語(yǔ)句結(jié)尾加上額外的SQL語(yǔ)句元素,欺騙數(shù)據(jù)庫(kù)服務(wù)器執(zhí)行非授權(quán)的任意查詢(xún)。 ?分析一個(gè)經(jīng)典的 SQL注入漏洞 dim rs admin1=request(admin) password1=request(password) set rs=() select * from admin where admin=39。 amp。 admin1 amp。 39。 and password=39。amp。 password1 amp。39。,conn,1 if and then SCRIPT language=JavaScriptalert(39。用戶(hù)名或密碼不正確! 39。)。 javascript:(1)/SCRIPT else session(admin)=rs(admin) session(password)=rs(password) session(aleave)=rs(aleave) end if set rs=nothing 一個(gè)經(jīng)典的 SQL注入漏洞 分析 ?在用戶(hù)名和密碼那里都填入 ‘ OR? ?=? , ? SQL語(yǔ)句被構(gòu)造成 select * from admin where admin=? 39。OR? 39。=? 39。 and password=? 39。OR? 39。=? ? ?意思是當(dāng) admin為空或者空等于空 ,password為空或者空等于空 的時(shí)候整個(gè)查詢(xún)語(yǔ)句就為真。 如何來(lái)修補(bǔ)漏洞? ?過(guò)濾掉其中的特殊字符。 ?這里我們就過(guò)濾掉其中的單引號(hào)“ 39?!?,即是把程序的頭兩行改為: admin1=replace(trim(request(admin)),39。,) password1=replace(trim(request(password)),39。,) 判斷數(shù)據(jù)庫(kù)的類(lèi)型 ?服務(wù)器的 IIS錯(cuò)誤提示沒(méi)關(guān)閉 提交 : 如果是 Access數(shù)據(jù)庫(kù),那么應(yīng)該返回: Microsoft JET Database Engine 錯(cuò)誤 39。80040e1439。 字符串的語(yǔ)法錯(cuò)誤 在查詢(xún)表達(dá)式 39。 id=37 39。 39。 中。 / ,行 8 Eg: 如果是 SQLServer數(shù)據(jù)庫(kù),那么應(yīng)該返回: Microsoft OLE DB Provider for ODBC Drivers 錯(cuò)誤 39。80040e1439。 [Microsoft][ODBC SQL Server Driver][SQL Server]字符串 39。39。 之前有未閉合的引號(hào)。 / ,行 8 ?服務(wù)器的 IIS錯(cuò)誤提示關(guān)閉了 根據(jù) Access和 SQLServer自己的系統(tǒng)表來(lái)區(qū)分。Access是在系統(tǒng)表 [msysobjects]中,但在 Web環(huán)境下讀該表會(huì)提示“沒(méi)有權(quán)限”, SQLServer是在表 [sysobjects]中,在 Web環(huán)境下可正常讀取。 提交: and (select count(*) from sysobjects)0 ?如果是 Access數(shù)據(jù)庫(kù),因?yàn)椴淮嬖?sysobjects表,所以返回結(jié)果應(yīng)該和正常頁(yè)面有很大區(qū)別; ?如果是 SQLServer,則應(yīng)該返回一個(gè)查詢(xún)成功的正常頁(yè)面。 Access數(shù)據(jù)庫(kù)的注入 ?把 IE菜單 =工具 =Inter選項(xiàng) =高級(jí) =顯示友好 HTTP 錯(cuò)誤信息前面的勾去掉,這樣可以顯示出現(xiàn)的錯(cuò)誤信息。 ?分析一次完整的 SQL注入。 % owen=request(id) Set rsnews=() sql=update news set hits=hits+1 where id=amp。cstr(request(id)) sql sql=select * from news where id=amp。owen sql,conn,1,1 title=rsnews(title) if and then (數(shù)據(jù)庫(kù)出錯(cuò) ) else % ? ? and 1=2 sql=select * from news where id=37 and 1=2 ? and 1=1 ? and 0(select count(*) from admin) 猜測(cè)是否存在 admin表 ? and 1=(select count(*) from admin where len(pass)0) 猜測(cè)是否存在 pass字段 ? and 1=(select count(*) from admin where len(password)0) ? and (select asc(mid(password,1,1)) from admin)100 假設(shè) pssword字段中第一個(gè)記錄的第一位的 ASCII碼大于 100,如果假設(shè)正確則應(yīng)該返回正常頁(yè)面 猜測(cè) password字段是否存在 防止 SQL注入 (1) 在服務(wù)端正式處理之前對(duì)提交數(shù)據(jù)的合法性進(jìn)行檢查; (2) 封裝客戶(hù)端提交信息; (3) 替換或刪除敏感字符 /字符串; (4) 屏蔽出錯(cuò)信息。 第一種方法 Dim Tc_Post,Tc_Get,Tc_In,Tc_Inf,Tc_Xh 39。定義需要過(guò)濾的字串 Tc_In=39。|。|and|(|)|exec|insert|select|delete|update|count|*|%|chr|mid|master|or|char|declare Tc_Inf = split(Tc_In,|) 39。處理 post數(shù)據(jù) If Then For Each Tc_Post In For Tc_Xh=0 To Ubound(Tc_Inf) If Instr(LCase((T