When logging in, Ubuntu shows (admin?) users some useful information, such as
70 packages can be updated.
35 updates are security updates.
I recently ran into an issue where this information popped up twice on each
login – one up-to-date entry and one outdated entry. Some investigation showed
that somehow /etc/motd.tail
had gained these lines too. The fix (rm -f
/etc/motd.tail
) was simple enough.
However, in the course of this investigation I noticed that
/etc/update-motd.d
is basically a bunch of shell scripts that get run as root on
every ssh login by any user. Scary, no?
Remembering that being able to inject some environment variables was
always a
great way to break out of ‘restricted’ shells that were written in
(ba)sh, I
set out to look at methods of influencing the environment these scripts
would
be run in. .ssh/environment
, .pam_environment
and
OpenSSH’s SendEnv
all turned out to be smart enough to only do
their work after update-motd was done, sadly. I was out of ideas.
The code of pam_env.so did tell me another interesting thing –
~/.pam_environment
is opened and read as root, without any
dropping of privileges. This suggested that symlinking it to some
unreadable
file (of the right format, i.e. consisting of VAR=value
lines)
would compromise the data in that file.
A proof of concept was simple enough (newline inserted because my blog layout is too narrow):
root@vps6001:~# cat /etc/env2
ENV2=bla...
peter@vps6001:~$ ls -al .pam_environment
lrwxrwxrwx 1 peter peter 9 May 12 22:13 .pam_environment -> /etc/env2
peter@vps6001:~$ ls -al /etc/env2
---------- 1 root root 9 May 12 22:13 /etc/env2
peter@vps6001:~$ set | grep -i env
ENV2=bla
It works! This means that any file that has lines containing = (without
whitespace around it) would be fair game. My first thought was
/etc/mysql/debian.cnf
, but that one has whitespace around the =
characters.
Effective targets for this trick do exist. DirectAdmin (a commercial control
panel) stores MySQL login information in a suitable file, and many daemons
that support LDAP expect a password stored in a similar way. Also,
base64-encoded files (like SSL and ssh keys) that happen to need padding such
that they end in ==
expose their last line this way. I don’t know what the
mathematical implications of having the last few bits of a private key are,
but it can’t be good.
Some internet searching turned out that this issue was previously discovered by other people. Ubuntu 10.04 and Debian 6 are still vulnerable to this issue. Debian has a report on file but has not acted on it yet. Ubuntu doesn’t seem to know at all.
I emailed security@ for both distributions, Debian responded within minutes pointing me to the report they already had. I’m waiting for a response from Ubuntu.
Workaround: add user_readenv=0
to every pam_env.so
listing in
/etc/pam.d
.
Please read my followup.