Bugtraq mailing list archives

Re: [Fwd: Truth about ssh 1.2.27 vulnerabiltiy]


From: long () KESTREL CC UKANS EDU (Jeff Long)
Date: Mon, 4 Oct 1999 12:41:41 -0500


Dan Astoorian wrote:

On Thu, 30 Sep 1999 15:04:14 EDT, Eric Griffis writes:

Jeff Long's patch is the sort of method I had in mind for fixing the
problem properly.

I'm not sure whether there are other credentials which the code should
also be giving away--for instance, if root belongs to supplementary
groups, then perhaps directories that are writable by those groups might
still be attacked by the exploit.  It would be worth testing whether
this is the case.  If so, perhaps an appropriate "initgroups(...)" would
help?

There's been a flurry of patches for this problem but since I'd already
sent out a partially correct patch I figured I better follow up with a
more(?) correct patch.  I've added the code to fixup the concurrent
groups before and after doing the bind().  This was tested on Tru64
5.0.  Since I guess some OS'es don't have initgroups() they will need to
add the #ifdef for initgroups() to avoid it.  Also I'm not really sure
if the calls to setegid() are still necessary but I felt better just
leaving them in.

Jeff Long

*** newchannels.c.original      Thu Sep 30 16:58:22 1999
--- newchannels.c       Mon Oct  4 12:23:48 1999
***************
*** 2262,2268 ****
    struct stat st, st2, parent_st;
    mode_t old_umask;
    char *last_dir;
!
    if (auth_get_socket_name() != NULL)
      fatal("Protocol error: authentication forwarding requested twice.");

--- 2262,2272 ----
    struct stat st, st2, parent_st;
    mode_t old_umask;
    char *last_dir;
!   uid_t saved_euid = 0;
!   gid_t saved_egid = 0;
!   gid_t saved_groups[NGROUPS_MAX];
!   int saved_groups_count = 0;
!
    if (auth_get_socket_name() != NULL)
      fatal("Protocol error: authentication forwarding requested twice.");

***************
*** 2411,2427 ****
       creating unix-domain sockets, you might not be able to use
       ssh-agent connections on your system */
    old_umask = umask(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
!
!   if (bind(sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)) < 0)
!     packet_disconnect("Agent socket bind failed: %.100s", strerror(errno));
!
!   umask(old_umask);
!
    if (directory_created)
      if (chown(".", pw->pw_uid, pw->pw_gid) < 0)
        packet_disconnect("Agent socket directory chown failed: %.100s",
                          strerror(errno));

    /* Start listening on the socket. */
    if (listen(sock, 5) < 0)
      packet_disconnect("Agent socket listen failed: %.100s", strerror(errno));
--- 2415,2450 ----
       creating unix-domain sockets, you might not be able to use
       ssh-agent connections on your system */
    old_umask = umask(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
!
    if (directory_created)
      if (chown(".", pw->pw_uid, pw->pw_gid) < 0)
        packet_disconnect("Agent socket directory chown failed: %.100s",
                          strerror(errno));

+   saved_euid = geteuid();
+   saved_egid = getegid();
+
+   if ((saved_groups_count = getgroups(NGROUPS_MAX, saved_groups)) < 0)
+       packet_disconnect("Agent socket getgroups failed: %s.100s", strerror(errno));
+   if (initgroups(pw->pw_name, pw->pw_gid))
+       packet_disconnect("Agent socket initgroups failed: %s.100s", strerror(errno));
+
+   if (setegid(pw->pw_gid) < 0)
+       packet_disconnect("Agent socket setegid failed: %.100s", strerror(errno));
+   if (seteuid(pw->pw_uid) < 0)
+       packet_disconnect("Agent socket seteuid failed: %.100s", strerror(errno));
+   if (bind(sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)) < 0)
+       packet_disconnect("Agent socket bind failed: %.100s", strerror(errno));
+
+   if (seteuid(saved_euid) < 0)
+       packet_disconnect("Agent socket re-seteuid failed: %.100s", strerror(errno));
+   if (setegid(saved_egid) < 0)
+       packet_disconnect("Agent socket re-setegid failed: %.100s", strerror(errno));
+   if (setgroups(saved_groups_count, saved_groups) < 0)
+       packet_disconnect("Agent socket setgroups failed: %s.100s", strerror(errno));
+
+   umask(old_umask);
+
    /* Start listening on the socket. */
    if (listen(sock, 5) < 0)
      packet_disconnect("Agent socket listen failed: %.100s", strerror(errno));


Current thread: