[Pkg-samba-maint] Bug#939542: denial of service and possible other security implications by giving wrong kerberos ticket cache file to other users.

Erik Thiele erik.thiele at thiele-hydraulik.de
Fri Sep 6 08:14:20 BST 2019


Package: libpam-winbind
Version: 2:4.5.16+dfsg-1+deb9u2
Severity: important

I am using a samba 4 as active directory domain controller in a basic
configuration as defined in the official samba 4 wiki. I added two
users:

root at seclag:/etc# id aduser
uid=30106(aduser) gid=30099(domain users) Gruppen=30099(domain
users),70002(BUILTIN\users)

root at seclag:/etc# id user2
uid=30100(user2) gid=30099(domain users) Gruppen=30099(domain
users),70002(BUILTIN\users)

the only computer added to the active directory is the linux machine
"seclag". It uses a basic libpam-winbind based configuration without
any changes to the default pam stack configuration. using
libpam-winbind is suggested by the official samba4 wiki.

in /etc/pam.d/common-auth we find:
auth    [success=1 default=ignore]      pam_winbind.so krb5_auth
krb5_ccache_type=FILE cached_login try_first_pass

this pam line is responsible for creating the file /tmp/krb5cc_30100 if
the user "user2" with uid 30100 is logging in on the console. this can
be shown by replacing krb5_ccache_type=FILE above with
krb5_ccache_type=FILE:/tmp/mydebug_%u because if you do so, the system
is creating /tmp/mydebug_30100 instead.

see:

user2 at seclag:~$ klist
Ticket cache: FILE:/tmp/mydebug_30100  <-- here!
Default principal: user2 at XX.MYDOMAIN.DE

let's revert back to using the normal /tmp/krb5cc_* system as is
configured by default. the example above was just to show that
pam_winbind is responsible for creating the problematic situation shown
in the following:

let's login as user "adtest" with uid 30106:

aduser at seclag:~$ klist
Ticket cache: FILE:/tmp/krb5cc_30106
Default principal: aduser at XX.MYDOMAIN.DE

see, the default principal is just fine. we have the right kerberos key
installed. now let's create a fake ticket cache for user2:

aduser at seclag:~$ export =/tmp/krb5cc_30100
# 30100 is the uid of user "user2"

aduser at seclag:~$ kinit aduser          
Password for aduser at XX.MYDOMAIN.DE: 
aduser at seclag:~$ klist
Ticket cache: FILE:/tmp/krb5cc_30100
Default principal: aduser at XX.MYDOMAIN.DE

ok we now created a new ticket cache with our key inside. all right.
now logout and login as user "user2":

user2 at seclag:~$ klist
klist: Credentials cache permissions incorrect
(filename: /tmp/krb5cc_30100)

ok so user "aduser" created a denial of service situation for user
"user2"! let's see if we can do more bad things. log in as user
"aduser" again:

aduser at seclag:~$ chmod 666 /tmp/krb5cc_30100 

now try again as user "user2":

user2 at seclag:~$ klist
Ticket cache: FILE:/tmp/krb5cc_30100
Default principal: aduser at XX.MYDOMAIN.DE

???????? see? user "user2" now has the kerberos key of user "aduser"
installed. The system is silently taking the keys someone else has
installed!

I am not quite sure how to fix this correctly, but:

pam_winbind certainly must not simply take an existing file which is
owned by an other user! it must instead remove that file and create it
correctly (but take care of race conditions!). the other alternative
would be to just fail, but then a user can deny service of other users
simply by creating /tmp/krb5cc_UID_OF_OTHER_USER. so the correct
solution is to remove that file and create it correctly. thereby
correctly taking care of possible symlink attacks and other bad stuff.
removing the file may be complicated if another user created a
directory with that name.

I am unsure what kind of bad things can be done due to this bug. but on
our site every user can do a denial of service against all other system
users (which have not logged on since cleaning of /tmp) with this
command:

for a in $(seq 30000 30200); do touch /tmp/krb5cc_$a; done

denial of service is only relevant to kerberos. thus if a user does a
kerberized cifs mount then it will not work. the other parts of the
system which do not depend on a valid kerberos ticket will work of
course.

an alternative would be to specify KEYRING as krb5_ccache_type but I
can't get it to work. cat /proc/keys always stays empty. no matter if i
use KEYRING or FILE. but in the KEYRING case, klist still
uses /tmp/krb5cc_30100 because the environment variable KRB5CCNAME is
unset for some reason when using KEYRING. i think the KEYRING
implementation in pam_winbind is broken?

cya
erik



More information about the Pkg-samba-maint mailing list