Bugtraq mailing list archives

Re: [Fwd: Truth about ssh 1.2.27 vulnerabiltiy]


From: djast () CS TORONTO EDU (Dan Astoorian)
Date: Mon, 27 Sep 1999 11:35:44 -0400


I'm surprised that nothing further has been reported to Bugtraq about
this, but the problem appears to be that under Linux, a bind() to a
Unix-domain socket will follow a dangling symlink, whereas most other
Unixes appear to return an EADDRINUSE error.

I leave it to the standards lawyers to determine whether the failing is
in the operating system for allowing the bind() to succeed, or in SSH
for not testing whether the link exists.  My vote goes to the OS being
at fault, since it's easy enough for it to avoid following the link (and
no real practical reason why it *should* follow the link).

A trivial demo program that demonstrates the problem is attached.  (It
needs no special privileges; run it as an unprivileged user in any
writable directory.)  The program reports "okay" under Solaris 2.5.1 and
IRIX 6.5.2, "vulnerable" under RedHat 6.

--                          People shouldn't think that it's better to have
Dan Astoorian               loved and lost than never loved at all.  It's
Sysadmin, CS Lab            not, it's better to have loved and won.  All
djast () cs toronto edu        the other options really suck.    --Dan Redican

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define FPATH "./bindlinktest"
#define LPATH "./bindlinktest0"

int main(int argc, char **argv) {
    int fd;
    struct sockaddr_un sunaddr;

    fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (fd < 0) { perror("socket");exit(1); };

    unlink(FPATH);
    if (symlink(FPATH, LPATH) < 0) {
        perror("symlink");exit(1);
    }

    memset(&sunaddr, 0, sizeof(sunaddr));
    sunaddr.sun_family = AF_UNIX;
    strncpy(sunaddr.sun_path, LPATH, sizeof(sunaddr.sun_path));
    if (bind(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
        if (errno == EADDRINUSE) {
            printf("bind() returned EADDRINUSE; this system appears to be okay.\n");
        } else {
            perror("bind");
        }
    } else {
        printf("bind() succeeded; this system appears to be vulnerable.\n");
    }

    close(fd)
    unlink(FPATH);
    unlink(LPATH);
    exit(0);
}


Current thread: