当前位置:首页 > 知识

远程溢出漏洞

2017年4月14日,远程溢出Shadow Brokers放出了“永恒之蓝”利用工具。漏洞一个月后,远程溢出WannaCry勒索病毒横扫全球,漏洞150个国家的远程溢出20多万台机器中招。英国NHS的漏洞医院系统瘫痪,医生只能拿纸笔记录病历。远程溢出这一切的漏洞源头,就是远程溢出一个远程溢出漏洞——MS17-010。

远程溢出漏洞的漏洞本质不复杂。程序接收网络数据时,远程溢出没有检查数据长度,漏洞直接塞进固定大小的远程溢出缓冲区。多出来的漏洞部分漫过边界,覆盖了相邻的远程溢出内存区域。攻击者精心构造这段溢出数据,就能改写程序执行流程,让它去执行攻击者想要的代码。

关键在于“远程”两个字。本地溢出需要攻击者已经能登录目标机器,远程溢出不需要。发一个网络包过去,对方处理时触发漏洞,代码就在对方机器上跑起来了。没有交互,没有认证,一个数据包换一个shell。这类漏洞的CVSS评分通常在9.0以上,属于最危险的那一档。

打个比方。你往一个只能装500毫升的杯子里倒600毫升水,水会溢出来流到桌上。如果桌子旁边恰好有个开关,水流过去按下了开关,启动了某个设备——这就是溢出攻击的物理版本。计算机世界里,那个“开关”就是被覆盖的函数返回地址或者函数指针。

写一个远程溢出利用,攻击者要做几件事。找到漏洞点,确定溢出偏移量,找到可以跳转的地址,构造shellcode,处理坏字符,绕过ASLR和DEP。听起来步骤清晰,实际操作中每一步都可能卡住。偏移量差一个字节,程序直接崩溃而不是被控制。目标系统的内存布局每次重启都在变,硬编码的跳转地址根本不可靠。

防御手段这些年确实在进步。栈保护(Stack Canary)在返回地址前面放一个随机值,溢出会先覆盖它,函数返回前检查发现被改了就直接终止程序。ASLR让内存地址随机化,攻击者猜不到跳转目标。DEP标记某些内存区域不可执行,shellcode放进去也跑不了。但这些保护不是万能的。Canary可以被泄露,ASLR在32位系统上熵值不够,ROP技术可以绕过DEP。攻防一直在拉锯。

我印象最深的一个案例是CVE-2019-0708,也就是“BlueKeep”。Windows远程桌面服务里的一个远程溢出漏洞。不需要用户认证,不需要用户交互,发一个特制请求就能触发。微软罕见地为已经停止支持的Windows XP和Windows 2003发布了补丁。当时安全圈的气氛很紧张,因为一旦蠕虫化利用出现,传播速度会比WannaCry还快。好在最终没有公开的蠕虫武器出现,但这件事说明远程溢出漏洞的威慑力有多大。

写这类漏洞的利用代码,体验很特别。你面对的是一个黑盒,只能通过发送数据包和观察响应来推断内部状态。有时候调了一整天,发现只是偏移量算错了一位。有时候运气好,几个小时后就能弹出计算器。那种“一个数据包换一个shell”的瞬间,确实让人上瘾。

远程溢出漏洞不会消失。代码是人写的,人就会犯错。网络服务暴露在公网,攻击面就一直在。补丁打了,旧系统还在跑。新协议、新服务、新框架,每一行处理网络数据的代码都可能是下一个入口。

分享到: