数据库系统是在操作系统平台之上的最重要的系统软件数据库系统的安全可以说是十分重要的曾经有句话这样说如果网络遍地是金钱那么金钱就在数据库服务器中随着无纸化业务环境的不断扩大人们在数据库中存储着越来越多的敏感信息银行账户医疗记录政府文件军事机密等等数据库系统就成为越来越有价值的攻击目标因此确保数据库系统的安全也越来越重要
作为一种大型的系统软件数据库系统中也存在着各种各样的安全漏洞其中危害性较大的有缓沖区溢出堆溢出和SQL注入等
缓沖区溢出
缓沖区溢出是一种很常见也很古老的安全漏洞早在上个世纪年代缓沖区溢出就已经为人所知但时至今日大量的缓沖区溢出漏洞仍被发现最着名的Morris蠕虫就是利用Unix系统上fingerd程序的缓沖区溢出漏洞在Oracle i发布之初Oarcle公司曾宣称他的数据库是 unbreakable 的但不到几个月的时间就暴出Oracle i中oracleexeXDB等程序存在多个缓沖区溢出漏洞
在C语言中最常见的缓沖区就是字符数组而操纵字符数组的函数有getsstrcpysprintf等这些函数在执行字符串拷贝的过程中没有对字符串进行长度检查这样就很容易发生超长的字符串溢出缓沖区的情况当初这样设计是出于效率的考虑但现在看来这些函数的使用已成为C语言软件脆弱的一个重要因素如果程序员没有良好的编程习惯时刻注意函数调用过程中是否拷贝了超过缓沖区长度的字符串那么缓沖区溢出就不可避免对于一个有缓沖区溢出漏洞的程序当普通用户输入超长字符串时通常只会使该程序崩溃例如对于下面一小段代码
以下是引用片段
/* vulprog */
#include
int main(int argc char * argv[])
{
char buff[];
strcpy(buff argv[]);
}
如果用户执行
/vulprog AAAAAAAAAAAAAAAA
在Linux上会出现段错误
因为用户输入了超长的字符串
除了填满了缓沖区
还覆盖了其他一些程序正常退出所需要的数据
为了研究这个问题
就需要了解Linux系统中进程的内存空间
进行函数调用时系统所作的序幕工作就是将函数的返回地址和EBP压栈再将ESP赋给EBP使其成为局部基指针最后ESP减去一定的值为局部变量留出空间这样当程序将过长的字符串拷贝到缓沖区时就会依次覆盖EBP和返回地址当用AAAA覆盖返回地址函数退栈时系统就将x(A的进制ASCII码)赋给EIP去执行由于是一个非法的内存地址故程序崩溃但如果用一个实际存在的地址覆盖返回地址那么程序就转而去执行该地址处的指令通常黑客会在这个地址植入所谓的shellcode由shellcode产生一个shell如果被攻击程序设置了suid位那么产生的shell就是root shell黑客也就获得了系统的最高控制权这一过程就是基本的缓沖区溢出攻击
覆盖函数的返回地址是比较常见的攻击方式但缓沖区溢出攻击的手法是灵活多样的往往在编程中的一个小小纰漏就可能导致被攻击下面简单介绍一下几种较为高级的攻击方式
()通过覆盖函数指针进行攻击
以下是引用片段
/* vulprog */
int main(int argc char * argv[])
{
void (* fp)(char *) = (void (*)(char *))&puts;
char buff[];
strcpy(buffargc[]);
fp(argc[]);
exit();
}
上面这个程序在执行拷贝时没有检查边界
这样用户数据就有可能覆盖函数指针fp
如果用shllcode的地址去覆盖fp
那么函数指针调用时就会去执行shellcode
这种覆盖函数指针的方式是一种较直接的覆盖方式(因为函数指针就在缓沖区上面)还有一种间接的覆盖方式就是当函数指针不直接在缓沖区上面时通过覆盖另外一个指针来覆盖函数指针再将shellcode的地址填充函数指针
()通过覆盖 dtors区地址进行攻击
以下是引用片段
/* vulprog */
int main(int argc char * argv[])
{
char * pbuf = malloc(strlen(argv[])+);
char buff[];
strcpy(buffargv[]);
strcpy(pbufargv[]);
exit();
}
虽然这个程序没有函数指针
但在执行第二个拷贝时
可以将任意的数据拷贝到任意的地址中(这个地址由第一个拷贝指定)
这时就可以选择用
dtors区的地址覆盖指针pbuf
在执行第二个拷贝时将shellcode的地址拷贝至
dtors区
那么在函数退出时shellcode就会被执行
其实针对这个程序攻击者不仅可以覆盖dtors区的地址还可以覆盖GOT(全局偏移表)中exit的地址或__deregister_frame_info的地址
从上面的这些例子可以看出如果编程中不注意缓沖区边界的检查就很可能导致被溢出攻击
由于缓沖区溢出攻击的频繁爆发迫使很多操作系统厂商推出了不可执行堆栈更新C库函数等措施这些措施一定程度上遏制了普通的缓沖区溢出但道高一尺魔高一丈黑客们很快就将注意力转移到新的溢出攻击上如堆溢出从最初的溢出重要变量(如函数指针文件指针)到dlmalloc中mallocfree类型的堆溢出到ptmalloc中的堆溢出层出不穷其实不管这些手法有多高明最终的根源只有一个利用程序中未对缓沖区边界进行有效检查
SQL注入
数据库系统除了可能受到缓沖区溢出的攻击外近几年又出现了SQL注入的攻击方式这种攻击方式被称为 SYSDBA的恶梦SQL注入可能导致数据库系统中的普通用户窃取机密数据(如获得SYSDBA密码)进行权限提升(如获得SYSDBA特权)等而这种攻击方式又不需要太多计算机方面的知识一般只要能熟练使用SQL语言即可因此对数据库的安全构成了很大的威胁
SQL注入的攻击方式比较简单一般是将一些特权语句注入到有漏洞的存储过程或触发器中导致这些语句被非法执行例如在Oracle中由SYS创建如下存储过程并将执行权限授予普通用户
以下是引用片段
CREATE OR REPLACE PROCEDURE PROC ( INPUT VARCHAR) AS
STMT:=SELECT TITLES FROM BOOKS WHERE AUTHOR = || INPUT || ;
EXECUTE IMMEDIATE STMT;
正常情况下用户可以通过执行
EXEC SYS
PROC
(
DICKENS
)来查询DICKENS的着作
但如果恶意用户这样执行该存储过程
EXEC SYSPROC( DICKENS UNION SELECT PASSWORD FROM USERS_TABLE WHERE A = A)那么他就非法地查出了所有用户的密码
虽然这只是一个简单的例子但它表明在编写系统存储过程函数和触发器时一定要注意防止SQL注入的可能
数据库是信息系统的基石一旦被黑客入侵后果将不堪设想而抵抗黑客入侵的最好办法就是克服软件编程中存在的各种漏洞让黑客无机可乘通过源码审计漏洞跟蹤等方式可以较好的修正现存系统中的各种安全隐患目前我们正在达梦数据库中积极开展漏洞发掘的相关工作努力使达梦数据库成为真正牢不可破的数据库为国家的信息安全构筑坚强的基石