数据库审计产品常见缺陷(3)多语句无法有效分割

2014-04-02 11:09:07来源:游侠安全网作者:
多语句是SQL Server上的一个特定情况。在其它的数据库管理系统中,语句之间都有明确的分割标识;而在SQL Serve中语句之间可以没有明确的分隔符。下面是一个示例:
多语句是SQL Server上的一个特定情况。在其它的数据库管理系统中,语句之间都有明确的分割标识;而在SQL Serve中语句之间可以没有明确的分隔符。下面是一个示例: use opencms SET NOCOUNT ON select * from opencms.opencms.CMS_LOG? where 1=1 or ‘a’ =’b’ select * from opencms.opencms.CMS_HISTORY_PROJECTS where 1=1 在这些语句之间没有类似于 ;号这样的明确分隔标识符;它们实际代表了四条语句: use opencms SET NOCOUNT ON select * from opencms.opencms.CMS_LOG? where 1=1 or ‘a’ =’b’ select * from opencms.opencms.CMS_HISTORY_PROJECTS where 1=1 SQL Server会将这些语句不加分割地组织在一个数据库通讯包中发送;对于一些专业化程度不高的数据库审计产品,会将这些语句作为一条语句审计下来。有效地实现多语句分割,需要非常专业的SQL解析技术。一些简单的方法,比如用select、use 、set这样的关键字来进行语句分割,稍微复杂的情况就不好处理了;下面这个示例,就无法用这种简单的方法处理: Select * from t1 where t1.col1 = 1 union     select * from? t2 where t2.col1 = 1 select * from t2 where t2.col1 = 1 即使采用稍微复杂一些的技术,比如正则表达式,也很难做到准确切割;非专业化的数据库审计产品都存在这个缺陷。 对无法准确切割多语句的缺陷,在不同的产品中表现不同,所造成的审计问题也不同,但大体可以总结为如下几点: (1)在审计记录中,不能准确记录下每条语句的SQL操作类型,从而造成一些高危操作不能不有效地被识别或告警,比如drop、truncate这些语句。 (2)在审计记录中,不能准确记录下每条SQL语句的数据库对象,从而对敏感对象的访问不能有效地被识别或告警。 (3)在审计记录中,不能准确地记录每条语句是否执行成功;比如多条语句中第一条语句执行成功,后面的语句执行失败了,往往会被整体记录为一个结果,往往是成功。 (4)在审计记录中,不能准确地反馈出每条语句造成的影响行数,从而也无法触发基于影响行的安全策略;往往记录下来的都是第一条语句的影响行,其余语句的影响行都被扔掉了。 下面的结果是一个专业数据库审计产品的执行结果,该产品准确实现了多语句切割,同时准确审计了每条语句的执行成功与否和影响行: db 以上结果,根据语句发送的先后顺序进行了倒排显示,同时审计了每条语句的操作对象、SQL语句、执行成功与否,影响行数。 这里进一步提供了一些用例,来帮助读者验证数据库审计产品能否完成多语句切割,是否准确地审计了每条语句的访问对象、返回结果和影响行: 用例一(一个很基本的多语句例子) INSERT INTO #AM_DBFILEIO(COLLECTION_TIME,TOTAL_IO_BYTES)VALUES(@CURRENT_COLLECTION_TIME,@CURRENT_TOTAL_IO_MB) insert #t1 ( object_id, object_type, rank) select t.relative_id, t.relative_type, 1 from #t1 t where t.relative_id not in ( select t2.object_id from #t1 t2 where not t2.object_id is null ) 用例二(一个稍显复杂点的,与游标相关的多语句示例): DECLARE tables_cursor CURSOR FOR SELECT name FROM sysobjects WHERE type = ‘U’ OPEN tables_cursor DECLARE @tablename sysname FETCH NEXT FROM tables_cursor INTO @tablename WHILE (@@FETCH_STATUS <> -1) BEGIN /* A @@FETCH_STATUS of -2 means that the row has been deleted. There is no need to test for this because this loop drops all user-defined tables. */ EXEC (‘DROP TABLE ‘ + @tablename) FETCH NEXT FROM tables_cursor INTO @tablename END PRINT ‘All user-defined tables have been dropped from the database.’ DEALLOCATE tables_cursor ; 用例三:(一个更复杂的的多语句示例) SET NOCOUNT ON; – Check Agent Status CREATE TABLE #TempAgentStatus (AgentStatus nvarchar(50)) IF (IS_SRVROLEMEMBER(‘sysadmin’) > 0) INSERT #TempAgentStatus (AgentStatus) EXEC master..xp_servicecontrol N’QUERYSTATE’,N’SQLServerAGENT’ ; ELSE INSERT #TempAgentStatus (AgentStatus) — sometimes this check doesn’t work – there are complains on the www SELECT ‘running’ FROM master.dbo.sysprocesses WHERE program_name like N’SQLAgent%Generic%Refresher%’ DECLARE @AgentRunning int; SET @AgentRunning = 0 SELECT @AgentRunning =1 from #TempAgentStatus where CharIndex(N’running’, Lower(AgentStatus)) > 0 DROP TABLE #TempAgentStatus – End Check Agent Status DECLARE @can_see_all_running_jobs int; SET @can_see_all_running_jobs = ISNULL(IS_SRVROLEMEMBER(N’sysadmin’), 0); DECLARE @current_execution_status int; DECLARE @job_owner sysname; SET @job_owner = SUSER_SNAME(); CREATE TABLE #xp_results ( job_id UNIQUEIDENTIFIER NOT NULL, last_run_date int NOT NULL, last_run_time int NOT NULL, next_run_date int NOT NULL, next_run_time int NOT NULL, next_run_schedule_id int NOT NULL, requested_to_run int NOT NULL, — BOOL request_source int NOT NULL, request_source_id sysname COLLATE database_default NULL, running int NOT NULL, — BOOL current_step int NOT NULL, current_retry_attempt int NOT NULL, job_state int NOT NULL ); IF @AgentRunning = 1 BEGIN INSERT INTO #xp_results EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner; END SELECT DISTINCT COUNT(1) FROM msdb.dbo.sysjobs_view obj LEFT OUTER JOIN msdb.dbo.sysjobservers js ON js.job_id = obj.job_id LEFT OUTER JOIN msdb.dbo.sysjobhistory jh ON (jh.job_id = obj.job_id) AND (jh.step_id = 0) AND (jh.instance_id = (SELECT Max(ijh.instance_id) FROM msdb.dbo.sysjobhistory ijh WHERE ijh.job_id = obj.job_id)) LEFT OUTER JOIN #xp_results res on js.job_id = res.job_id DROP TABLE #xp_results; 说明:本文来自数据库安全厂家“安华金和” 的投稿,首发“游侠安全网”(www.youxia.org),转载请包括本声明。

赞助商链接:

齐乐娱乐