黄惠烽
(四川民族学院 图书馆,四川 康定 626001)
图书馆局域网缓冲区溢出漏洞原理分析
黄惠烽
(四川民族学院 图书馆,四川 康定 626001)
随着数字图书馆的发展,图书馆局域网的安全工作越来越受到大家的重视,近年出现的缓冲区溢出漏洞也成为了网络攻击中最常用、最典型的攻击漏洞.本文通过讲述缓冲区溢出漏洞的原理,介绍了预防缓冲区溢出漏洞的相关方法,使得图书馆局域网尽量避免缓冲区溢出漏洞的攻击.
局域网;缓冲区溢出漏洞;原理;预防
随着数字图书馆的不断发展,图书馆局域网的安全也越来越受到人们的重视,图书馆管理系统中的读者信息、图书借还信息、藏书目录和电子资源数据等信息都是图书馆的核心数据,一旦这些数据遭遇丢失或损坏将会严重影响图书馆各部门的工作,严重时将导致图书馆工作的瘫痪.因此图书馆局域网安全工作不容刻缓.
现在的很多操作系统和应用软件或多或少都存在着各种安全隐患,从UNIX到Microsoft操作系统无一例外,只不过是这些系统的漏洞被发现时间的早晚不同,对系统造成的危害程度不同而已.作为网络管理员应该熟悉这些漏洞,并掌握这些漏洞的原理还和补救方法.
因编程缺陷或程序设计语言中的问题造成的缓冲区溢出问题是一种广泛存在的安全漏洞,人们对缓冲区溢出的漏洞早已有所了解,这方面的漏洞在图书馆局域网中也是时有发生的,但是直到近几年,才引起了人们的重视,因此研究图书馆局域网中的缓冲区溢出漏洞非常必要.
缓冲区溢出英文叫Buffer overflow,它是一个非常危险而又常见的漏洞,它能在windows、Unix等操作系统存在,也可以在SQL sever、日历程序、计算器程序和游戏程序等应用软件中存在.1988年发生的Morris“蠕虫”事件就是利用缓冲区溢出漏洞的“杰作”之一,著名红色代码网络病毒是根据微软提供的因特网服务软件IIS4.0、5.0中的一个缓冲区溢出漏洞传播的.据统计,缓冲区溢出漏洞占了已确认漏洞的20%.这种漏洞被认为是输入验证漏洞的子集,输入验证漏洞则几乎占了已确认漏洞的50%.对于软件使用者来说,缓冲区溢出是最可怕的漏洞.它经常会引起网络蠕虫、有助于利用的能动性的工具和入侵尝试.但是,我们可以这样说,发生缓冲区溢出的基本都是那些结构比较差的软件程序产品,它们基本上都存在一些不足之处.那么什么是缓冲区溢出呢?缓冲区溢出为什么能产生这么大的危害呢?
缓冲区溢出顾名思义就是缓冲区太小,装不了足够多的数据,多出来的部分跑出来了.产生缓冲区溢出的主要原因是,当向一个有限的缓冲区拷贝了过长的字符串时,这将导致过长的字符串覆盖相邻的存储单元,从而引起程序运行失败,个别人甚至可以恶意利用这种漏洞去执行任意命令,取得系统的特权,从而进行系统的攻击和破坏.
我们需要知道什么是缓冲区,一般来说,缓冲区就是分配的一块存储空间,其中可以存储某种类型的文本或者数据.程序员利用缓冲区的一块或多块数据提供系统预先制定的空间.例如,用C语言编写程序时会经常用到缓冲区来存放用户输入的姓名,程序员必须首先判断姓名缓冲区要求有多少字符,该字段允许多少字符,或者用户在给定的字段可以敲多少下键,这称为字符缓冲区的大小.
一个程序通常由多个子程序(模块)组成,程序规模越大,模块就越多.当对一个程序编译以后,在内存中划分三种区域,分别存放程序代码区、数据区和堆栈区.其中程序中定义的各种变量和缓冲区存放在数据区,调用子程序的返回地址存放在堆栈区,当控制从子程序返回时,按照堆栈顶指示的地址返回到主控程序.
在利用C语言编写程序时一般要用到输入函数来获得用户输入的姓名.当用户试图将超过缓冲区能够处理的更多的姓名字符输入到缓冲区时,程序中如果没有缓冲区越界检查机制,当超长的字符串输入后,就会产生缓冲区的溢出.例如,如果程序员编写的程序中定义:char name[15],当输入超过15个字节长的字符串后,就会溢出字符缓冲区.
在C语言中它是假定了缓冲区的长度是足够的,所以数组是不进行边界检查的.但是实践中往往会出现特殊情况,当向局部变量拷贝了一个超过定义长度的字符串时,这时候其他的变量空间将会被超出的字符串所覆盖,这时变量就会出现异常情况.另一种情况下,由于超出的字符串覆盖了子程序的返回地址,子程序返回时便可能转向一个未知的地址,从而使程序发生错误.
让我们来看看另一个例子:
这个程序的函数明显有一个内存缓冲区编码错误.这个函数出现错误的主要原因,一是因为没有进行边界检查就复制了字符串,二是错误地使用了strcpy()而没有使用strncpy().所以运行这个程序就会产生段错误,strcpy()将*str的内容(lars[])复制到bf[]里,到在字符串中碰到一个空字符.显然,*s比 bf[]大得多,bf[]只有26个字节,而 *s有356个字节的内容.当程序执行到这个地方时,bf之后的堆栈中330个字节将会全被覆盖.当函数返回时,程序尝试读取返回地址的下一个指令,此时就会得到一个段错误.
在网络上最常见的是通过制造缓冲区溢出使程序运行一个用户shell,再通过shell执行其它命令.如果该程序属于root且有suid权限的话,攻击者就获得了一个有root权限的shell,可以对系统进行任意操作了.在执行溢出的电脑打开DOS(shell).只要很简单的一段程序:
只要到这里就获得shell了,再通过shell执行其它命令,黑客们可以激动地拥有了一台“肉鸡”,可以对这台电脑为所欲为了.
下面我们再来看一下缓冲区溢出漏洞的攻击过程:
首先对ROOT程序进行试探性攻击,然后执行类似exec(sh)的执行代码来获得具有root权限的shell.此步可再分二步走:a.植入一定的代码到程序中b.初始化内存和寄存器,使程序跳转到预定的程序中去.步骤如下:
(1)植入一定的代码到程序中.当攻击者输入一个字符串到被攻击程序时,这个字符串会被放到缓冲区里去.该字符串的相关信息就成为了可以运行的一些指令序列.在这个时候攻击代码就可以存放在被攻击程序的缓冲区中去.第二种是利用已经存在的代码.前提是攻击者想要的代码已经在被攻击的程序中了.这时候需要完成的任务是对代码参数的传递.
(2)使程序跳转到预定的程序中去方法.当程序没有通过缓冲区溢出检查时,就会产生一个相应的缓冲区,它会影响程序的执行顺序,使得程序跳转到一个未知的地址.
目前预防缓冲区溢出的方法有很多种,但是基本有三种基本方法:
(1)通过给操作系统添加补丁等办法,一旦某个漏洞被厂家的补丁程序修补了,那么针对该漏洞的攻击手段也将失效,这样缓冲区就不能执行,攻击代码就不能写入操作系统.
(2)编写程序时要使用正确的方法,避免所拷贝的字符串长度超过所定义的字符串长度,保证代码的正确性.
(3)通过编译器作为关卡,实现边界检查,这样可以实现保护缓冲区的目的,避免了缓冲区的溢出.
但是不管编写什么程序,做到没有错误是极其困难的,即使最仔细的复查通常也会遗漏其中一些错误.开发安全程序的最重要方法之一是最小化特权.那意味着程序的各个部分应该具有它们需要的唯一特权,一点也不能多.这样即使程序具有缺陷,也可能会避免将该缺陷转化为安全事故.
缓冲区溢出漏洞问题并不是一个新问题,许多常见的工具都容易受到缓冲区溢出的攻击.但入侵者需要很高的技巧才能实现缓冲区溢出的攻击.实际上也确实很少入侵者有高超的编程知识来做到这一点.为了防止系统不受到缓冲区溢出攻击,应该要求程序员在编程时,限制缓冲区的输入字符数,使它们不超过缓冲区的定义长度,这样就不会产生缓冲区溢出问题.
〔1〕Necula G C;Mc Peak S;Weimer W CCured:typesafe retrofitting of legacy code 2002.
〔2〕U Hermann Overview of pscan source package 2006.
〔3〕Z Lin;B Mao;L Xie LibsafeXP.A practical and transparent tool for run-time buffer over flow preventions 2006.
〔4〕Luk C;Cohn R;Muth R Pin:Building Customized Program Analysis Tools with Dynamic Instrumentation 2005.
〔5〕Taeho Oh.Advanced Buffer Overfiow Expioit [ EB/OL]。 http://postech.edu/ohhara,2004-09.
〔6〕Vendicator,StackShield:A stack smashing technique protection tool for Linux 2010.
〔7〕徐启杰.基于Win32平台的漏洞挖掘和漏洞利用技术研究[J].上海交通大学(学位论文),2007.
G250.73
A
1673-260X(2012)05-0131-02