翻译:overXsky
预估稿费:100RMB
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
前言
许多设备的使用都离不开网络,其中,用来同步网络上各种设备时间使用的是网络时间协议(Network Time Protocol)。网络时间协议守护进程(Network Time Protocol Daemon ,NTPD)是此协议的开源实现。在过去的几个月内,NTPD被陆续报道了大量的漏洞,其中一个就是CVE-2016-9311——可以引发崩溃从而导致拒绝服务。在这篇文章中,我们将从细节着手分析这个漏洞。
查找更改
通过检查补丁程序,我们在ntp_control.c文件中找到了 “report_event” 函数,它就是该漏洞的修复程序。 补丁比较工具显示如下(摘自http://bugs.ntp.org/attachment.cgi?id=1460&action=diff):
图一左侧显示的是未修补的代码,右侧是已修补的代码。
在易受攻击的代码中有一个判断语句:
INSIST(peer!=NULL)
INSIST函数定义在ntp_assert.h头文件中,如果peer==NULL,那么返回值为真,判断语句失败,NTPD将崩溃。
对比修复后的代码可以明显的发现,原来的INSIST(peer!=NULL)判断语句被替换成了简单的if判断:
if ((err & PEER_EVENT) && !peer)
return
if语句会检查“peer”的值是否为NULL,如果是的话它就简单地返回并防止崩溃。
分析根本原因
要触发这个漏洞,程序流需要执行到“report_event”函数,并给它传送特定的参数值以便使得INSISIT函数判断失败从而崩溃。
当NTPD接收到一个数据包时,它会去调用ntp_proto.c中的接收函数“receive”。接收函数会对接收到的分组执行各种检查,其中一项检查是确认接收到的加密否定应答(crypto-NAK)分组是否有效。
如果NTPD收到一个无效的NAK数据包,它将调用易受攻击的函数“report_event”。该函数会查找数据包中陷阱(trap)的数量,如果没有在NTPD上配置过陷阱(关于NTPD traps可以参考这里),该函数将简单返回,后面易受攻击的代码片段也不会被执行。
当且仅当在NTPD中启用陷阱时,才能利用此漏洞。 要检查NAK数据包是否有效会用到“valid_NAK” 函数,它被定义在ntp_proto.c文件中,代码如下:
从上面的代码中可以总结出,一个数据包符合以下几点特征中的任何一个即为无效:
1. 模式不是MODE_SERVER、MODE_ACTIVE和MODE_PASSIVE。
2. keyid不为0。
3. peer为NULL,或者peer没有密钥。
4. ORIGIN不匹配。
如果NTPD上启用了陷阱功能,触发此漏洞只需要构造一个没有peer存在(即peer=NULL)的“无效NAK”数据包然后发送即可。为了证实这一点,我们用调试器来对未修复版本代码进行了测试,如下所示,NTPD因为判断失败而崩溃了:
总结
此漏洞在NTPD启用了陷阱功能的情况下可以被利用来触发崩溃引起拒绝服务。NTPD默认情况下不启用陷阱。利用此漏洞不需要授权。
防范此漏洞可以通过安装最新的补丁程序或更新最新版本的NTPD,或者使用McAfee网络安全平台等防护软件。
参考文献
发表评论
您还未登录,请先登录。
登录