缓冲区溢出
缓冲区溢出早已被承认为一个问题,在低层次的语言。 核心的问题是用户数据和程序流程控制信息交织,为求表现,以及低层次的语言,可以直接进入应用记忆体。 c和c + +是两个最流行的语言得了缓冲区溢出。 严格地说,一个缓冲器溢出发生程序当允许输入写年底以后所分配的缓冲区,但也有几个相关的问题,往往具有相同的效果。 其中最有趣的是,格式字符串漏洞。 另一个化身的问题发生时,攻击者可以写上任意位置记忆之外的一个数组中的应用,同时,严格来说,这不是一个典型的缓冲区溢出,我们将涵盖在此过。 的影响,一个缓冲器溢出的是什么,从撞车到攻击者完全控制用户的申请,如果申请运行作为一项高层次的用户(根,管理人,或本地系统) ,然后控制整个操作系统和任何其他用户正在登录,或将日志上,是在政府手中的攻击。 如果应用在一个问题是一个网络服务时,因该缺陷可能是一种蠕虫病毒。 首著名的网络蠕虫利用了一个缓冲区溢出,在手指服务器,被称为罗伯特莫里斯(或仅为莫里斯)手指的蠕虫病毒。 虽然它似乎好像越来学到如何避免缓冲区溢出,因为其中有近击落了因特网在1988年,我们继续看到的频繁报道缓冲区溢出,在许多类型的软件。 虽然有人可能会认为只有马虎,不小心程序员小心受骗缓冲区溢出,问题是复杂的,很多的解决办法,不是简单的,和任何人的书面足够炭/炭+ +代码已几乎肯定会作出这条老路。 即使是非常好,非常细心的程序员犯错误,和最好的程序员知道怎样可以很容易地是滑起来,并付诸坚实的测试方法,来捕捉错误。 受语言c是最常见的语言,用来建立缓冲区溢出,紧随其后的c + + 。 人们很容易造成缓冲区溢出时,以书面形式在汇编由于它没有任何安全保障可言。 虽然c + +中本来就是作为危险为c ,因为它是一个超集的c ,用标准模板库( stl )的照顾,可大大减少潜在的,以处理不当弦乐团。 增加的松紧程度c + +编译器将帮助程序员避免出现一些错误。 我们的意见是,即使你是写纯c代码,用c + +编译器将导致清洁守则。 最近发明了更高层次的抽象语言直接记忆体存取以外的程序员,一般都在大幅度的性能代价。 语言如java , c #和视觉基本有本土字符串类型,范围核对阵列,并普遍禁止直接记忆体存取。 虽然有些人会说,这使得缓冲区溢出不可能的,它的更准确的说,缓冲区溢出是不太可能。 在现实中,大多数这些语言是实施炭/炭+ + ,并执行漏洞,可导致缓冲区溢出。 另一个潜在来源缓冲区溢出,在更高水平的代码存在,是因为该守则,最终必须与一个操作系统,它的操作系统几乎肯定是写在炭/炭+ + 。 c #中,使您能够履行而不净申报不安全的路段;不过,虽然它提供了更容易的互操作性与底层操作系统和图书馆写在炭/炭+ + ,你可以作出同样的错误,你可以在炭/炭+ 。 如果你主要是程序在更高水平的语言,其主要项目为你的是,要继续以验证数据传递给外部库,或者,你可作为管道,以他们的缺点。 虽然,我们也不会提供一份详尽无遗的名单,受影响的语言,最年长的语言容易受到缓冲区溢出 罪恶解释经典的化身,一个缓冲区溢位的是被称为"砸栈"在编制计划,堆栈是用来进行控制信息,如论点,如果应用程序需要返回,一旦它用函数和,因为对极少数的正式选民登记册上提供的x86处理器,往往登记获得暂时存放于栈。 不幸的是,变数是本地分配,也存储在栈。 这些堆栈变量有时是不准确地称为正超静定分配,而非被动态分配的堆内存。 如果你能听到有人在谈论一个静态缓冲区溢位,他们真正的意思是一个堆栈缓冲区溢出。 问题的根源是,如果应用写道:超越界限的一个数组分配堆栈,攻击者愈是具体的控制信息。 这是成功的关键;攻击者想要修改控制数据,以价值观他的竞标。 有人可能会问,为什么我们继续采用这种显然是危险的制度。 我们本来有机会逃脱这个问题,至少有一部分是与迁移到英特尔的64位安腾芯片,而回复地址都存放在一个登记册。 但问题是,我们不得不容忍一个重要向后兼容的损失,截至记者截稿时,看来64位芯片,将有可能最终较受欢迎的筹码。 您也可能会问,为什么我们只是不全部迁移到代码进行严格检查阵列,并不允许直接记忆体存取。 问题是,对于许多类型的应用中,性能特点的更高水平的语言是不够的。 一个中间地带,是使用高级别语言,为高层的接口与危险的事物(如用户! ) ,和较低级别的语言为核心的代码。 另一种解决办法,就是充分利用的能力c + +中,并使用字符串图书馆和收藏班级。 举例来说,互联网信息服务器( iis ) 6.0网站伺服器开关完全居+弦乐班处理的投入,以及一名勇敢的开发商声称他i'd截他的小指,如果有任何缓冲区溢出被发现在他的代码。 为写本,发展仍然有他的指头,没有安全公告已经发出,对网络服务器,在近两年时间以来,其释放。 现代编译器处理好templatized班,是有可能写出相当高的高性能c + +代码。 足够的理论-让我们考虑一个例子: #包括<stdio.h> 无效dontdothis (烧焦*输入) strcpy ( buf ,输入) ; printf ( " % s \ n " , buf ) ; int ( int argc ,烧焦*定义argv [ ] ) 现在的编制应用,并采取看看会发生什么。 对于本次演示中,作者用了一个新闻稿,建立与调试符号,使和栈检查残疾人。 一个好的编译器,还需要在内嵌一个函数小dontdothis ,尤其是如果它仅仅是所谓的一次,所以他也残疾人优化。 这里的是什么栈看起来像对他的系统前夕呼吁strcpy : 0 x0012fec0的c8铁一二○○ èþ .. < -地址的b uf说法 记得所有的价值观强加给栈,是在倒退。 这个例子是由英特尔公司制度,这是"小的endian "这意味着至少有显著字节的价值至上,因此,如果你看到一个回邮地址,在记忆体作为" 3f104000 " ,它的真正地址0x0040103f 。 现在让我们看看会发生什么,当buf是被覆盖。 第一控制信息,对栈的内容是延长基地指针(时序)登记。 时序载帧指针,如果场外由一溢流情况下,时序性,将截断。 如果攻击者可以控制内存在0x0012fe00 (场外由一零出最后一个字节) ,该计划跳到该地点并执行攻击者提供的代码。 如果出现超支,不受制约的一个字节,下一个项目去,是回邮地址。 如果攻击者就可以控制这种价值,并能对地方不够大会变成一个缓冲区他们知道的位置,你正在寻求一个典型的可开采缓冲区溢出。 注意到大会码(通常被称为壳代码,因为最常见的就是利用援引指挥壳) ,并不须要放在进入缓冲区,这被覆盖。 它的经典案例,但总体而言,任意代码,攻击者已放置到你的节目可设在其他地方。 不采取任何安慰,以为这样超支,是局限在一个很小的范围。 一旦返回地址已被覆盖,攻击者愈玩论点的可开发的功能。 如果程序写入任何的这些论点,然后再返回,它代表了一个机会,让更多的混乱局面。 这一点变得很重要,当考虑的成效栈篡改对策,如克里斯cowan的卫士, ibm的propolice ,以及微软的/ gs的编译器旗。 大家可以看到,我们刚刚经历了由于攻击者至少有三种方式,以控制我们的应用,这是只有在一个很简单的功能。 如果一个c + +类与虚拟的职能是宣布对栈,然后虚拟函数指针表,将现有的,而这很容易导致功勋。 如果其中一个论据,以功能刚巧是一个函数指针,这是相当普遍,在任何窗口系统(例如, x窗口系统或微软视窗) ,然后覆盖的函数指针,以便在使用前,是一个明显的方式来转移控制该项目的申请。 许多,许多更聪明的方式来抓住控制的一个应用存在比我们的软弱大脑能想到的。 还有一个失衡的自己的能力,作为开发商和能力和资源的攻击。 你不容许无限多的时间来写你的申请,但攻击者可能没有什么都做,与他们有大量的空闲时间,比想出如何使你的代码,做他们想做的。 你的代码可以保护资产的宝贵足够的理由,几个月来的心血,以颠覆你的申请。 攻击者花费了大量的时间学习最新的发展造成破坏,并有资源,如www.metasploit.com那里,他们可以点和点击途中壳代码,但这几乎任何他们想要同时运行在一个受限字符集。 只要你尝试,以确定是否有可开采的是,它极有可能你会得到错误的。 在大多数情况下,这是唯一可能的证明,甚至是被利用的,或者你是不是足够聪明(或者可能没有花足够的时间) ,以确定如何写一个剥削。 这是极为罕见的能够证明与任何信心,在所有超支不开采。 提出此项谩骂,是聪明的做法,就是以刚修理臭虫! 已多次表示, "代码质量的改善"最终被证明安全补丁回想起来。 笔者只花了3个多小时争论的一个开发团队是否应该定一个bug 。 电子邮件线程进行了共八人这件事时,我们很容易用了20个小时(其中半数的人-周)在辩论是否应该解决问题,或者是不是因为开发团队想要证明代码被剥削。 一旦安全专家证实这个bug真的是一个问题,解决问题,估计在一个小时的时间,开发商和几个小时的测试时间。 这是一个令人难以置信的是浪费时间。 一时间,当你不想被解析是立即付运前提出申请。 如果申请是在最后阶段,你想能够创造出一个良好的猜测有关问题是否是可开采的理由风险的回归分析和不稳定的产品。 这是一个常见的误解,以为超支堆缓冲区不足可开采超过栈超支,但这一结果并非如此。 最堆的实现受到同等的基本缺陷,因为栈-用户数据和控制数据交织。 视执行内存分配表,它往往能够得到一堆经理人的地方, 4个字节的攻击者的选择,到指定地点由攻击者。 详情如何攻击一堆有点难懂。 最近一项,并明确书面发表主题演讲, "可靠的窗口堆功勋, "马修"休克" conover & oded手机,可在http://cansecwest.com/ csw04/csw04-oded + connover.ppt 。 即使一堆经理不能颠倒做攻击者的竞标中,数据在毗邻的拨款可能含有函数指针,或指针将用来写入资料。 在同一时间,利用堆溢出被认为是异国情调和硬堆溢出,现在一些较为频繁类型的剥削错误。 那双充满戾气的炭 /炭+ 还有很多,很多方法超支缓冲炭/炭+ + 。 这里的到底是如何造成的手指莫里斯蠕虫: 煤焦buf [ 20 ] ; 获得( buf ) ; 是绝对不存在的方法,可使用愈读投入,从stdin没有冒一个溢出的缓冲区使用fgets代替。 也许是第二个最受欢迎的方式溢出的缓冲区,是用strcpy (见前面的例子) 。 这是另一种方式带来了一些问题: 煤焦buf [ 20 ] ; strcpy ( buf ,前缀) ; 煤焦buf [ max_path ] ; sprintf ( buf , " % s -% d \ n " ,径, e rrno) ; 这几乎是不可能的,除了在少数几个角落的情况下,使用sprintf平安。 一个危急安全公告微软视窗被释放,因为sprintf是用在调试测井功能。 参阅安全公告011更多信息(见环节,在"其他资源"一节) 。 这里的另一个最爱: 煤焦buf 〔 32 〕 ; 另一种方式带来了一些问题,是错把字符计数字节计数。 如果你处理ascii字符,这些都是一样的,但是,如果你处理unicode的,有两个字节,以一个字。 这里的一个例子: _ snwprintf ( wbuf , sizeof ( wbuf ) , " % s \ n " ,输入) ; bool copystructs ( inputfile * pinfile ,无符号长计数) m_pstructs =新structs [计数] ; (一= 0 ; i <计数;一+ + ) ptr =的malloc ( sizeof (类型) *计数) ; 这里的另一种方式,一个缓冲器溢出可以创造: #界定max_buf 256 时限= strlen (输入) ; / /当然,我们可以用strcpy平安 const size_t max_buf = 256 ; 时限= strlen (输入) ; / /当然,我们可以用strcpy平安 相关罪孽 一个密切相关的单整数溢出。 如果你做的选择,以减轻缓冲区溢出用计数字符串处理来电中,或正设法确定有多少空间分配上的霸主地位,算术变得至关重要,以提供安全的应用。 格式字符串漏洞能够被用来完成同样的效果作为一个缓冲区溢出,但并不真正超支。 格式字符串漏洞通常是在没有超越任何缓冲可言。 一个变一个缓冲区溢出是一个无限写信给一个数组。 如果攻击者可以供应指数你的阵列,你不正确验证不管是内部的正确方向的阵列,有针对性写信给一个内存位置的攻击者的选择会演出。 这不仅可以全部相同挪用节目流发生,而且攻击者可能没有打乱相邻记忆,这妨碍任何因应对策,你也可能在地方,对缓冲区溢出。 发现单模式这里是组成以寻找:
检举这期间,单代码审查,由被很容易会非常困难。 该容易的事情做起,以寻找有使用不安全的字符串处理功能。 一个问题应该意识到的是,你可以找出许多事例中的安全使用,但它一直是我们的经验,有问题隐藏其中正确的来电。 转换代码仅使用安全要求有一个非常低的回归率(随时随地从十分之一到1/100th的正常千年虫定回归率) ,这将消除功勋,从你的代码。 其中一个好方法,这样做是为了让编译器找到危险功能调用给你。 如果您未定义strcpy , strcat , sprintf ,而类似的功能,编译器会发现他们都是为你。 是一个问题必须明白的是,有些应用程序已重新实行全部或部分的c运行时间库内部。 更艰巨的任务是寻找堆超支。 基本上,你想先看看拨款,然后再审查算术来计算缓冲区大小。 整体最好的办法是追踪使用者输入的入职起薪点你的申请通过所有功能调用。 正在意识到事情的攻击者控制,使大的差别 测试技术,以找出单模糊测试,其中科目你的申请,以半随机投入,是一个更好的测试技术使用。 尽量增加长度的输入串,同时遵守行为的亚洲浆纸。 东西看出来的是,有时错配的输入检查,将结果在相对较小的窗户脆弱的代码。 举例说,有人可能会提出一个检查,在一个地方投入必须不少于260字,然后再拨出256字节的缓冲区。 如果你测试一个很长的输入,它会简单地予以拒绝,但如果你击中溢流正是,你可以找到一个剥削。 长度是倍数两年的倍数两个正负人会经常发现问题。 其他方法试图寻找任何地方,在那里输入长度的东西,是用户指定的。 改变长度,所以它不匹配的长度字符串,尤其是寻找整数溢出的可能性,条件,而长度+ 1 = 0往往是危险的。 这是你应该做的时候,模糊测试就是要创造一个专门测试兴建。 调试建立经常声称,改变程序流程,并会随时向你打从开采条件。 另一方面,关于调试是建立在现代编译器通常都载有更先进的栈腐败侦查。 视乎你的堆和操作系统,你也可以让更多的严格堆腐败检查工作。 一个变化是,你可能想使你的代码是,如果一个断言是检查用户输入的,改变后,从 断言(时限< max_path ) ; 至 如果(时限> = max_path ) 你应该总是测试你的代码,根据某种形式的内存错误检测工具,如appverifier对视窗 例如捷联惯导系统以下条目,其中直接来自共同的脆弱性和风险的名单,或cve的( http://cve.mitre.org ) ,并有实例的缓冲区溢出。 一个有趣的一点琐事,是因为写本, 1734 cve的作品,那场比赛的"缓冲区溢出"的存在。 搜索证书警告,其中记载只有更广泛和更严重的漏洞,产量107点击"缓冲区溢出" cve的- 1999年至0042年从cve的描述: "缓冲区溢出,在华盛顿大学的执行imap和流行服务器。 " 这cve的条目,是彻底地记录在证书的咨询钙1997年至1909年,并参与了一个缓冲器溢出,在认证序列的华盛顿大学的邮局协议(流行音乐)和互联网信息接入协议( imap )服务器。 一个相关的漏洞是,该电子邮件服务器没有得到有效落实,至少特权,并利用发放根获得袭击者。 溢出导致广泛的开发易受攻击的系统中。 网络脆弱性检查,旨在寻找弱势版本的这个服务器也发现了类似的漏洞在西雅图实验室slmail 2.5作为报告,在www.winnetmag.com/article/articleid/9223/9223.html 。 cve的- 2000年至0389年- cve的- 2000年至0392年从cve的- 2000年至0389年: "缓冲区溢出krb_rd_req功能kerberos的第4和第5 ,让远程攻击者获得root权限。 " 从cve的- 2000年至0390年: "缓冲区溢出krb425_conv_principal功能kerberos的5款允许远程攻击者获得root权限。 " 从cve的- 2000年至0391年: "缓冲区溢出krshd在kerberos的5款允许远程攻击者获得root权限。 " 从cve的- 2000年至0392年: "缓冲区溢出ksu在kerberos的5款允许本地用户获得root权限。 " 这一连串的问题,在美国麻省理工学院的执行kerberos是文档证书咨询钙- 2000 - 06 ,发现在www.cert.org/advisories/ca-2000-06.html 。虽然源代码已经提供给市民几年来,这个问题源于使用危险的字符串处理函数( strcat ) ,也只是在2000年的报告。 cve的- 2002年至0842年, cve的- 2003年至0095年,可以- 2003年至0096年
这些漏洞记录在证书的咨询钙- 2003 - 05 ,位于www.cert.org/advisories/ca-2003-05.html 。问题是一个定数,发现大卫litchfield称和他的团队在下一代安全软件有限公司作为旁白,这体现了广告人的申请列为"牢不可破" ,未必是最好的事,而先生litchfield称正在调查你的申请。 灿2003年至0352年
这溢流有趣的是,因为它导致了普遍的剥削,有两个很具破坏性的蠕虫,都造成了重大的破坏在互联网上。 溢流是在一堆,事实证明,这是不可能建立的蠕虫病毒,是很稳定。 一个因素是一个失败的原则,最小权限:接口不应该被提供给匿名用户。 另一个有趣的注意的是,溢流对策视窗2003年退化攻击升级特权拒绝服务攻击。 更多信息,对这个问题就可以找到www.cert.org/advisories/钙- 2003 23.html , www.microsoft.com/technet/security/bulletin/ms03-039.asp 赎回步骤道路,以缓冲区溢出赎回仍是漫长而充满坑洞。 我们讨论各种各样的技术,帮助您避免缓冲区溢出,和其他一些技术,减少损害缓冲区溢出可引起。 先来看看你怎样才能改善你的代码。 取代危险的字符串处理函数你应该,至少,取代不安全的功能,如strcpy , strcat和sprintf与计数版本,每一个这些功能。 你有多项选择的是什么,以取代他们。 一定要记住,老年人计数功能的界面问题,并要求你做算术,在很多情况下,以确定参数。 电脑是没有那么好,在数学,因为你可能希望。 较新的图书馆一样, strsafe ,外管局显像管(三运行时间库)的出货量将在微软的visual studio (并且是一个快速的轨道,成为部分ansi的炭/炭+标准) ,和strlcat / strlcpy为* nix中。 你也需要照顾,如何与上述各职能处理终止和截断的弦乐团。 部分职能,保证无效终止,但大多数的老年人计数功能,没有这样的规定。 微软office集团的经验与更换不安全的字符串处理函数,该办公室在2003年发布的是,回归率(新的缺陷所造成的每修理) ,是非常低,所以不要让恐惧的回归图阻止你。 审核拨款另一名消息人士的缓冲区溢出来自于算术错误。 检查环路和阵列通道第三种方式缓冲区溢出造成的,是不妥当检查终止循环中,并没有妥善检查数组界限之前写访问。 这是一个最困难的地区,你会发现,在某些情况下,这一问题与地球防碎-排行榜是在完全不同的模块。 取代c字符串缓冲器与c +弦乐团这是更有效的不仅仅是取代通常的c通话,而且可以造成巨大的变化,在现有的代码,特别是如果代码是不是已经汇编为c + + 。 你也应该知道和了解性能特点的stl的集装箱班。 这是非常有可能通过编写,性能高的stl代码,但像许多其他方面的编程,不读优良手册( rtfm )往往会导致在不到最佳的效果。 最常见的替换是使用stl的性病: :字符串或性病: wstring模板类。 取代静态数组的stl容器所有的问题如上所述适用stl的容器如向量,但另外一个问题是,并不是所有实施的载体: : iterator建构检查出界进入。 这项措施可以帮助,作者发现使用的stl使得有可能为他写正确的代码更迅速,但也知道这是不是一个银弹。 使用分析工具有一些很好的工具来对市场进行分析的炭/炭+ +代码安全缺陷;例子包括coverity的, prefast , klocwork 。 视觉工作室。净, 2005年将包括prefast和另一项工具所谓源代码注释语言(萨尔) ,以协助缉捕安全缺陷,例如缓冲区溢出。 最好的方法来描述萨尔是透过代码。 在(傻)的例子如下,你就会知道之间的关系数据和计数的论点:数据是count字节长。 但是编译器不知道;它只是看到烧焦*及size_t 。 无效* dostuff (烧焦*数据, size_t计数) ( 这个代码看起来好(根本无视事实,我们并不愿意返回静态缓冲区,但幽默美) 。 但是,如果指望,是要大32 ,那么,你是否有缓冲区溢出。 一萨尔注明版本,这将赶上这个bug : 无效* dostuff ( __in_ecount (计数)烧焦*数据, size_t计数) ( 考虑额外的防御性措施,以同样的方式,您认为安全带,在你的车。 安全带往往会减少的严重性撞车,但你仍然不想介入到一起意外事故。 它的重要地注意到,为每一个主要类缓冲区溢出减灾,以前可开发的条件已不再是可开发,在所有存在;并为任何特定的缓解技术,有足够复杂的突袭,才能克服技术完全。 先来看看几个人。 Stack ProtectionStack protection was pioneered by Crispin Cowan in his Stackguard product, and was independently implemented by Microsoft as the /GS compiler switch. At its most basic, stack protection places a value known as a canary on the stack between the local variables and the return address. Newer implementations may also re-order variables for increased effectiveness. The advantage of this approach is that it is cheap, has minimal performance overhead, and has the additional benefit of making debugging stack corruption bugs easier. Another example is ProPolice, a Gnu Compiler Collection (GCC) extension created by IBM. Any current product should utilize stack protection. You should be aware that stack protection can be overcome by a variety of techniques. If a virtual function pointer table is overwritten and the function is called prior to return from the function—virtual destructors are good candidates—then the exploit will occur before stack protection can come into play. Non-executable Stack and HeapThis countermeasure offers considerable protection against an attacker, but it can have a significant application compatibility impact. Some applications legitimately compile and execute code on the fly, such as many applications written in Java and C#. It’s also important to note that if the attacker can cause your application to fall prey to a return into libc attack, where a legitimate function call is made to accomplish nefarious ends, then the execute protection on the memory page may be removed. Unfortunately, most of the hardware currently available is unable to support this option, and support varies with CPU-type, operating system, and operating system version as well. As a result, you cannot count on this protection being present in the field, but you must test with it enabled to ensure that your application is compatible with a non-executable stack and heap, by running your application on hardware that supports hardware protection, and the target operating system set to use the protection. For example, if you are targeting Windows XP, then make sure you run all your tests on a Windows XP SP2 computer using an AMD Athlon 64 FX processor. On Windows, this technology is called Data Execution Protection (DEP); it was once known as No eXecute (NX). Windows Server 2003 SP1 also supports this capability. PaX for Linux and OpenBSD also support non-executable memory Other Resources
this is an article added by Hendra Fang
|
|||
|