-
當(dāng)前位置:首頁(yè) > 創(chuàng)意學(xué)院 > 技術(shù) > 專題列表 > 正文
如何sql注入(如何sql注入攻擊)
大家好!今天讓創(chuàng)意嶺的小編來(lái)大家介紹下關(guān)于如何sql注入的問(wèn)題,以下是小編對(duì)此問(wèn)題的歸納整理,讓我們一起來(lái)看看吧。
開(kāi)始之前先推薦一個(gè)非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計(jì)劃、工作報(bào)告、論文、代碼、作文、做題和對(duì)話答疑等等
只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準(zhǔn),寫出的就越詳細(xì),有微信小程序端、在線網(wǎng)頁(yè)版、PC客戶端
官網(wǎng):https://ai.de1919.com。
創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務(wù)客戶遍布全球各地,如需了解SEO相關(guān)業(yè)務(wù)請(qǐng)撥打電話175-8598-2043,或添加微信:1454722008
本文目錄:
一、什么是sql注入如何防止sql注入
SQL注入是一種非常常見(jiàn)的數(shù)據(jù)庫(kù)攻擊手段,同時(shí)也是網(wǎng)絡(luò)世界中最普遍的漏洞之一,簡(jiǎn)單理解就是惡意用戶通過(guò)在表單中填寫包含SQL關(guān)鍵字的數(shù)據(jù)來(lái)使數(shù)據(jù)庫(kù)執(zhí)行非常規(guī)代碼的過(guò)程。
問(wèn)題來(lái)源是,SQL數(shù)據(jù)庫(kù)的操作是通過(guò)SQL語(yǔ)句來(lái)執(zhí)行的,而無(wú)論是執(zhí)行代碼還是數(shù)據(jù)項(xiàng)都必須寫在SQL語(yǔ)句中,也就導(dǎo)致如果我們?cè)跀?shù)據(jù)項(xiàng)中加入了某些SQL語(yǔ)句關(guān)鍵字,比如SELECT、DROP等,這些關(guān)鍵字就很有可能在數(shù)據(jù)庫(kù)寫入或讀取數(shù)據(jù)時(shí)得到執(zhí)行。
解決方案
方案一:
采用預(yù)編譯技術(shù)
使用預(yù)編譯的SQL語(yǔ)句,SQL語(yǔ)句的語(yǔ)義不會(huì)是不會(huì)發(fā)生改變的。預(yù)編譯語(yǔ)句在創(chuàng)建的時(shí)候就已經(jīng)將指定的SQL語(yǔ)句發(fā)送給了DBMS,完成了解析,檢查,編譯等工作,所以攻擊者無(wú)法改變SQL語(yǔ)句的結(jié)構(gòu),只是把值賦給?,然后將?這個(gè)變量傳給SQL語(yǔ)句。當(dāng)然還有一些通過(guò)預(yù)編譯繞過(guò)某些安全防護(hù)的操作,大家感興趣可以去搜索一下。
方案二:
嚴(yán)格控制數(shù)據(jù)類型
在java、c等強(qiáng)類型語(yǔ)言中一般是不存在數(shù)字型注入的,因?yàn)樵诮邮艿接脩糨斎雐d時(shí),代碼一般會(huì)做一個(gè)int id 的數(shù)據(jù)類型轉(zhuǎn)換,假如我們輸入的是字符串的話,那么這種情況下,程序就會(huì)報(bào)錯(cuò)。但是在PHP、ASP這些沒(méi)有強(qiáng)調(diào)處理數(shù)據(jù)類型的語(yǔ)言,一般我們看到的接收id的代碼都是如下等代碼。
方案三:
對(duì)特殊的字符進(jìn)行轉(zhuǎn)義
數(shù)字型注入可以通過(guò)檢查數(shù)據(jù)類型防止,但是字符型不可以,那么怎么辦呢,最好的辦法就是對(duì)特殊的字符進(jìn)行轉(zhuǎn)義了。比如在MySQL中我們可以對(duì)" '
"進(jìn)行轉(zhuǎn)義,這樣就防止了一些惡意攻擊者來(lái)閉合語(yǔ)句。當(dāng)然我們也可以通過(guò)一些安全函數(shù)來(lái)轉(zhuǎn)義特殊字符。如addslashes()等,但是這些函數(shù)并非一勞永逸,攻擊者還可以通過(guò)一些特殊的方式繞過(guò)。
二、如何防范SQL注入漏洞及檢測(cè)
以下是OMG我為大家收集整理的文章,希望對(duì)大家有所幫助。
SQL注入(SQLInjection)漏洞攻擊是目前網(wǎng)上最流行最熱門的黑客腳本攻擊方法之一,那什么是SQL注入漏洞攻擊呢?它是指黑客利用一些Web應(yīng)用程序(如:網(wǎng)站、論壇、留言本、文章發(fā)布系統(tǒng)等)中某些存在不安全代碼或SQL語(yǔ)句不縝密的頁(yè)面,精心構(gòu)造SQL語(yǔ)句,把非法的SQL語(yǔ)句指令轉(zhuǎn)譯到系統(tǒng)實(shí)際SQL語(yǔ)句中并執(zhí)行它,以獲取用戶名、口令等敏感信息,從而達(dá)到控制主機(jī)服務(wù)器的攻擊方法。
1. SQL注入漏洞攻擊原理
1. 1 SQL注入漏洞攻擊實(shí)現(xiàn)原理
SQL(Structured Query Language)是一種用來(lái)和數(shù)據(jù)庫(kù)交互的語(yǔ)言文本。SQL注入的攻擊原理就是攻擊者通過(guò)Web應(yīng)用程序利用SQL語(yǔ)句或字符串將非法的數(shù)據(jù)插入到服務(wù)器端數(shù)據(jù)庫(kù)中,獲取數(shù)據(jù)庫(kù)的管理用戶權(quán)限,然后將數(shù)據(jù)庫(kù)管理用戶權(quán)限提升至操作系統(tǒng)管理用戶權(quán)限,控制服務(wù)器操作系統(tǒng),獲取重要信息及機(jī)密文件。
SQL注入漏洞攻擊主要是通過(guò)借助于HDSI、NBSI和Domain等SQL注入漏洞掃描工具掃描出Web頁(yè)面中存在的SQL注入漏洞,從而定位SQL注入點(diǎn),通過(guò)執(zhí)行非法的SQL語(yǔ)句或字符串達(dá)到入侵者想要的操作。下面以一段身份驗(yàn)證的.NET代碼為例,說(shuō)明一下SQL 注入攻擊的實(shí)現(xiàn)方法。
SqlConnectionnwConn = new SqlConnection((string)ConfigurationSettings.AppSettings["DBconnStrings"]); string queryStr = "SELECT userid,userpwd, username,type FROM users where userid='" + Txtusername.Text +"'";
DataSet userSet = new DataSet();
SqlDataAdapter userAdapter = newSqlDataAdapter(queryStr, nwConn);
userAdapter.Fill(userSet, "Users");
Session["UserID"] =Txtusername.Text.ToString();
Session["type"] =type.Text.ToString();
Response.Redirect("/Myweb/admin/login.aspx");
從上面的代碼中可以看出,程序在與數(shù)據(jù)庫(kù)建立連接得到用戶數(shù)據(jù)之后,直接將username的值通過(guò)session傳給login.aspx,沒(méi)有進(jìn)行任何的過(guò)濾和處理措施, 直接用來(lái)構(gòu)造SQL 語(yǔ)句, 其危險(xiǎn)系數(shù)是非常高的, 攻擊者只要根據(jù)SQL 語(yǔ)句的編寫規(guī)則就可以繞過(guò)身份驗(yàn)證,從而達(dá)到入侵的目的。
1. 2 SQL注入漏洞攻擊分析
SQL注入可以說(shuō)是一種漏洞,也可以說(shuō)是一種攻擊。當(dāng)程序中的變量處理不當(dāng),沒(méi)有對(duì)用戶提交的數(shù)據(jù)類型進(jìn)行校驗(yàn),編寫不安全的代碼,構(gòu)造非法的SQL語(yǔ)句或字符串,都可能產(chǎn)生這個(gè)漏洞。
例如Web系統(tǒng)有一個(gè)login頁(yè)面,這個(gè)login頁(yè)面控制著用戶是否有權(quán)訪問(wèn),要求用戶輸入一個(gè)用戶名和口令,連接數(shù)據(jù)庫(kù)的語(yǔ)句為:
“select * from users where username = 'username' andpassword = 'password'”
攻擊者輸入用戶名為aa or 1=1口令為1234 or 1=1之類的內(nèi)容。我們可以看出實(shí)際上攻擊者并不知道真正的用戶名、口令,該內(nèi)容提交給服務(wù)器之后,服務(wù)器執(zhí)行攻擊者構(gòu)造出的SQL命令,但由于攻擊者輸入的內(nèi)容非常特殊,所以最后得到的SQL命令變成:
“select * from users where username = 'aa' or 1=1 andpassword = '1234' or 1=1”
服務(wù)器執(zhí)行查詢或存儲(chǔ)過(guò)程,將用戶輸入的身份信息和數(shù)據(jù)庫(kù)users表中真實(shí)的身份信息進(jìn)行核對(duì),由于SQL命令實(shí)際上已被修改,存在永遠(yuǎn)成立的1=1條件,因此已經(jīng)不能真正驗(yàn)證用戶身份,所以系統(tǒng)會(huì)錯(cuò)誤地授權(quán)攻擊者訪問(wèn)。
SQL 注入是通過(guò)目標(biāo)服務(wù)器的80端口進(jìn)行的,是正常的Web訪問(wèn),防火墻不會(huì)對(duì)這種攻擊發(fā)出警告或攔截。當(dāng)Web服務(wù)器以普通用戶的身份訪問(wèn)數(shù)據(jù)庫(kù)時(shí),利用SQL注入漏洞就可能進(jìn)行創(chuàng)建、刪除、修改數(shù)據(jù)庫(kù)中所有數(shù)據(jù)的非法操作。而當(dāng)數(shù)據(jù)庫(kù)以管理用戶權(quán)限的身份進(jìn)行登錄時(shí),就可能控制整個(gè)數(shù)據(jù)庫(kù)服務(wù)器。
SQL注入的方法很多,在以手動(dòng)方式進(jìn)行攻擊時(shí)需要構(gòu)造各種各樣的SQL語(yǔ)句,所以一般攻擊者需要豐富的經(jīng)驗(yàn)和耐心,才能繞過(guò)檢測(cè)和處理,提交語(yǔ)句,從而獲得想要的有用信息。這個(gè)過(guò)程需要花費(fèi)很多的時(shí)間,如果以這種手動(dòng)方式進(jìn)行SQL注入漏洞攻擊,許多存在SQL注入漏洞的ASP、JSP、PHP、JAVA等網(wǎng)站就會(huì)安全很多了,不是漏洞不存在了,而是手動(dòng)入侵者需要編程基礎(chǔ),但現(xiàn)在攻擊者可以利用一些現(xiàn)成的黑客工具來(lái)輔助SQL注入漏洞攻擊,加快入侵的速度,使SQL注入變得輕而易舉。
由于SQL注入漏洞攻擊利用的是通用的SQL語(yǔ)法,使得這種攻擊具有廣泛性。理論上說(shuō),對(duì)于所有基于SQL語(yǔ)言的數(shù)據(jù)庫(kù)管理系統(tǒng)都是有效的,包括MSSQLServer、Oracle、DB2、Sybase和MySQL等。當(dāng)然,各種系統(tǒng)自身的SQL擴(kuò)展功能會(huì)有所不同,因此最終的攻擊代碼可能不盡相同。
1. 3 SQL注入漏洞攻擊過(guò)程
(1)繞過(guò)身份驗(yàn)證
如一個(gè)login界面,需要輸入用戶名和口令,然后Post到另一個(gè)頁(yè)面,進(jìn)行身份驗(yàn)證,因此攻擊者只需在用戶名和口令的輸入框中都輸入aa or’1’=’1’的內(nèi)容,那么攻擊者就可以通過(guò)欺騙的驗(yàn)證方式而直接進(jìn)入下一個(gè)頁(yè)面,并擁有和正常登錄用戶一樣的全部特權(quán)。原因是什么呢? 我們比較一下正常用戶登錄和攻擊者登錄時(shí)的兩種SQL語(yǔ)句:
1)正常用戶(如用戶名為admin,口令為1234567) :
SQL= " selectfrom users where username = ’admin’and password= ’1234567’ ";
2)攻擊者(用戶名和口令都為aa or’1’=’1’) :
SQL= " select * from users where username='aa or’1’=’1’'and password = ' aa or’1’=’1’'";
可以看到由and連接的兩個(gè)條件都被一個(gè)永遠(yuǎn)成立的1=1所代替,執(zhí)行的結(jié)果為true,數(shù)據(jù)庫(kù)會(huì)認(rèn)為條件恒成立,會(huì)返回一個(gè)true,讓攻擊者以合法身份登錄進(jìn)入下一個(gè)頁(yè)面。
(2)執(zhí)行非法操作
如一個(gè)查詢頁(yè)面select1.asp? id=1,編程人員原本設(shè)計(jì)意圖是顯示id為1的查詢信息,而攻擊者利用程序中沒(méi)有對(duì)id內(nèi)容進(jìn)行檢查的機(jī)制,插入自己的代碼。
從select1.asp中摘錄一段關(guān)鍵代碼:
SQL= " select *from photo where photoid= 'id'";
可以看到,id沒(méi)有進(jìn)行任何的處理,直接構(gòu)成SQL語(yǔ)句并執(zhí)行,而攻擊者在知道該系統(tǒng)數(shù)據(jù)庫(kù)中表名及字段名的情況下,利用SQL語(yǔ)句特性(分號(hào)是將兩句SQL 語(yǔ)句分開(kāi)的符號(hào)),直接向數(shù)據(jù)庫(kù)Tuser表中添加記錄:
select1.asp? id= 1;Insertinto Tuser (username,password,type) values ('hack','1234567','管理員'),然后攻擊者就可以直接用hack進(jìn)行登錄了。通過(guò)這樣的方法,攻擊者還可以對(duì)系統(tǒng)做任何的事情,包括添加、刪除、修改系統(tǒng)資源的操作。
(3)執(zhí)行系統(tǒng)命令
如果Web主機(jī)使用MSSQL數(shù)據(jù)庫(kù)管理系統(tǒng),那么攻擊者就可以用到xp_cmdshell這個(gè)擴(kuò)展存儲(chǔ)過(guò)程,xp_cmdshell是一個(gè)非常有用的擴(kuò)展存儲(chǔ)過(guò)程,用于執(zhí)行系統(tǒng)命令,比如dir、net等,攻擊者可以根據(jù)程序的不同,提交不同的語(yǔ)句:
execmaster.dbo.xp_cmdshell " dir "; exec master.dbo.xp_cmdshell" net user hack 1234567 /add ";
execmaster.dbo.xp_cmdshell " net localgroup administrators hack /add ";
這樣就可以向Web主機(jī)系統(tǒng)中成功添加了一個(gè)管理員帳戶。
2. SQL注入漏洞攻擊的檢測(cè)方式及方法
2. 1檢測(cè)方式
SQL注入漏洞攻擊檢測(cè)分為入侵前的檢測(cè)和入侵后的檢測(cè)。入侵前的檢測(cè),可以通過(guò)手工方式,也可以使用SQL注入漏洞掃描工具軟件。檢測(cè)的目的是為預(yù)防SQL注入漏洞攻擊,而對(duì)于SQL注入漏洞攻擊后的檢測(cè),主要是針對(duì)審計(jì)日志的查看,SQL注入漏洞攻擊成功后,會(huì)在Web Service和數(shù)據(jù)庫(kù)的審計(jì)日志中留下“痕跡”。
2. 2檢測(cè)方法
(1)動(dòng)態(tài)SQL檢查
動(dòng)態(tài)的SQL語(yǔ)句是一個(gè)進(jìn)行數(shù)據(jù)庫(kù)查詢的強(qiáng)大的工具,但把它和用戶輸入混合在一起就使SQL注入成為了可能。將動(dòng)態(tài)的SQL語(yǔ)句替換成預(yù)編譯的SQL或者存儲(chǔ)過(guò)程對(duì)大多數(shù)應(yīng)用程序是可行的。預(yù)編譯的SQL或者存儲(chǔ)過(guò)程可以將用戶的輸入作為參數(shù)而不是命令來(lái)執(zhí)行,這樣就限制了入侵者的行動(dòng)。當(dāng)然,它不適用于存儲(chǔ)過(guò)程中利用用戶輸入來(lái)生成SQL命令的情況。在這種情況下,用戶輸入的SQL命令仍可能得到執(zhí)行,數(shù)據(jù)庫(kù)仍然存在SQL注入漏洞攻擊的危險(xiǎn)。
(2)有效性校驗(yàn)
如果一個(gè)輸入框只可能包括數(shù)字,那么要通過(guò)驗(yàn)證確保用戶輸入的都是數(shù)字。如果可以接受字母,檢查是不是存在不可接受的字符,那就需要設(shè)置字符串檢查功能。確保應(yīng)用程序要檢查以下字符:分號(hào)、等號(hào)、破折號(hào)、括號(hào)以及SQL關(guān)鍵字。
(3)數(shù)據(jù)表檢查
使用SQL注入漏洞攻擊工具軟件進(jìn)行SQL注入漏洞攻擊后,都會(huì)在數(shù)據(jù)庫(kù)中生成一些臨時(shí)表。通過(guò)查看數(shù)據(jù)庫(kù)中最近新建的表的結(jié)構(gòu)和內(nèi)容,可以判斷是否曾經(jīng)發(fā)生過(guò)SQL注入漏洞攻擊。
(4)審計(jì)日志檢查
在Web服務(wù)器中如果啟用了審計(jì)日志功能,則Web Service審計(jì)日志會(huì)記錄訪問(wèn)者的IP地址、訪問(wèn)時(shí)間、訪問(wèn)文件等信息,SQL注入漏洞攻擊往往會(huì)大量訪問(wèn)某一個(gè)頁(yè)面文件(存在SQL注入點(diǎn)的動(dòng)態(tài)網(wǎng)頁(yè)),審計(jì)日志文件會(huì)急劇增加,通過(guò)查看審計(jì)日志文件的大小以及審計(jì)日志文件中的內(nèi)容,可以判斷是否發(fā)生過(guò)SQL注入漏洞攻擊事件;另外還可以通過(guò)查看數(shù)據(jù)庫(kù)審計(jì)日志,查詢某個(gè)時(shí)間段是否有非法的插入、修改、刪除操作。
(5)其他
SQL注入漏洞攻擊成功后,入侵者往往會(huì)添加特權(quán)用戶(如:administrator、root、sa等)、開(kāi)放非法的遠(yuǎn)程服務(wù)以及安裝木馬后門程序等,可以通過(guò)查看用戶帳戶列表、遠(yuǎn)程服務(wù)開(kāi)啟情況、系統(tǒng)最近日期產(chǎn)生的一些文件等信息來(lái)判斷是否發(fā)生過(guò)入侵。
3. SQL注入漏洞防范措施
SQL注入漏洞攻擊的防范方法有很多種,現(xiàn)階段總結(jié)起來(lái)有以下方法:
(1)數(shù)據(jù)有效性校驗(yàn)。如果一個(gè)輸入框只可能包括數(shù)字,那么要通過(guò)校驗(yàn)確保用戶輸入的都是數(shù)字。如果可以接受字母,那就要檢查是不是存在不可接受的字符,最好的方法是增加字符復(fù)雜度自動(dòng)驗(yàn)證功能。確保應(yīng)用程序要檢查以下字符:分號(hào)、等號(hào)、破折號(hào)、括號(hào)以及SQL關(guān)鍵字。另外限制表單數(shù)據(jù)輸入和查詢字符串輸入的長(zhǎng)度也是一個(gè)好方法。如果用戶的登錄名最多只有10個(gè)字符,那么不要認(rèn)可表單中輸入10個(gè)以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。
(2)封裝數(shù)據(jù)信息。對(duì)客戶端提交的數(shù)據(jù)進(jìn)行封裝,不要將數(shù)據(jù)直接存入cookie中,方法就是在編程的代碼中,插入session、if、try、else,這樣可以有效地防止攻擊者獲取cookie中的重要信息。
(3)去除代碼中的敏感信息。將在代碼中存在的用戶名、口令信息等敏感字段刪除,替換成輸入框。
SQL=" select from users where username = ’admin’and password= ’1234567’ "
如:這樣顯然會(huì)暴露管理員的用戶名、口令信息。可以將其修改成:
SQL= " select * from users where username='" +Txtuser.Text + "' and userpwd='" + Textpwd.Text + "'"
這樣就安全了很多,入侵者也是不會(huì)輕易的就獲取到用戶名、口令信息。
(4)替換或刪除單引號(hào)。使用雙引號(hào)替換掉所有用戶輸入的單引號(hào),這個(gè)簡(jiǎn)單的預(yù)防措施將在很大程度上預(yù)防SQL注入漏洞攻擊,單引號(hào)時(shí)常會(huì)無(wú)法約束插入數(shù)據(jù)的Value,可能給予輸入者不必要的權(quán)限。用雙引號(hào)替換掉單引號(hào)可以使大部分SQL注入漏洞攻擊失敗。 如:
“select* from users where username='" + admin + "' and userpwd='" + 1234567+ "'”
顯然會(huì)得到與
“select * from users where username='admin' and password= '1234567'”
相同的結(jié)果。
(5)指定錯(cuò)誤返回頁(yè)面。攻擊者有時(shí)從客戶端嘗試提交有害代碼和攻擊字符串,根據(jù)Web Service給出的錯(cuò)誤提示信息來(lái)收集程序及服務(wù)器的信息,從而獲取想得到的資料。應(yīng)在Web Service中指定一個(gè)不包含任何信息的錯(cuò)誤提示頁(yè)面。
(6)限制SQL字符串連接的配置文件。使用SQL變量,因?yàn)樽兞坎皇强梢詧?zhí)行的腳本,即在Web頁(yè)面中將連接數(shù)據(jù)庫(kù)的SQL字符串替換成指定的Value,然后將Web.config文件進(jìn)行加密,拒絕訪問(wèn)。
(7)設(shè)置Web目錄的訪問(wèn)權(quán)限。將虛擬站點(diǎn)的文件目錄禁止游客用戶(如:Guest用戶等)訪問(wèn),將User用戶權(quán)限修改成只讀權(quán)限,切勿將管理權(quán)限的用戶添加到訪問(wèn)列表。
(8)最小服務(wù)原則。Web服務(wù)器應(yīng)以最小權(quán)限進(jìn)行配置,只提供Web服務(wù),這樣可以有效地阻止系統(tǒng)的危險(xiǎn)命令,如ftp、cmd、vbscript等。
(9)鑒別信息加密存儲(chǔ)。將保存在數(shù)據(jù)庫(kù)users表中的用戶名、口令信息以密文形式保存,也可以對(duì)users表進(jìn)行加密處理,這樣可以大大增加對(duì)鑒別信息訪問(wèn)的安全級(jí)別。
(10)用戶權(quán)限分離。應(yīng)盡可能的禁止或刪除數(shù)據(jù)庫(kù)中sa權(quán)限用戶的訪問(wèn),對(duì)不同的數(shù)據(jù)庫(kù)劃分不同的用戶權(quán)限,這樣不同的用戶只能對(duì)授權(quán)給自己的數(shù)據(jù)庫(kù)執(zhí)行查詢、插入、更新、刪除操作,就可以防止不同用戶對(duì)非授權(quán)的數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn)。
4. 結(jié)束語(yǔ)
SQL注入漏洞攻擊在網(wǎng)上非常普遍,許多ASP、PHP論壇和文章管理系統(tǒng)、下載系統(tǒng)以及新聞系統(tǒng)都存在這個(gè)漏洞。造成SQL注入漏洞攻擊的主要原因是開(kāi)發(fā)人員在系統(tǒng)開(kāi)發(fā)的過(guò)程中編程不規(guī)范,沒(méi)有形成良好的編程習(xí)慣,問(wèn)題的解決只有依賴于規(guī)范編程。此外,也可以使用現(xiàn)有的SQL注入漏洞掃描器對(duì)整個(gè)網(wǎng)站中的關(guān)鍵代碼進(jìn)行掃描,查找網(wǎng)站頁(yè)面中存在的SQL注入點(diǎn)。對(duì)于有問(wèn)題的頁(yè)面,可以及時(shí)刪除或更新。本文通過(guò)對(duì)SQL注入漏洞攻擊的方法、原理以及攻擊實(shí)施過(guò)程進(jìn)行了闡述和總結(jié),并給出了一些常見(jiàn)的SQL注入漏洞攻擊防范的方法。
三、舉例說(shuō)明SQL注入的一般過(guò)程!
如果你以前沒(méi)試過(guò)SQL注入的話,那么第一步先把IE菜單=>工具=>Internet選項(xiàng)=>高級(jí)=>顯示友好 HTTP 錯(cuò)誤信息前面的勾去掉。否則,不論服務(wù)器返回什么錯(cuò)誤,IE都只顯示為HTTP 500服務(wù)器錯(cuò)誤,不能獲得更多的提示信息。
第一節(jié)、SQL注入原理
以下我們從一個(gè)網(wǎng)站www.19cn.com開(kāi)始(注:本文發(fā)表前已征得該站站長(zhǎng)同意,大部分都是真實(shí)數(shù)據(jù))。
在網(wǎng)站首頁(yè)上,有名為“IE不能打開(kāi)新窗口的多種解決方法”的鏈接,地址為:http://www.19cn.com/showdetail.asp?id=49,我們?cè)谶@個(gè)地址后面加上單引號(hào)’,服務(wù)器會(huì)返回下面的錯(cuò)誤提示:
Microsoft JET Database Engine 錯(cuò)誤 '80040e14'
字符串的語(yǔ)法錯(cuò)誤 在查詢表達(dá)式 'ID=49'' 中。
/showdetail.asp,行8
從這個(gè)錯(cuò)誤提示我們能看出下面幾點(diǎn):
1.網(wǎng)站使用的是Access數(shù)據(jù)庫(kù),通過(guò)JET引擎連接數(shù)據(jù)庫(kù),而不是通過(guò)ODBC。
2.程序沒(méi)有判斷客戶端提交的數(shù)據(jù)是否符合程序要求。
3.該SQL語(yǔ)句所查詢的表中有一名為ID的字段。
從上面的例子我們可以知道,SQL注入的原理,就是從客戶端提交特殊的代碼,從而收集程序及服務(wù)器的信息,從而獲取你想到得到的資料。
第二節(jié)、判斷能否進(jìn)行SQL注入
看完第一節(jié),有一些人會(huì)覺(jué)得:我也是經(jīng)常這樣測(cè)試能否注入的,這不是很簡(jiǎn)單嗎?其實(shí),這并不是最好的方法,為什么呢?
首先,不一定每臺(tái)服務(wù)器的IIS都返回具體錯(cuò)誤提示給客戶端,如果程序中加了cint(參數(shù))之類語(yǔ)句的話,SQL注入是不會(huì)成功的,但服務(wù)器同樣會(huì)報(bào)錯(cuò),具體提示信息為處理 URL 時(shí)服務(wù)器上出錯(cuò)。請(qǐng)和系統(tǒng)管理員聯(lián)絡(luò)。
其次,部分對(duì)SQL注入有一點(diǎn)了解的程序員,認(rèn)為只要把單引號(hào)過(guò)濾掉就安全了,這種情況不為少數(shù),如果你用單引號(hào)測(cè)試,是測(cè)不到注入點(diǎn)的
那么,什么樣的測(cè)試方法才是比較準(zhǔn)確呢?答案如下:
① http://www.19cn.com/showdetail.asp?id=49
② http://www.19cn.com/showdetail.asp?id=49 and 1=1
③ http://www.19cn.com/showdetail.asp?id=49 and 1=2
這就是經(jīng)典的1=1、1=2測(cè)試法了,怎么判斷呢?看看上面三個(gè)網(wǎng)址返回的結(jié)果就知道了:
可以注入的表現(xiàn):
① 正常顯示(這是必然的,不然就是程序有錯(cuò)誤了)
② 正常顯示,內(nèi)容基本與①相同
③ 提示BOF或EOF(程序沒(méi)做任何判斷時(shí))、或提示找不到記錄(判斷了rs.eof時(shí))、或顯示內(nèi)容為空(程序加了on error resume next)
不可以注入就比較容易判斷了,①同樣正常顯示,②和③一般都會(huì)有程序定義的錯(cuò)誤提示,或提示類型轉(zhuǎn)換時(shí)出錯(cuò)。
當(dāng)然,這只是傳入?yún)?shù)是數(shù)字型的時(shí)候用的判斷方法,實(shí)際應(yīng)用的時(shí)候會(huì)有字符型和搜索型參數(shù),我將在中級(jí)篇的“SQL注入一般步驟”再做分析。
第三節(jié)、判斷數(shù)據(jù)庫(kù)類型及注入方法
不同的數(shù)據(jù)庫(kù)的函數(shù)、注入方法都是有差異的,所以在注入之前,我們還要判斷一下數(shù)據(jù)庫(kù)的類型。一般ASP最常搭配的數(shù)據(jù)庫(kù)是Access和SQLServer,網(wǎng)上超過(guò)99%的網(wǎng)站都是其中之一。
怎么讓程序告訴你它使用的什么數(shù)據(jù)庫(kù)呢?來(lái)看看:
SQLServer有一些系統(tǒng)變量,如果服務(wù)器IIS提示沒(méi)關(guān)閉,并且SQLServer返回錯(cuò)誤提示的話,那可以直接從出錯(cuò)信息獲取,方法如下:
http://www.19cn.com/showdetail.asp?id=49 and user>0
這句語(yǔ)句很簡(jiǎn)單,但卻包含了SQLServer特有注入方法的精髓,我自己也是在一次無(wú)意的測(cè)試中發(fā)現(xiàn)這種效率極高的猜解方法。讓我看來(lái)看看它的含義:首先,前面的語(yǔ)句是正常的,重點(diǎn)在and user>0,我們知道,user是SQLServer的一個(gè)內(nèi)置變量,它的值是當(dāng)前連接的用戶名,類型為nvarchar。拿一個(gè)nvarchar的值跟int的數(shù)0比較,系統(tǒng)會(huì)先試圖將nvarchar的值轉(zhuǎn)成int型,當(dāng)然,轉(zhuǎn)的過(guò)程中肯定會(huì)出錯(cuò),SQLServer的出錯(cuò)提示是:將nvarchar值 ”abc” 轉(zhuǎn)換數(shù)據(jù)類型為 int 的列時(shí)發(fā)生語(yǔ)法錯(cuò)誤,呵呵,abc正是變量user的值,這樣,不廢吹灰之力就拿到了數(shù)據(jù)庫(kù)的用戶名。在以后的篇幅里,大家會(huì)看到很多用這種方法的語(yǔ)句。
順便說(shuō)幾句,眾所周知,SQLServer的用戶sa是個(gè)等同Adminstrators權(quán)限的角色,拿到了sa權(quán)限,幾乎肯定可以拿到主機(jī)的Administrator了。上面的方法可以很方便的測(cè)試出是否是用sa登錄,要注意的是:如果是sa登錄,提示是將”dbo”轉(zhuǎn)換成int的列發(fā)生錯(cuò)誤,而不是”sa”。
如果服務(wù)器IIS不允許返回錯(cuò)誤提示,那怎么判斷數(shù)據(jù)庫(kù)類型呢?我們可以從Access和SQLServer和區(qū)別入手,Access和SQLServer都有自己的系統(tǒng)表,比如存放數(shù)據(jù)庫(kù)中所有對(duì)象的表,Access是在系統(tǒng)表[msysobjects]中,但在Web環(huán)境下讀該表會(huì)提示“沒(méi)有權(quán)限”,SQLServer是在表[sysobjects]中,在Web環(huán)境下可正常讀取。
在確認(rèn)可以注入的情況下,使用下面的語(yǔ)句:
http://www.19cn.com/showdetail.asp?id=49 and (select count(*) from sysobjects)>0
http://www.19cn.com/showdetail.asp?id=49 and (select count(*) from msysobjects)>0
如果數(shù)據(jù)庫(kù)是SQLServer,那么第一個(gè)網(wǎng)址的頁(yè)面與原頁(yè)面http://www.19cn.com/showdetail.asp?id=49是大致相同的;而第二個(gè)網(wǎng)址,由于找不到表msysobjects,會(huì)提示出錯(cuò),就算程序有容錯(cuò)處理,頁(yè)面也與原頁(yè)面完全不同。
如果數(shù)據(jù)庫(kù)用的是Access,那么情況就有所不同,第一個(gè)網(wǎng)址的頁(yè)面與原頁(yè)面完全不同;第二個(gè)網(wǎng)址,則視乎數(shù)據(jù)庫(kù)設(shè)置是否允許讀該系統(tǒng)表,一般來(lái)說(shuō)是不允許的,所以與原網(wǎng)址也是完全不同。大多數(shù)情況下,用第一個(gè)網(wǎng)址就可以得知系統(tǒng)所用的數(shù)據(jù)庫(kù)類型,第二個(gè)網(wǎng)址只作為開(kāi)啟IIS錯(cuò)誤提示時(shí)的驗(yàn)證。
第一節(jié)、SQL注入的一般步驟
首先,判斷環(huán)境,尋找注入點(diǎn),判斷數(shù)據(jù)庫(kù)類型,這在入門篇已經(jīng)講過(guò)了。
其次,根據(jù)注入?yún)?shù)類型,在腦海中重構(gòu)SQL語(yǔ)句的原貌,按參數(shù)類型主要分為下面三種:
(A) ID=49 這類注入的參數(shù)是數(shù)字型,SQL語(yǔ)句原貌大致如下:
Select * from 表名 where 字段=49
注入的參數(shù)為ID=49 And [查詢條件],即是生成語(yǔ)句:
Select * from 表名 where 字段=49 And [查詢條件]
(B) Class=連續(xù)劇 這類注入的參數(shù)是字符型,SQL語(yǔ)句原貌大致概如下:
Select * from 表名 where 字段=’連續(xù)劇’
注入的參數(shù)為Class=連續(xù)劇’ and [查詢條件] and ‘’=’ ,即是生成語(yǔ)句:
Select * from 表名 where 字段=’連續(xù)劇’ and [查詢條件] and ‘’=’’
(C) 搜索時(shí)沒(méi)過(guò)濾參數(shù)的,如keyword=關(guān)鍵字,SQL語(yǔ)句原貌大致如下:
Select * from 表名 where 字段like ’%關(guān)鍵字%’
注入的參數(shù)為keyword=’ and [查詢條件] and ‘%25’=’, 即是生成語(yǔ)句:
Select * from 表名 where字段like ’%’ and [查詢條件] and ‘%’=’%’
接著,將查詢條件替換成SQL語(yǔ)句,猜解表名,例如:
ID=49 And (Select Count(*) from Admin)>=0
如果頁(yè)面就與ID=49的相同,說(shuō)明附加條件成立,即表Admin存在,反之,即不存在(請(qǐng)牢記這種方法)。如此循環(huán),直至猜到表名為止。
表名猜出來(lái)后,將Count(*)替換成Count(字段名),用同樣的原理猜解字段名。
有人會(huì)說(shuō):這里有一些偶然的成分,如果表名起得很復(fù)雜沒(méi)規(guī)律的,那根本就沒(méi)得玩下去了。說(shuō)得很對(duì),這世界根本就不存在100%成功的黑客技術(shù),蒼蠅不叮無(wú)縫的蛋,無(wú)論多技術(shù)多高深的黑客,都是因?yàn)閯e人的程序?qū)懙貌粐?yán)密或使用者保密意識(shí)不夠,才有得下手。
有點(diǎn)跑題了,話說(shuō)回來(lái),對(duì)于SQLServer的庫(kù),還是有辦法讓程序告訴我們表名及字段名的,我們?cè)诟呒?jí)篇中會(huì)做介紹。
最后,在表名和列名猜解成功后,再使用SQL語(yǔ)句,得出字段的值,下面介紹一種最常用的方法-Ascii逐字解碼法,雖然這種方法速度很慢,但肯定是可行的方法。
我們舉個(gè)例子,已知表Admin中存在username字段,首先,我們?nèi)〉谝粭l記錄,測(cè)試長(zhǎng)度:
http://www.19cn.com/showdetail.asp?id=49 and (select top 1 len(username) from Admin)>0
先說(shuō)明原理:如果top 1的username長(zhǎng)度大于0,則條件成立;接著就是>1、>2、>3這樣測(cè)試下去,一直到條件不成立為止,比如>7成立,>8不成立,就是len(username)=8
當(dāng)然沒(méi)人會(huì)笨得從0,1,2,3一個(gè)個(gè)測(cè)試,怎么樣才比較快就看各自發(fā)揮了。在得到username的長(zhǎng)度后,用mid(username,N,1)截取第N位字符,再asc(mid(username,N,1))得到ASCII碼,比如:
id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0
同樣也是用逐步縮小范圍的方法得到第1位字符的ASCII碼,注意的是英文和數(shù)字的ASCII碼在1-128之間,可以用折半法加速猜解,如果寫成程序測(cè)試,效率會(huì)有極大的提高。
第二節(jié)、SQL注入常用函數(shù)
有SQL語(yǔ)言基礎(chǔ)的人,在SQL注入的時(shí)候成功率比不熟悉的人高很多。我們有必要提高一下自己的SQL水平,特別是一些常用的函數(shù)及命令。
Access:asc(字符) SQLServer:unicode(字符)
作用:返回某字符的ASCII碼
Access:chr(數(shù)字) SQLServer:nchar(數(shù)字)
作用:與asc相反,根據(jù)ASCII碼返回字符
Access:mid(字符串,N,L) SQLServer:substring(字符串,N,L)
作用:返回字符串從N個(gè)字符起長(zhǎng)度為L(zhǎng)的子字符串,即N到N+L之間的字符串
Access:abc(數(shù)字) SQLServer:abc (數(shù)字)
作用:返回?cái)?shù)字的絕對(duì)值(在猜解漢字的時(shí)候會(huì)用到)
Access:A between B And C SQLServer:A between B And C
作用:判斷A是否界于B與C之間
第三節(jié)、中文處理方法
在注入中碰到中文字符是常有的事,有些人一碰到中文字符就想打退堂鼓了。其實(shí)只要對(duì)中文的編碼有所了解,“中文恐懼癥”很快可以克服。
先說(shuō)一點(diǎn)常識(shí):
Access中,中文的ASCII碼可能會(huì)出現(xiàn)負(fù)數(shù),取出該負(fù)數(shù)后用abs()取絕對(duì)值,漢字字符不變。
SQLServer中,中文的ASCII為正數(shù),但由于是UNICODE的雙位編碼,不能用函數(shù)ascii()取得ASCII碼,必須用函數(shù)unicode ()返回unicode值,再用nchar函數(shù)取得對(duì)應(yīng)的中文字符。
四、如何在servlet 中處理sql注入
一、經(jīng)常出現(xiàn)漏洞的sql語(yǔ)句 用戶名和密碼 一起同時(shí)查詢。
select * from users where username=‘a(chǎn)bc’ and passwd=‘123’ or 1=‘1’
12
二、正確的sql語(yǔ)句先查詢數(shù)據(jù)庫(kù)根據(jù)用戶名查詢密碼,如果存在改用戶名,再看密碼是否相同。
"select passwd from users where username='" + name + "' limit 1";1
正確代碼如下:
String name = req.getParameter("username");
String pwd = req.getParameter("pwd");
Connection conn = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver);
// 得到數(shù)據(jù)庫(kù)連接
String url = "jdbc:mysql://localhost:3306/student";
String user = "root";
String password = "tianyejun6";
conn = DriverManager.getConnection(url, user, password);
// 創(chuàng)建statement
statement = conn.createStatement();
//sql語(yǔ)句
String sql = "select passwd from users where username='" + name + "' limit 1";
System.out.println(sql);
resultSet = statement.executeQuery(sql);
if (resultSet.next()) {
// 說(shuō)明用戶真實(shí)存在
String passwd = resultSet.getString(1);
if (passwd.equals(pwd)) {// 說(shuō)明用戶真合法,密碼相同
HttpSession session = req.getSession(true);
// 向session中添加某個(gè)屬性
session.setAttribute("pass", "ok");
// 設(shè)置超時(shí)時(shí)間。
session.setMaxInactiveInterval(20);
resp.sendRedirect("Wel?username=" + name + "&pwd=" + pwd);
} else {// 說(shuō)明用戶名不存在
resp.sendRedirect("Login");
}
} else {
resp.sendRedirect("Login");
}
} catch (Exception e) {
e.printStackTrace();
resp.sendRedirect("Login");
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
以上就是關(guān)于如何sql注入相關(guān)問(wèn)題的回答。希望能幫到你,如有更多相關(guān)問(wèn)題,您也可以聯(lián)系我們的客服進(jìn)行咨詢,客服也會(huì)為您講解更多精彩的知識(shí)和內(nèi)容。
推薦閱讀:
景觀設(shè)計(jì)師如何在抖音推廣(景觀設(shè)計(jì)師如何在抖音推廣產(chǎn)品)
設(shè)計(jì)院未來(lái)發(fā)展前景(設(shè)計(jì)院未來(lái)發(fā)展前景如何)
室內(nèi)魚池假山設(shè)計(jì)實(shí)景圖(室內(nèi)魚池假山設(shè)計(jì)實(shí)景圖 小型)
猜你喜歡
常見(jiàn)的網(wǎng)頁(yè)布局(常見(jiàn)的網(wǎng)頁(yè)布局形式有幾種)
日本人智商亞洲排第一(日本人智商亞洲排第一的是誰(shuí))
國(guó)內(nèi)最權(quán)威的腫瘤醫(yī)院(國(guó)內(nèi)最權(quán)威的腫瘤醫(yī)院是哪家)
有沒(méi)有網(wǎng)站來(lái)一個(gè)(有沒(méi)有網(wǎng)站給我一個(gè))
四大地理區(qū)域的氣候特征(四大地理區(qū)域的氣候特征及類型)
一般個(gè)人網(wǎng)址是什么(一般個(gè)人網(wǎng)址是什么格式的)
抖音搜索全部變成用戶了(抖音搜索全部變成用戶了怎么恢復(fù))
問(wèn)大家
東城奠基儀式辦公會(huì)議場(chǎng)地出租如何選擇不被騙?在座的老鐵們?cè)诰€等
抖音海外直播權(quán)限如何開(kāi)通,如何開(kāi)通抖音海外直播權(quán)限
抖音如何開(kāi)通海外直播權(quán)限?抖音怎么開(kāi)通海外直播權(quán)限
成都價(jià)錢最公道的會(huì)務(wù)策劃如何避免踩一些雷?路過(guò)的老司機(jī)們幫個(gè)忙
在國(guó)外怎么做抖音直播?如何解決國(guó)外的直播權(quán)限?
濟(jì)南有哪家征婚交友相親介紹對(duì)象的比較誠(chéng)信、正規(guī)???收費(fèi)如何?
如何開(kāi)通抖音海外直播白名單?抖音海外直播權(quán)限解決辦法
抖音如何開(kāi)通國(guó)外直播權(quán)限?抖音怎么開(kāi)通國(guó)外直播權(quán)限?
抖音如何在英國(guó)直播?抖音怎么在英國(guó)直播?
如何開(kāi)通抖音海外直播白名單?抖音海外直播權(quán)限解決辦法
武漢里可以代做投標(biāo)文件,代寫標(biāo)書多少錢一份
河北二志文化傳媒有限公司在秦皇島專業(yè)制作候車廳行業(yè)口碑如何?在座的資深人士們急需賜教
如果一個(gè)平面設(shè)計(jì)有計(jì)劃轉(zhuǎn)行,轉(zhuǎn)到哪個(gè)行業(yè)或者職位會(huì)比較容易呢?