Bugtraq mailing list archives

possible lpd remote vulnerability


From: volobuev () t1 chem umn edu (Yuri Volobuev)
Date: Sat, 30 Nov 1996 02:55:46 -0600


Howdy,

I was looking through lpd sources and noticed something that can actually be
a remote vulnerability in lpd, allowing for stack overflow and thus
arbitrary machine code execution.  The piece of code that I'm suspicios
about is

lpd.c, line 463
        hp = gethostbyaddr((char *)&f->sin_addr,
            sizeof(struct in_addr), f->sin_family);
        if (hp == 0)
                fatal("Host name for your address (%s) unknown",
                        inet_ntoa(f->sin_addr));

        strcpy(fromb, hp->h_name);
        from = fromb;
        if (!strcmp(from, host))
                return;

        sp = fromb;
        cp = ahost;
        while (*sp) {
                if (*sp == '.') {
                        if (baselen == -1)
                                baselen = sp - fromb;
                        *cp++ = *sp++;
                } else {
                        *cp++ = isupper(*sp) ? tolower(*sp++) : *sp++;
                }
        }
        *cp = '\0';

after a call to gethostbyaddr() h_name, i.e. hostname of the remote machine,
is copied first to fromb then to ahost without checking for length.

Arrays are allocated as

global array
char fromb[32];

local automatic array
char ahost[50];

So strcpy(fromb, hp->h_name) could overwrite array boundaries, but since
it's in the global data segment, it's not dangerous (it could have other
kinds of side effects, but not stack smashing).  But then h_name is copied
to ahost, which _is_ on stack, right near the top, and if hostname is longer
than 50 characters, it's possible to smash the stack.  Of course, it's not
possible to put the actual machine code into the hostname, but actually all
that's necessary is the return address, machine code can be passed earlier
as an lpd command.  Of course, it would be very difficult to figure the
correct address where code is located on the remote machine, but it's
possible theoretically.

The only thing I'm not sure about is what kind of stuff can be put in the
hostname.  I haven't found how long the hostname can actually be.  RFC1034
says that hostname can contain up to 255 "labels" up to 63 chars each.  I've
seen _long_ hostnames on the net, much longer than 32 characters.  But may
be gethostbyaddr truncates h_name field to 32 chars (I don't think so,
because long hostnames actually work, but I don't know for sure).

If I'm right about this one, person with access to a nameserver can make up
a long hostname, carefully constructed to overwrite stack on the remote
machine running lpd, and execute arbitrary machine code, say, xterm -display
evilhost:0.  Copying/overwriting is done _before_ the client host-based
authentification.

The code I was looking at was obtained from Debian Linux distribution
sources, lpd version is 5.19.  But I suspect that all lpd's around that are
derived from BSD lpd have this piece of code, including commercial Unices.

Can somebody confirm this or show that I'm wrong?  I can then make a
summary.

Thanks, cheers,

yuri
Always speaking for myself and only for myself



Current thread: