今天让我们来看看在SQL Server加密和SQL 注入攻击
SQL Server上的加密
SQL Server上内置了加密用来保护各种类型的敏感数据在很多时候这个加密对于你来说是完全透明的当数据被存储时候被加密它们被使用的时候就会自动加密在其他的情况下你可以选择数据是否要被加密SQL Server可以加密下列这些组件
·密码
·存储过程视图触发器用户自定义函数默认值和规则
·在服务器和用户之间传输的数据
密码加密
SQL Server自动将你分配给登陆和应用角色的密码加密尽管当你可以从主数据库中直接察看系统表格而不需要密码你不能给对这种情况作出任何修改事实上你根本不能破坏它
定义加密
在有些时候如果对对象进行加密是防止将一些信息分享给他人例如一个存储进程可能包含所有者的商业信息但是这个信息不能和让其他的人看到即使他们公开的系统表格并可以看到对象的定义这就是为什么SQL Server允许你在创建一个对象的时候进行加密为了加密一个存储进程使用下面形式的CREAT PROCEDURE 语句
CREATE PROCEDURE procedurename [;number]
[@parameter datatype
[VARYING][ = defaultvalue][OUTPUT]]
[ …]
[WITH RECOMPILE | ENCRYPTION | RECOMPILE ENCRYPTION]
我们关心的仅仅是可选的WITH参数你可以详细说明ARECOMPILE或者ENCRYPTION或者你可以同时说明它们ENCRYPTION关键字保护SQL Server它不被公开在进程中结果如果ENCRYPTION在激活的时候系统存储进程sp_helptext就会被忽视这个存储进程将被存储在用户创建进程的文本中如果你不想要加密你可以使用ALTER PROCEDURE忽略WITH ENCRYPTION子句来重新创建一个进程
为了能够使用加密用户和服务器都应该使用TCP/IP NetworkLibraries用来连接运行适当的Network Utility和检查Force protocol encryption看下表用户和服务器之间的连接将不会被加密
加密也不能完全自由当连接确定后要继续其他的构造并且用户和服务器必须运行代码来解释加密和解释的包裹这里将需要一些开销并且当在编译码的时候会使进程慢下来如果网络包裹在你控制范围之外使用这种做法是非常好的
加密中缺少什么?
你可以注意到在这个列表中缺少一些被加密的东西你表格中的数据在你存储数据之前SQL Server不会提供任何内置的工具来加密你的数据
如果你需要保护存储在SQL Server上的数据我们给你两条建议
第一你可以利用GRANT 和DENY关键字来控制你想哪个用户可以在SQL Server中读取的数据
第二.如果你真的想对数据加密不要设法加密码你可以利用被测试过的商业产品的算法
SQL 注入攻击
SQL 注入攻击是一个常规性的攻击它可以允许一些不法用户检索你的数据改变服务器的设置或者在你不小心的时候黑掉你的服务器SQL 注入攻击不是SQL Server问题而是不适当的程序如果你想要运行这些程序的话你必须明白这冒着一定的风险
测点定位弱点
SQL 注入的脆弱点发生在程序开发员构造一个WHERE 子句伴随着用户的输入的时候比如一个简单的ASP程序允许用户输入一个顾客的ID然后检索公司的全部人员的名字如果顾客ID如果作为ASP页面的请求串的一部分返回那么开发员可以编写下面的代码获得数据
strConn = Provider=SQLOLEDB;Data Source=(local); & _
Database=Northwind;Integrated Security=SSPI
Set cnn = ServerCreateObject(ADODBConnection)
cnnOpen strConn
strQuery = SELECT ContactName FROM Customers & _
WHERE CustomerID = & RequestForm(CustID) &
Set rstResults = cnnExecute(strQuery)
ResponseWrite(rstResultsFields(ContactName)Value)
现在你知道什么地方有问题了吧?如果用户知道一个用户的ID他可以通过检索来获得全部的相应的名字现在明白了?
获得额外的数据
当然对于一个攻击程序尽管它不知道任何顾客的ID甚至不用去猜它也可以获得数据为了完成这个工作它将下面的文本输入到应用程序调用顾客ID的textbox中
customer ID:
UNION ALL SELECT ContactName FROM Customers
WHERE CustomerID <>
如果你输入了这个代码你将会看到返回一个询问语句
SELECT ContactName FROM Customers
WHERE CustomerID =
UNION ALL SELECT ContactName FROM Customers
WHERE CustomerID <>
通过获得空和非空顾客的ID并集这个查询语句会返回数据库中所有的相关姓名事实上这个UNION技术可以被用来获得你数据库中大多数信息看看这个CustomerID的值
UNION ALL SELECT FirstName + + LastName FROM
Employees WHERE LastName <>
它将SQL语句变成
SELECT ContactName FROM Customers
WHERE CustomerID =
UNION ALL SELECT FirstName + + LastName FROM
Employees WHERE LastName <>
看那就是攻击程序从你的数据库获得的第一个雇员的名字
更多的攻击程序
如果SQL注入仅仅只有数据暴光这个弱点就已经够糟糕的了但是实际上一个良好的攻击程序可以通过这个弱点获取你数据库中所有的资料看下面这个例子
;DROP TABLE Customers;
SQL语句变成
SELECT ContactName FROM Customers
WHERE CustomerID =
; DROP TABLE Customers;
这个分号使语句和SQL Server隔离所以这里实际上是两个语句第一个语句不存在的名字第二个则撤消的整个Customers表两个—SQL Server注释符它可以使子句不发生语法错误
使用这个技术的变异一个攻击程序可以在任何SQL语句或者存储过程上运行通过使用xp_cmdshell扩展存储过程一个攻击程序同样可以在操作系统命令下运行显然这是一个严重的漏洞
保护自己的数据库
现在你知道如何防范SQL注入攻击了吗?首先你不能在用户输入中构造WHERE子句你应该利用参数来使用存储进程在最初的ASP页面下重新写的部分将和刚才我们在表中所看到的东西相似即使你认为在你的应用程序中没有脆弱点你应该遵守最小特权原则使用我们建议的其他安全技术允许你的用户仅仅访问他们能够访问的在你没有发现你数据库脆弱点的时候只有这样不会使你的数据库崩溃
最后的建议
这就是全部的SQL Server安全系列也许你现在不是一个全面的专家但是你已经了解了很多反面下一步就是你要保护你SQL Server数据记住你在这里所学到的知识并利用到你的数据库中保证你的数据不被那些黑客攻击