Network Time Protocol Daemon (ntpd) Multiple Vulnerabilities(CVE-2014-9293、CVE-2014-9294、CVE-2014-9295、CVE-2014-9295、CVE-2014-9295、CVE-2014-9296)
目录
0. 引言 1. CVE-2014-9293: Weak default key in config_auth() 2. CVE-2014-9294: non-cryptographic random number generator with weak seed used by ntp-keygen to generate symmetric keys 3. CVE-2014-9295: Buffer overflow in crypto_recv()、Buffer overflow in ctl_putdata()、Buffer overflow in configure() 4. CVE-2014-9296: receive(): missing return on error
0. 引言
NTF's NTP Project has been notified of a number of vulnerabilities from Neel Mehta and Stephen Roettger of Google's Security Team. The two most serious of these issues and four less serious issues have been resolved as of ntp-4.2.8, which was released on 18 December 2014. There are still two less significant issues to be addressed. We're expecting to fix these within the next month.
本次Google Security Team一共报告了和NTPD有关的6个漏洞,其中2个属于缓冲区溢出导致的RCE(远程代码执行)漏洞,属于高危漏洞
Relevant Link:
http://support.ntp.org/bin/view/Main/SecurityNotice#Buffer_overflow_in_ctl_putdata http://www.kb.cert.org/vuls/id/852879 https://rhn.redhat.com/errata/RHSA-2014-2024.html
1. CVE-2014-9293: Weak default key in config_auth()
0x1: 触发条件
1. no auth key is set in the configuration file 2. All NTP4 releases before 4.2.7p11
vim /etc/ntp.conf
# Key file containing the keys and key identifiers used when operating
# with symmetric key cryptography.
keys /etc/ntp/keys
vim /etc/ntp/keys
# # PLEASE DO NOT USE THE DEFAULT VALUES HERE. # #65535 M akey #1 M pass
在默认安装情况下,NTP是没有配置显式指定"auth key"的,也就是说,NTP中的这个漏洞是默认存在的
0x2: 漏洞源代码分析
\ntp-4.2.6p5\ntpd\ntp_config.c
static void config_auth(struct config_tree *ptree ) { ... u_char digest[EVP_MAX_MD_SIZE]; u_int digest_len; /* typedef struct EVP_MD_CTX { byte macType; // md5 or sha for now Hasher hash; } EVP_MD_CTX; */ EVP_MD_CTX ctx; ... /* if doesn't exist, make up one at random */ if (authhavekey(req_keyid)) { req_keytype = cache_type; #ifndef OPENSSL req_hashlen = 16; #else /* OPENSSL follows */ EVP_DigestInit(&ctx, EVP_get_digestbynid(req_keytype)); EVP_DigestFinal(&ctx, digest, &digest_len); req_hashlen = digest_len; #endif } else { // when an auth key is not configured int rankey; //这行代码是漏洞产生的关键,ntp_random()无法产生足够密文空间的密文 rankey = ntp_random(); req_keytype = NID_md5; req_hashlen = 16; MD5auth_setkey(req_keyid, req_keytype, (u_char *)&rankey, sizeof(rankey)); authtrust(req_keyid, 1); } ... }
我们继续跟进ntp_random()这个函数
\ntp-4.2.6p5\libntp\ntp_random.c
/* * random: * * If we are using the trivial TYPE_0 R.N.G., just do the old linear * congruential bit. Otherwise, we do our fancy trinomial stuff, which is * the same in all the other cases due to all the global variables that have * been set up. The basic operation is to add the number at the rear pointer * into the one at the front pointer. Then both pointers are advanced to * the next location cyclically in the table. The value returned is the sum * generated, reduced to 31 bits by throwing away the "least random" low bit. * * Note: the code takes advantage of the fact that both the front and * rear pointers can't wrap on the same call by not testing the rear * pointer if the front one has wrapped. * * Returns a 31-bit random number. */ long ntp_random( void ) { register long i; register long *f, *r; if (rand_type == TYPE_0) { i = state[0]; state[0] = i = (good_rand(i)) & 0x7fffffff; } else { /* * Use local variables rather than static variables for speed. */ f = fptr; r = rptr; *f += *r; i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */ if (++f >= end_ptr) { f = state; ++r; } else if (++r >= end_ptr) { r = state; } fptr = f; rptr = r; } return(i); }
\ntp-4.2.6p5\libntp\ntp_random.c
static inline long good_rand ( register long x ) { #ifdef USE_WEAK_SEEDING /* * Historic implementation compatibility. * The random sequences do not vary much with the seed, * even with overflowing. */ return (1103515245 * x + 12345); #else /* !USE_WEAK_SEEDING */ /* * Compute x = (7^5 * x) mod (2^31 - 1) * wihout overflowing 31 bits: * (2^31 - 1) = 127773 * (7^5) + 2836 * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. */ register long hi, lo; hi = x / 127773; lo = x % 127773; x = 16807 * lo - 2836 * hi; if (x <= 0) x += 0x7fffffff; return (x); #endif /* !USE_WEAK_SEEDING */ }
ntp_random产生了一个32bit的密文
0x3: 漏洞的攻击场景
这里的关键是ntp_random产生的key,是在哪里使用的,这决定了如何触发重现这个漏洞
0x4: 修复方案
Upgrade to 4.2.7p11
0x5: 攻防思考
从漏洞原理上来说,这个漏洞属于"初始种子SEED未指定,导致系统使用默认的内置初始SEED进行密钥序列生成,而这个使用默认初始SEED生成的密钥序列是攻击者可预测的"漏洞,类似的漏洞有
1. PHP的的rand()函数在没有显式调用srand()设置初始SEED的情况下,PHP将使用内置的默认SEED进行随机数生成,导致可预测漏洞 2. JAVA JDK 1.6之前的伪随机生成函数可预测漏洞
要避免这种漏洞的出现,我们可以从2个方面去思考
1. 使用良好的编程规范,对和密钥生成相关的随机数都必须在生产之前显式地进行种子SEED赋值 2. 在代码库底层就实现"安全伪随机数生成函数",即允许直接调用伪随机数生成函数,但是函数在底层自动实现了初始种子SEED的随机重置,PHP的mt_srand()就是一个很好的例子
Relevant Link:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9293
2. CVE-2014-9294: non-cryptographic random number generator with weak seed used by ntp-keygen to generate symmetric keys
0x1: 触发条件
1. Prior to ntp-4.2.7p230
0x2: 漏洞源代码分析
\ntp-4.2.6p5\util\ntp-keygen.c
0x3: 漏洞的攻击场景
Prior to ntp-4.2.7p230 ntp-keygen used a weak seed to prepare a random number generator that was of good quality back in the late 1990s. The random numbers produced was then used to generate symmetric keys
0x4: 修复方案
Upgrade to 4.2.7p230
0x5: 攻防思考
Relevant Link:
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9294
3. CVE-2014-9295: Buffer overflow in crypto_recv()、Buffer overflow in ctl_putdata()、Buffer overflow in configure()
0x1: 触发条件
0x2: 漏洞源代码分析
0x3: 漏洞的攻击场景
0x4: 修复方案
0x5: 攻防思考
4. CVE-2014-9296: receive(): missing return on error
0x1: 触发条件
0x2: 漏洞源代码分析
0x3: 漏洞的攻击场景
0x4: 修复方案
0x5: 攻防思考
Copyright (c) 2014 LittleHann All rights reserved
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)