-- ---------------------------------------------------------------------- Sylvain Robitaille syl_at_alcor.concordia.ca Systems Manager Concordia University Instructional & Information Technology Montreal, Quebec, Canada ---------------------------------------------------------------------- *** newchannels.c.original Wed May 12 07:19:27 1999 --- newchannels.c Thu Sep 30 11:50:11 1999 *************** *** 16,21 **** --- 16,26 ---- */ /* + * Revision 1.50unoff 1999/09/29 14:27:52 <syl_at_alcor.concordia.ca> + * ssh-agent symlink DoS exploit protection added + */ + + /* * $Id: newchannels.c,v 1.49 1999/02/22 08:14:01 tri Exp $ * $Log: newchannels.c,v $ * Revision 1.49 1999/02/22 08:14:01 tri *************** *** 317,323 **** #define STATUS_TERMINATE 0x003f ! /* Data structure for channel data. This is iniailized in channel_allocate and cleared in channel_free. */ typedef struct --- 322,398 ---- #define STATUS_TERMINATE 0x003f ! /* ! * 1999/09/29 Sylvain Robitaille: Used for mailing to the sysadmin(s) if ! * we catch someone trying the exploit to cause the agent ! * socket to be created at the other end of a sym-link. ! */ ! #define MAIL_RECIPIENT "sysadm" ! #define MAIL_COMMAND "/usr/bin/mailx -s 'URGENT: POSSIBLE SSH-AGENT SYMLINK ATTACK' " MAIL_RECIPIENT ! ! /* ! * Mail a complaint to the sysadmin. ! */ ! void mail_report(char *dirname, char *linkname, struct stat *st) ! { ! FILE *mail_pipe; ! struct passwd *pw; ! struct group *gr; ! char usrname[17]; ! char grpname[17]; ! char target[PATH_MAX]; ! char filename[PATH_MAX]; ! int count; ! ! if ((mail_pipe = popen(MAIL_COMMAND, "w")) == NULL) ! { ! snprintf(target, sizeof(target) - 1, "can't open pipe to %s\n", ! MAIL_COMMAND); ! log_msg(target); ! exit(1); ! } ! ! /* reconstruct the full path to the file */ ! if (dirname[strlen(dirname)-1] == '/') dirname[strlen(dirname)-1] = 0; ! snprintf(filename, sizeof(filename) - 1, "%s/%s", dirname, linkname); ! ! /* Figure out who owns the file. */ ! pw = getpwuid(st->st_uid); ! if (!pw) { ! snprintf(usrname, sizeof(usrname) - 1, "%d", st->st_uid); ! } else { ! snprintf(usrname, sizeof(usrname) - 1, "%s", pw->pw_name); ! } ! ! gr = getgrgid(st->st_gid); ! if (!gr) { ! snprintf(grpname, sizeof(grpname) - 1, "%d", st->st_gid); ! } else { ! snprintf(grpname, sizeof(grpname) - 1, "%s", gr->gr_name); ! } ! ! /* ! * Get the link's target. NOTE: The target may not necessarily ! * already exist, so we don't bother getting stats on it, but we ! * do want to know its path. ! */ ! count = readlink(filename, target, sizeof(target) - 1); ! if (count < 0) { ! snprintf(target, sizeof(target) - 1, "unreadable!"); ! } else { ! target[count] = '\0'; ! } ! ! (void) fprintf(mail_pipe, "File: %s exists as a symbolic link\n", filename); ! (void) fprintf(mail_pipe, "Owner: %s.%s\n", usrname, grpname); ! (void) fprintf(mail_pipe, "Target: %s\n", target); ! (void) fprintf(mail_pipe, "Mode: %o\n", 07777 & st->st_mode); ! (void) fflush(mail_pipe); ! ! (void) pclose(mail_pipe); ! } ! ! /* Data structure for channel data. This is initialized in channel_allocate and cleared in channel_free. */ typedef struct *************** *** 2395,2400 **** --- 2470,2502 ---- return 0; } + /* + * 1999/09/28 Sylvain Robitaille: Check that there isn't already a + * file by the same name. If there is, and it's a symbolic + * link, we probably have a DoS attempt. Else, if the file + * exists and is not already a socket, complain and fail. + * + * File exists but is a socket is acceptable, since that + * socket might be a remnant (did the machine crash while + * that socket was still open?) + */ + ret = lstat(channel_forwarded_auth_socket_name, &st); + if (!ret && S_ISLNK(st.st_mode)) { + packet_send_debug("* Remote error: Agent socket creation failed: File exists as a symbolic link."); + packet_send_debug("* Remote error: Authentication fowarding disabled."); + log_msg("Agent socket creation failed: File %s is a symbolic link.", + channel_forwarded_auth_socket_name); + mail_report(channel_forwarded_auth_socket_dir_name, + channel_forwarded_auth_socket_name, &st); + return 0; + } else if (!ret && !S_ISSOCK(st.st_mode)) { + packet_send_debug("* Remote error: Agent socket creation failed: File exists and is not a socket."); + packet_send_debug("* Remote error: Authentication fowarding disabled."); + log_msg("Agent socket creation failed: File %s is not a socket.", + channel_forwarded_auth_socket_name); + return 0; + } + /* Create the socket. */ sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0)Received on Thu Sep 30 1999 - 17:36:45 NZST
This archive was generated by hypermail 2.4.0 : Wed Nov 08 2023 - 11:53:39 NZDT