[Bug 268149] kadmind handle_mit() rpc/gss bugs
Date: Sun, 04 Dec 2022 16:16:18 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=268149
Bug ID: 268149
Summary: kadmind handle_mit() rpc/gss bugs
Product: Base System
Version: CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: bin
Assignee: bugs@FreeBSD.org
Reporter: rtm@lcs.mit.edu
Attachment #238511 text/plain
mime type:
Created attachment 238511
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=238511&action=edit
tickle bugs in kadmind's RPC/GSS interface by sending RPCs in the clear
The heimdal kadmind has code to receive requests via ONC RPC protected
by GSS encryption and signatures; this is handle_mit() etc in
kadmind/rpc.c.
One problem is that kadmind reads RPC arguments in the clear direct
from the TCP connection, with no encryption or signature (and not
preceded by a length). This means that an eavesdropper could read
or modify RPC arguments (including, I believe, the passwords in
create requests).
That is, when receiving an RPC on a connection that's already been set
up and had initial authentication done, process_stream(...,sp) in
kadmind/rpc.c does this:
read an RPC length from sp (which is just the socket, no crypto yet);
read_data(sp, msg, len); // copy bytes from sp socket to msg buffer
parse the RPC header, including cred and verf, out of msg;
case RPC_DATA:
gss_unwrap(... &gout ...) which I believe decrypts, and checks the
signature
(*procs[chdr.proc].func)(server_handle, sp, dreply);
Note that the 2nd argument to procs[].func is sp, not gout or sp1.
That is, the RPC handler function is going to read its arguments
in clear-text from the underlying socket, not from a data buffer
that is the result of decryption and signature check.
Separately, after the RPC handler has returned, process_stream()
frees sp but then uses it to send the reply:
krb5_storage_free(sp);
... much later;
CHECK(krb5_store_uint32(sp, data.length | LAST_FRAGMENT));
sret = krb5_storage_write(sp, data.data, data.length);
This potentially results in reading and writing and calling through
garbage pointers.
Separately, there are a couple of calls to ret_string_xdr() and
ret_principal_xdr() that assume that if these fuctions return zero
(success), then they allocated a string. That's not the case: if the
client specified a zero-length string, these functions set the string
pointer to NULL.
I've attached a demo. Due to some error in my setup, the host name
must be set to "admin" in order for this to work; otherwise the gss rpc
library changes "kadmin/admin" to "kadmind\\/admin", which kdc doesn't
recognize. valgrind or a debugging malloc is required to see the
use-after-free. kinit is required.
# cc kadmind27a.c -lrpcsec_gss
# hostname admin
# kinit
# valgrind /usr/libexec/kadmind --debug &
# ./a.out
If the user has no kadmind permissions, I get the use-after-free bug:
#0 0x00000f24b3546b31 in krb5_store_int (sp=0xf24bb6d6180,
value=<optimized out>, len=4)
at /usr/src/crypto/heimdal/lib/krb5/store.c:328
#1 krb5_store_int32 (sp=0xf24bb6d6180, value=<optimized out>)
at /usr/src/crypto/heimdal/lib/krb5/store.c:356
#2 krb5_store_uint32 (sp=sp@entry=0xf24bb6d6180, value=<optimized out>)
at /usr/src/crypto/heimdal/lib/krb5/store.c:375
#3 0x00000f1c8fc8d07d in process_stream (contextp=0xf24bb6d7000,
buf=0xf24b0753974 "$\017", ilen=0, sp=0xf24bb6d6180)
at /usr/src/crypto/heimdal/kadmin/rpc.c:1087
#4 handle_mit (contextp=contextp@entry=0xf24bb6d7000,
buf=buf@entry=0xf24b0753970, len=len@entry=4, sock=<optimized out>)
at /usr/src/crypto/heimdal/kadmin/rpc.c:1107
#5 0x00000f1c8fc8e46a in kadmind_loop (contextp=0xf24bb6d7000,
keytab=0xf24bb6eb000, sock=-1)
at /usr/src/crypto/heimdal/kadmin/server.c:591
#6 0x00000f1c8fc8fae9 in main (argc=<optimized out>, argv=<optimized out>)
at /usr/src/crypto/heimdal/kadmin/kadmind.c:202
If the user has kadmind permissions, kadmind crashes when trying
to use a NULL principal name:
#0 _hdb_fetch_kvno (context=0x6972dc59000, db=0x6972dc74000, principal=0x0,
flags=93, kvno=0, entry=0x6971fd5d880)
at /usr/src/crypto/heimdal/lib/hdb/common.c:110
#1 0x0000069721cadb81 in kadm5_s_delete_principal (
server_handle=0x6972dc5a040, princ=0x0)
at /usr/src/crypto/heimdal/lib/kadm5/delete_s.c:51
#2 0x0000068efeee0140 in proc_delete_principal (contextp=0x6972dc5a040,
in=<optimized out>, out=0x6972dc58200)
at /usr/src/crypto/heimdal/kadmin/rpc.c:597
#3 0x0000068efeee1d15 in process_stream (contextp=0x6972dc59000,
buf=0x6971fd5dd14 "\227\006", ilen=0, sp=0x6972dc58180)
at /usr/src/crypto/heimdal/kadmin/rpc.c:926
#4 handle_mit (contextp=contextp@entry=0x6972dc59000,
buf=buf@entry=0x6971fd5dd10, len=len@entry=4, sock=<optimized out>)
at /usr/src/crypto/heimdal/kadmin/rpc.c:1107
#5 0x0000068efeee346a in kadmind_loop (contextp=0x6972dc59000,
keytab=0x6972dc6d000, sock=93)
at /usr/src/crypto/heimdal/kadmin/server.c:591
#6 0x0000068efeee4ae9 in main (argc=<optimized out>, argv=<optimized out>)
at /usr/src/crypto/heimdal/kadmin/kadmind.c:202
--
You are receiving this mail because:
You are the assignee for the bug.