xorl %eax, %eax

CVE-2011-0010: sudo Group ID Privilege Escalation

leave a comment »

This is a neat vulnerability in sudo was reported by Alexander Kurtz to the Debian bug tracking system. The problem was that you could change your GID without being asked for a password. This could result in privilege escalation and the buggy code was available in check.c which you can see here:

/*
 * This function only returns if the user can successfully
 * verify who he/she is.
 */
void
check_user(validated, mode)
    int validated;
    int mode;
{
    char *timestampdir = NULL;
  ...
    /* Always prompt for a password when -k was specified with the command. */
    if (ISSET(mode, MODE_INVALIDATE)) {
	SET(validated, FLAG_CHECK_USER);
    } else {
        if (user_uid == 0 || user_uid == runas_pw->pw_uid || user_is_exempt())
	    return;
    }
  ...
    efree(timestampdir);
    efree(timestampfile);
}

Where it did not prompt the user for a password if any of the following was true…
– User ID was 0 (aka root)
– User ID was matching the “Run As” one
– The user is exempt (from sudo’s configuration file)
As you can see there was no check for the group of the user. The new releases of sudo updated the above check with this patch:

     } else {
-	if (user_uid == 0 || user_uid == runas_pw->pw_uid || user_is_exempt())
+	/*
+	 * Don't prompt for the root passwd or if the user is exempt.
+	 * If the user is not changing uid/gid, no need for a password.
+	 */
+	if (user_uid == 0 || (user_uid == runas_pw->pw_uid &&
+	    (!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name))) ||
+	    user_is_exempt())
 	    return;

The addition was that the “Run As” for group is set or that the user belongs to “Run As” group. Also, the plugins/sudoers/sudoers.c file and the sudoers policy routine in particular which was this:

static int
sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
    char **command_infop[], char **argv_out[], char **user_env_out[])
{
    static char *command_info[32]; /* XXX */
    char **edit_argv = NULL;
  ...
    if (def_stay_setuid) {
	easprintf(&command_info[info_len++], "runas_uid=%u",
	    (unsigned int)user_uid);
	easprintf(&command_info[info_len++], "runas_gid=%u",
	    (unsigned int)user_gid);
	easprintf(&command_info[info_len++], "runas_euid=%u",
	    (unsigned int)runas_pw->pw_uid);
	easprintf(&command_info[info_len++], "runas_egid=%u",
	    (unsigned int)runas_pw->pw_gid);
    } else {
	easprintf(&command_info[info_len++], "runas_uid=%u",
	    (unsigned int)runas_pw->pw_uid);
	easprintf(&command_info[info_len++], "runas_gid=%u",
	    (unsigned int)runas_pw->pw_gid);
    }
  ...
    return rval;
}

Was changed to incorporate the ‘runas_gr’ check as we can see from this patch:

 	easprintf(&command_info[info_len++], "runas_egid=%u",
+	    runas_gr ? (unsigned int)runas_gr->gr_gid :
 	    (unsigned int)runas_pw->pw_gid);
     } else {
 	easprintf(&command_info[info_len++], "runas_uid=%u",
 	    (unsigned int)runas_pw->pw_uid);
 	easprintf(&command_info[info_len++], "runas_gid=%u",
+	    runas_gr ? (unsigned int)runas_gr->gr_gid :
 	    (unsigned int)runas_pw->pw_gid);

Written by xorl

January 14, 2011 at 15:13

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s