服务器的数据库泄漏泄漏是怎么回事?

软件调试(7)
我们监控平台有台报警服务器,其主要功能是接收前端,TDDC,网管服务器等发送的报警,并依据报警联动配置进行相应的联动操作,最近发现在该服务器运行过程中,通过任务管理器查看其句柄数量会不断增加,以至于影响其他服务器工作,初步怀疑是句柄泄露问题,现对其进行分析排查。
句柄是Windows用来标识应用程序所建立或使用的对象的唯一整数,Windows的内核对象包括进线程,窗口,位图,GDI对象等等。应用程序通过句柄访问内核对象,当使用完内核对象之后需要释放资源关闭该内核对象句柄,如果未能正确关闭,则会造成句柄泄露。
一般而言,如果怀疑发生了句柄泄露,最首要任务是查找泄露的句柄类型,这样有助于后面的排查分析,缩小目标范围。这时可以通过一些辅助工具来帮助分析,如Process Explorer,PCHunter等,这些工具能够非常明了的看到进程所正在使用的内核对象,可以帮助我们找到问题所在。
打开Process Explorer,找到运行的报警服务器进程,该工具的会显示出报警服务器当前创建的内核对象句柄,如图,可以看出该进程的句柄数已经有上千个,而且还在快速增长中。
该工具很方便的一点是,当有新的内核对象创建时,在下方的列表框中会以绿色标识出来,方便查看,观察一段时间发现,不停的有线程对象创建,而且不会关闭,初步猜测应该是线程对象的句柄没有关闭导致。接下来的工作就是要找出这个线程内核对象在哪儿创建的。
查找句柄的创建位置的可以通过windbg来获取,windbg是windows下一款非常强大的内核调试器。使用Windbg的!htrace命令可以调试句柄泄露。其原理比较简单,就是分别为进程的内核对象做两次快照,比较这两次的不同,就可以知道有哪些内核对象创建了,同时还能找到是在哪儿分配的。
打开windbg,按F6,附加报警服务器进程。在命令行里面输入!htrace–enable开启htrace功能。输入!htrace
–snapshot做第一个快照,然后输入g命令,让程序执行一段时间。
该过程如下图所示:
程序运行一段时间后,按Ctrl+Break键,将程序中断下来。这时输入!handle –diff,可以比较新增句柄的分配上下文。
通过仔细观察,可以看出,有创建了多个线程内核对象,查看一个内核对象的信息可以使用!handle命令。例如查看handle值为f98的线程内核对象,可输入!handlef98
ff。如下图所示
其起始地址为HPR_GetNetWorkFlowData,可以确定该线程是使用HPR库创建的,可以通过在源代码中查找HPR_Thread_Create来缩小范围。
再图中还可以看到线程ID为7670.fef4,其中7670为进程ID,fef4是线程ID,因此可以切换到该线程看看,输入
~~[fef4]s命令,切换线程。
出现了一条错误信息,即该线程已经不存在了,那其实我们就基本可以确定这里发生了泄露,线程已经不复存在,但该线程的内核对象却未能关闭。
通过仔细观察,我们可以看到这些线程对象都是同一个线程创建的,如图
最终都指向了71a8这个线程,这样我们可以确定是71a8这个线程创建了很多线程内核对象,却没有将内核对象的句柄关闭,这样造成了线程内核对象的句柄泄露,只要定位到71a8这个线程,就能找到泄露的地方。
输入~~[71a8]s,切换到这个线程,并输入kb打印其调用栈,如下图:
调用栈是一堆非常奇怪的数据,其实是因为我的系统是64位的,而报警服务器这个进程是32位的,windbg使用64位的上下文去解析32位的进程,造成了错误的解析。这时可以通过!sw这条命令来切换至32位的上下文。然后再敲入kb命令,就能看到该线程的调用栈了,如图:
可以清楚的看到该线程的调用栈,此时该线程正在等待socket连接,使用的是HPR库的HPR_Accept函数,到这个地步,在源代码中定位该线程函数就非常容易了。
在源代码中搜索HPR_Accept函数,只有一个地方:
可以清楚的看到,这个线程接受到连接之后,就创建了一个线程,不过却未将创建线程的句柄关闭,从而造成了句柄泄露,这与我们之前分析的一致。知道了问题所在,修改也就很方便了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:33071次
排名:千里之外
原创:21篇
转载:19篇
评论:12条
(1)(3)(2)(3)(4)(7)(2)(5)(3)(1)(1)(6)(3)知乎服务器出现故障 用户账号信息或遭泄露|界面新闻o科技9月7日下午,知乎出现了严重的&串号&现象&&用户在正常登陆知乎以后,发现登陆的并不是自己的账号,而用户可以完全看到陌生账号的所有信息、回答,甚至匿名回答。而当用户马上重新登录以后,系统仍未显示正确的个人信息,用户则又进入了另外一个陌生人的账户。
对此,知乎采取了一些紧急措施,串号的情况不再出现,但是在个人主页出现了一行代码报错,用户无法继续对软件进行任何操作。随后不久,知乎App在iOS端已无法访问。
可以说,这是一次非常严重的事故。
而知乎粗暴的处理方式招致了用户不满,也让外界怀疑知乎没有数据库备份。因为如果备份,在这种突发情况下,可以直接切换到备份服务器,不必用切断服务器的方法应急。
对此,知乎官方18:00左右发出了公告,说明故障原因是&所使用的第三方防火墙产品进行了内部变更&,并称已经&临时调整了第三方防火墙策略。 在反复测试和筛查后,移动端服务正在逐步恢复。&
串号问题无独有偶,新浪微博也出现过类似情况。导致此类问题的原因可能是内部错误操作,也可能是外部攻击,而前者的可能性似乎更大。
目前,尚没有知乎用户表明此次事故给自己造成了比较严重的影响, 知乎在官方回复中也表示&目前没有迹象表明,知友发布的内容遭到篡改&。
但愿如此。
更多精彩新闻,更多专业报道,请前往各大App应用商店搜索下载&界面新闻&,或
0界面记者相关文章您至少需输入5个字评论()CSDN数据库泄露!那些网站够安全吗? | 科学人 | 果壳网 科技有意思
CSDN数据库泄露!那些网站够安全吗?
网络密码被盗怎么办?
本文作者:sqybi
,近 600 万用户真实账号密码外泄。该事件横扫整个中文互联网,并且随后又爆出
,另有传言人人网、开心网、天涯社区、世纪佳缘、百合网等社区都有可能成为黑客下一个目标。一时间人人自危,更换密码者无数。
这到底是怎么回事?用户信息是如何泄漏的?为什么一瞬间就有这么多密码被轻易获取,而一般的网站又是如何保护用户密码的?黑客和网站管理者之间,展开过怎样的密码攻防战?死理性派就此做了一番详细的介绍。
黑客的目标:你的密码存在哪儿?
很多人对这次事件都有一个疑问:网站把我的密码存在哪?
对于大部分网站,密码的存储和验证过程简单来说就是:用户输入密码,密码被传输到服务器,服务器将密码存储起来(注册)或和已经存储的密码比对(登录)。不论在哪个步骤,都有可能遭到黑客的攻击和入侵。本次事件的数据库泄露,就和第 3 个步骤相关。
一般来说,每个网站都有一个或多个专门存储密码的数据库。这些数据库通常并不能下载到。那黑客们是如何得到数据库的呢?
比较技术的方法是通过一些服务器返回的错误信息推断数据库的位置,例如“%5c大法”。它的原理是,故意进行一个错误的数据库访问,从错误信息中获取数据库真实地址,再通过这个地址下载数据库。但修补这个漏洞的方法也很简单,只要更改一下数据库出错时返回的错误信息就可以了。
有经验的软件管理员自然会对这种技术手段有所防范。但密码泄漏的途径其实不像想象中的那么“技术”:可能某个辞职员工偷偷带走了数据库;可能某台存储数据库的服务器染上了病毒;可能有人偷偷潜入了机房拷贝走了数据……总之,黑客会通过各种可能的手段获得存有用户名和密码的数据库,数据库泄露的危险总是存在的。
图片来源:XKCD
道高一尺:加密让数据库更安全
数据库总有被黑客攻击的危险,那网站如何应对?众所周知,在本次事件当中,被泄露的 CSDN 数据库,用的是明文储存密码。顾名思义,明文密码就是直接将用户输入的密码存到数据库中。这种方式的安全性不言自明。
既然明文密码太危险,那不妨用加密密码。但怎么加密呢?这就要说到大名鼎鼎的哈希函数了。
哈希是一种从从多到一对应的函数,它的作用是将一个很大的集合映射到一个很小的集合。例如,我们可以设计一个哈希函数 h(x) = x % 100 (其中 % 表示取余数,如 4 % 3 = 1,8 % 2 = 0),这样我们就把所有的整数 x 映射到了一个 0 到 99 的有限集合中。而像 MD5 和 SHA-1 这些著名的算法,都是哈希函数。当然,和前面这个 h(x) 不同,它们的计算方法非常复杂,常常需要经过很多轮计算。
哈希一个很重要的作用是帮助查找。很容易看到,如果两个数 x 1 和 x 2 对应的哈希值 h( x 1 ) 和 h( x 2 ) 不相等,那么 x 1 和 x 2 也一定不相等。这样一来,我们就可以用两个对象的哈希值进行过滤。因为哈希值的集合比原始值的集合更小,所以比较哈希值的速度是很快的。
典型的哈希算法。 图片来源:维基百科
而这个想法,也被应用于密码的保护上。实际上,无论是避免数据库泄露后的危险,还是出于对用户隐私保护的需要,现在大部分网站数据库存储的密码都不是明文,而是用户密码的哈希值,也就是所谓的加密密码。如果输入了一个错误的密码,它的哈希值就会有很大可能性与正确密码的哈希值不同,那么用哈希值代替密码进行比较也没有什么问题。另外,哈希的作用是将一个大集合映射到一个小集合,所以它的结果一定是不可逆的(因为从小集合到大集合的映射是一对多的映射)。这种不可逆性,使得理论上从哈希值找出原始密码成了一个不可能的任务,从而保护了密码。
但是,也会出现这种情况:两个不同的原始密码,它们的哈希值一样。这在密码学上被称作“碰撞”。碰撞是一个设计良好的哈希函数需要极力避免的,正因为如此,很多哈希函数的运算结果都很长,例如知名的 MD5 算法,它的运算结果包括了 128 位二进制数。试想一下,如果使用之前提到的哈希函数 h(x) = x % 100,随便输入一个密码,就有 1/100 的可能性验证通过,那还了得!好在现在流行的哈希函数,在这一点上做的还都还不错。
魔高一丈:哈希不是万能的
前面提到,哈希是不可逆的。那么使用哈希存储的密码,真的就安全了吗?如果你当真这么认为,那黑客就要在一旁偷偷地笑了——非也,非也!
事实上,即使数据库中的密码经过了哈希函数的加密,数据库泄露之后也会有很大的危险,尤其是当使用的哈希算法还是 MD5 和 SHA-1 这种已经流行很多年的“大众脸”时。确实,哈希本身并不可逆,但要注意的是,黑客并没多少兴趣知道原始密码:因为服务器验证密码时不需要原始密码。只要找到一个和数据库里存储的哈希值相同的密码,就可以用它轻松通过验证,这正是前面提到哈希函数要尽力避免碰撞的原因。
通常黑客手中,都会有一份很长的列表,称为“碰撞库”。碰撞库里存储的,是很多常用密码对应的各种哈希值。这里的“常用”,并不单单是指 “” 这种“烂大街”的密码——事实上,任何不够长、只含字母或数字的类似于 “iloveyou” 这种由简单单词组成的密码,都可能出现在碰撞库中,现在黑客们生成的碰撞库的规模早已超出我们的想象。对于大部分常用密码,只要把泄漏出的哈希值放到碰撞库中比对一下,就可以找到一个产生碰撞的密码。
而滑稽的是,哈希算法极力要避免的碰撞在这里又给了黑客很大的方便:因为碰撞几率极低,如果一个哈希值存在于碰撞库里,那基本就可以确定库中对应的碰撞密码正是经过哈希加密前的真实密码!因此,那些用户名密码在各个网站都一成不变的用户们就悲剧了。
并非束手无策:猜不出的哈希算法
即便如此,网站管理员也并非束手无策。黑客可以用列表来破解哈希后的密码,很大程度上是因为加密时使用的哈希算法是公开的。如果黑客不知道加密的哈希算法是什么,那他也就无从下手了。
一个直接的解决办法是,自己设计一个哈希算法。然而,一个好的哈希算法是很难设计的——既要避免碰撞,又不能有明显的规律,做到这两点要比想象中的要困难很多。因此实际应用中更多的是利用已有的哈希算法进行多次哈希。
但是单纯的多次哈希,依然阻挡不住黑客。两次 MD5、三次 MD5之类的方法,我们能想到,黑客自然也能想到。特别是对于一些开源代码,这样哈希更是相当于直接把算法告诉了黑客。
没有攻不破的盾,但也没有折不断的矛。现在安全性比较好的网站,都会用一种叫做“加盐”的方式来存储密码,也就是常说的 “salt”。他们通常的做法是,先将用户输入的密码进行一次MD5(或其它哈希算法)加密;将得到的 MD5 值前后加上一些只有管理员自己知道的随机串,再进行一次 MD5 加密。这个随机串中可以包括某些固定的串,也可以包括用户名(用来保证每个用户加密使用的密钥都不一样)。举个例子:
用户名:sqybi
进行第一次 MD5,得到:25d55ad283aa400af464c76d713c07ad
指定两个 salt: salt1 = @#$%
salt2 = ^&*()
salt1+用户名+salt2+MD5,得到:@#$%sqybi^&*()25d55ad283aa400af464c76d713c07ad
对新字符串再计算一次 MD5,得到最终的加密串:7edfee82ab9b6f5aa50edbc3a9eb6507
在两个 salt 没有泄露的情况下,黑客如果拿到的是最后这个加密串,就几乎不可能推算出原始的密码是什么了。
最后的安全攻防:数据库泄露之外的危险
但是,即使有这种安全的密码存储方式,也不能太掉以轻心。在文章的一开始我们就说过,密码的存储和验证有三个步骤,每个步骤都有可能被黑客趁虚而入,数据库泄露只不过是其中的一个罢了。
在用户输入密码这个步骤,黑客可以通过植入木马等方式直接监视用户的键盘操作;在密码被传输到服务器这个步骤,黑客可以设法截获数据包分析其中包含的密码。而即使数据库有“加盐”,设置过于简单的密码也不是好选择——salt的值也不是没有泄露的可能!
要说的是,无论对于用户还是网站管理员,有良好的安全习惯才是最好的防御手段。用户应经常查毒,了解每个系统进程的作用,让木马没有藏身之处;网站管理员可以通过提供https连接或者在本地对密码进行首次加密再传输给服务器,避免数据包被截获;而经常更换密码,重要的账号不重复使用同一个密码,都可以在密码泄露的时候把损失降到最低。关于用户应当如何对待自己密码这个问题,死理性派的
有过全面而详细的介绍,强烈推荐大家一读。
总之,网络的时代想保护好自己的隐私,需要谨慎、谨慎再谨慎,养成良好的安全习惯,才是保护密码的最好方式。而至于网络安全要走的路,还有很长、很长……
参考资料:
相关阅读:
这几天你收到多少封“XXX提醒您注意密码安全”的邮件了?
你可能感兴趣
CSDN你累死我了。
计算机科学与工程专业本科生,口琴控,动漫迷
啊自己没抢到前排。。。
这次终于被坑爹了,居然直接明文密码
数学物理控
统计学专业本科生,数学控
CSDN啊。。。让人情何以堪???对你的仰慕之情瞬间消失!!!
软件工程师,小众软件爱好者
这几天你收到多少封“XXX提醒您注意密码安全”的邮件了?目前还木有
终于刷出来了
前排一下~~
软件工程师,小众软件爱好者
刚看到百度贴吧里的一个帖子百度真是人性化,把ID和密码一起打出来会自动和谐掉~1L 不信试试,我先试吧!潘晋诗 *********2LMe丶强强 密码 LZSB6L艺术de第3只手 8L艺术de第3只手 啊糟了!
的回应:这几天你收到多少封“XXX提醒您注意密码安全”的邮件了?目前还木有羊驼君的安保工作真是到位。。。膜拜。。。
果然看完就木有前排了??
的回应:刚看到百度贴吧里的一个帖子百度真是人性化,把ID和密码一起打出来会自动和谐掉~1L 不信试试,我先试吧!潘晋诗 *********2LMe丶强强 密码 LZSB6L艺术de第3只手 8L艺术de第3只手 啊糟了!我觉得这个明显应该去GEEK笑点低!
的回应:刚看到百度贴吧里的一个帖子百度真是人性化,把ID和密码一起打出来会自动和谐掉~1L 不信试试,我先试吧!潘晋诗 *********2LMe丶强强 密码 LZSB6L艺术de第3只手 8L艺术de第3只手 啊糟了!啊噗!!
Mathematica玩家
翻出这么篇文章……
有时候觉得死理性派很可爱。。但是作为一个文科生,不得不说,看到那一大段代码公式什么的真是头昏眼花啊啊啊
有机化学博士,法学学士
那个漫画又看了一遍,笑死了,有时候五块钱的扳手可能真的是更有效的方案……另外,对于Slat方式,能不能用这种方法去折腾:先去注册一个号,把密码设计的很简单,比如abcdefg,然后拿到加盐后的HASH值,多折腾几个就能推出Salt到底是什么了。
计算机科学与工程专业本科生,口琴控,动漫迷
的回应:有时候觉得死理性派很可爱。。但是作为一个文科生,不得不说,看到那一大段代码公式什么的真是头昏眼花啊啊啊我和吴师傅好冤枉啊。。。这篇文章明明就没有什么代码公式的嘛&.&
计算机科学与工程专业本科生,口琴控,动漫迷
的回应:那个漫画又看了一遍,笑死了,有时候五块钱的扳手可能真的是更有效的方案……另外,对于Slat方式,能不能用这种方法去折腾:先去注册一个号,把密码设计的很简单,比如abcdefg,然后拿到加盐后的HASH值,多折腾几个就能推出Salt到底是什么了。加盐的安全性就在于,你不知道盐加在哪里,加了多少……于是可能的组合是很难穷尽的……实际上如果源代码不公开,我个人感觉做100次MD5也挺安全……当然了,一旦salt泄露,什么都完了。。。
软件工程师,小众软件爱好者
的回应:那个漫画又看了一遍,笑死了,有时候五块钱的扳手可能真的是更有效的方案……另外,对于Slat方式,能不能用这种方法去折腾:先去注册一个号,把密码设计的很简单,比如abcdefg,然后拿到加盐后的HASH值,多折腾几个就能推出Salt到底是什么了。不太好推,就算差不多相同的两段文字HASH之后的密文也会天差地别,失去了比较意义。
计算机科学与工程专业本科生,口琴控,动漫迷
的回应:那个漫画又看了一遍,笑死了,有时候五块钱的扳手可能真的是更有效的方案……另外,对于Slat方式,能不能用这种方法去折腾:先去注册一个号,把密码设计的很简单,比如abcdefg,然后拿到加盐后的HASH值,多折腾几个就能推出Salt到底是什么了。顺带一提,为什么用户的密码就很容易被穷举出来而salt则不会?密码被穷举出来,大部分是因为设的太简单。如果你的密码是jdklajfkl!$!afdfaq&&&这种乱七八糟的形式,实际上除非你人品很差, 爆库的手段是不太可能获得你的密码的(当然碰到这种明文存储的,就什么都不要说了,自认倒霉吧……)。而salt因为没有记忆成本(大不了翻一下源代码就知道salt是什么了……),所以可以设的很复杂,再加上可以在每次md5的时候都salt一下,于是破解的复杂度就大大增高了……就是这样
有机化学博士,法学学士
的回应:顺带一提,为什么用户的密码就很容易被穷举出来而salt则不会?密码被穷举出来,大部分是因为设的太简单。如果你的密码是jdklajfkl!$!afdfaq&&&这种乱七八糟的形式,实际上除非你人品很差, 爆库的手段是不太可能获得你的密码的(当然碰到这种明文存储的,就什么都不要说了,自认倒霉吧……)。而salt因为没有记忆成本(大不了翻一下源代码就知道salt是什么了……),所以可以设的很复杂,再加上可以在每次md5的时候都salt一下,于是破解的复杂度就大大增高了……就是这样如此~忽然想起来,我在网上好多地方都用的是同一组密码,啊~开心网、果壳网、网易,你们千万别是用明文储存的密码呀!
土木工程硕士生
呐。。。想起了当年的网络基础。。。
计算机科学与工程专业本科生,口琴控,动漫迷
的回应:如此~忽然想起来,我在网上好多地方都用的是同一组密码,啊~开心网、果壳网、网易,你们千万别是用明文储存的密码呀!一般比较正规的网站应该都不会用明文存储密码。。。当然也仅限于不会用明文存储密码吧。。。
大气科学专业,气象万千小组管理员
这就是正反博弈吧…
计算机科学与工程专业本科生,口琴控,动漫迷
的回应:翻出这么篇文章……其实我还看到了这个
的回应:那个漫画又看了一遍,笑死了,有时候五块钱的扳手可能真的是更有效的方案……另外,对于Slat方式,能不能用这种方法去折腾:先去注册一个号,把密码设计的很简单,比如abcdefg,然后拿到加盐后的HASH值,多折腾几个就能推出Salt到底是什么了。目前的技术能力不能,hash的特性就是单向不可逆。现在的md5库只是人工把常用密码的md5都算出来。。。然后匹配然而在salt不知道的情况下,要把常用密码+复杂salt的各种md5组合算出来是不可能
显示所有评论
(C)2016果壳网&&&&京ICP证100430号&&&&京网文[-239号&&&&新出发京零字东150005号传言网易数据泄露?服务器有内存破坏漏洞?黑客常用漏洞利用方法和防御方法浅谈 - 点融网财富
传言网易数据泄露?服务器有内存破坏漏洞?黑客常用漏洞利用方法和防御方法浅谈
内存破坏漏洞(memory corruption bugs)攻击是指通过篡改内存中的控制流对象(如返回值,函数指针)或者数据流对象(验证变量,配置变量),从而执行恶意代码(如shellcode, rootkit)。常见的内存破坏漏洞包括缓冲区溢出漏洞,格式字符串漏洞,use-after-free漏洞。在互联网中,内存破坏漏洞攻击严重威胁web服务器(如apache, nginx),操作系统以及网络安全密码协议库(如openssl)的安全。
1内存破坏漏洞利用的方式
内存破坏漏洞利用的方式大致分为以下几种:
(1)恶意代码注入(code injection)。这种利用方式相对比较常见,比如利用缓冲区溢出注入shellcode, 并篡改返回值,从而执行shellcode。 恶意代码注入的方式往往有明显的特征,即需要额外引入shellcode, 而shellcode中常常需要包含系统调用或者库函数调用语句等明显的特征, 如shellcode经常使用execve(“/bin/sh”, 0)获得shell.
图1:常见的恶意代码注入的shellcode
图2:execve(“/bin/bash”, 0).
图3:混淆后的execve(“/bin/bash”,0)
(2)返回库函数(return-into-libc)。这种方式利用相对于恶意代码注入更加隐蔽。不需要在payload里填入shellcode, 而只要在payload中精心构造好函数的参数,并将控制流篡改到某个库函数入口(如system)即可。
图4:一个常见的return-into-libc的payload
注意对比图1与图4可见,返回库函数不需要引入shellcode, 只有padding, 库函数地址(0x),以及参数所在的地址(“/bin/sh”)。然而,受到库函数的功能限制和构造参数,return-into-libc虽然非常隐蔽,但是与shellcode相比功能有限。
(3)ROP(return oriented programming)。与return-into-libc代码复用思路类似,利用程序中已有的代码构造攻击。所不同的是,ROP使用的是已有代码中的指令片段(一般以ret结尾指令片段,一般3-10个指令长度,实际攻击中也有用到call/jmp结尾的指令片段)。
图5:一个常见的ROP的payload
这里,与代码注入,return-into-libc不同,关键是EIP所指。代码注入EIP指向shellcode, return-into-libc指向库函数入口,而ROP指向gadget1, gadget1是以ret结尾的指令片段:如xor eax, ret。 接着执行gadget2…gadget10等, 最终gadget10调用execve(“/binsh”,0) 获得shell.
以上是常见的三种内存破坏漏洞的利用方式。可以看到无论采用何种攻击方式,都需要篡改控制流对象(如篡改返回值)。为此,安全保护措施围绕着控制流对象保护进行,分别总结为编译器保护,库函数保护,系统保护以及控制流完整性保护。
2编译器保护
最著名的保护是StackGuard, 它已经被GNU GCC采纳,用户通过设置编译选项-fno-stack-protector, 可以为编译后的程序所有的返回值前增加一个canary(哨兵)。 由于一般缓冲区溢出是连续写内存,所以修改返回值必定修改哨兵,从而通过检查哨兵即可检测是否返回值被修改。不难想象,StackGuard只能起到一定缓解内存破坏漏洞攻击的作用,因为攻击者不仅可以通过溢出时不篡改canary(保持canary不变),而且可以直接修改未被保护的堆栈上的函数指针达到攻击目的。
为了防止函数指针被篡改,编译器补丁又出现了PointGuard, PointGuard由于性能问题,未被直接采纳进GCC中,但是它提供了一种保护思路,即将栈上的指针放在数组的上方(低地址),并对指针加密(加密由于需要指针分析,技术上也有许多不完善的地方,这是没有大规模使用的原因之一)。近期的ROP攻击由于大量使用了以ret结尾的指令片段,因此有人提出利用编译器将ret指令消除(Return-Less), 然而这种方法仅停留在研究阶段,未被工业界采用。
3库函数保护
库函数保护最著名的是LibSafe, LibSafe对库函数中如printf, sprintf等进行了参数审查,可以有效保护格式字符串等攻击。使用时只要使用LD_PRELOAD将libsafe替换原有的libc库即可。其他的库函数保护也可以采用这种方式。
最著名的系统保护包括ASLR(Address Space Layout Randomization)以及DEP(Data Execution Prevention)。ASLR已经被主流操作系统Linux (2.6.12以后), Windows (Vista以后), IOS(4.3以后), Android (Android 4.0) 采用。DEP 也被主流操作系统Linux (kernel 2.6.8以后) 以及Windows (Windows XP Service Pack以后) 采用。
ASLR的主要思想是对程序的段基址进行随机化(如栈和堆),这样即使攻击者可以通过漏洞注入代码或者数据,但是由于不能准确获得溢出代码或者数据的地址,因此不能利用注入的代码和数据完成攻击。
绕过ASLR的方法有很多种,最有效的方式是利用信息泄露,例如利用缓冲区溢出漏洞越界读内存,从而获得一些指令(jmp/call)的操作数或者数据/代码指针,由于这些指令和指针里包含了随机以后的内存地址,因此攻击者可以以此来计算出注入的代码或数据地址。
DEP的主要思想是对程序的堆栈进行保护,它不允许堆栈执行。由于一般的注入攻击都需要将shellcode写入栈或者堆,接着执行这些shellcode; 然而堆栈不可执行可以阻止shellcode的执行;当然DEP对另外两种攻击方法无效。
5从控制流完整性检查(Control Flow Integrity)
CFI 最早于2005年由微软研究院提出,其主要思想是通过程序分析,静态分析出每个控制流跳转语句 (jmp, ret, call) 的跳转目标集,在运行时检查每个控制流跳转是否超出跳转目标集。CFI由于受限于程序分析技术,主要是指针分析,精确的跳转目标集较难构造。而运行时对每个控制流跳转的检查开销非常大,因此未被工业界广泛采纳。不过近期一种轻量版的CFG(Control Flow Guard)技术受到青睐,与CFI不同,CFG防护方法需要在编译链接阶段来完成准备工作,同时需要操作系统的支持。
2015年微软推出的win10将CFG纳入安全保护系统,CFG需要编译器记录下间接调用信息(一般是call/ret),并把他们记录在最终的可执行文件中,并且在所有的间接调用之前插入额外的校验,当间接调用的地址被篡改时,会触发一个异常,由操作系统进行处理。
综上,互联网中内存破坏攻击的威胁非常大,由于存在大量的0-day漏洞,而100%的保护几乎是不可能。为了缓解受到攻击,建议互联网厂商在源码编译时使用StackGuard进行编译;动态库可以使用LibSafe进行保护;而操作系统方面打开ASLR以及DEP的保护。控制流完整性检查可以通过一些新的操作系统和编译器特性共同完成。
本文作者:陈平(),现任安全工程师,主要从事软件和系统漏洞,恶意代码分析以及防御工作。
随着新一轮融资,点融网即将开始大规模的扩张,需要各种优秀人才的加入,如果你觉得自己够优秀,欢迎加入我们!获取更多职位信息,请关注。
猜你喜欢:
上一篇: &&&&&&&&&&
不动产抵押}

我要回帖

更多关于 数据库泄漏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信