GRATIA-CONDOR-2010-0002


Summary:

 

It is possible for an attacker to overwrite arbitrary files on the host running Gratia Condor probe. The attacker can escalate their privileges to root, or cause damage to the operating system in numerous ways.


Component Vulnerable Versions Platform Availability Fix Available
condor_meter 1.04.4d-1
1.06.13b-1
all not known to be publicly available no
Status Access Required Host Type Required Effort Required Impact/Consequences
Verified local ordinary user with Condor submission privileges Gratia Condor probe host, and Condor submit host. medium high
Fixed Date Credit
  Rohit Koul

Access Required:

local ordinary user with Condor submission privileges

The vulnerability requires local access to the machine with the ability to submit Condor jobs. This also requires the ability to run arbitrary code as an unprivileged user on the host where the Gratia Condor probe runs.

Effort Required:

medium

To be successful, an attacker must win a race condition in order to overwrite critical system files. Additionally, gaining root access requires the attacker to submit a Condor job with unusual job attributes in the submit file.

Impact/Consequences:

high

If the attacker is successful, any file on the host could be overwritten. Careful selection of the target file and the data written, could compromise the root account or even crash the system.

Full Details:

 

condor_meter.pl creates files containing the executed python code (apparently for debugging purposes), in the /tmp directory.

The Condor probe code tries to delete these files if they already exist, before attempting to create them. The files are created using O_CREAT without O_EXCL flag. In this mode of file creation, if the final component of the file path is a symbolic link, the file is created where the symbolic link points. This allows for a potential race condition where someone may create a file or symbolic link to the pathname after the operation that deletes the files, but before the one that opens and creates them. The attacker can thus cause the script to overwrite arbitrary files in the system.

For example, the following script repeatedly tries to create a symbolic link /tmp/py.in to /etc/passwd. If the ln runs after /tmp/py.in is deleted by the Gratia Condor probe, but before the file is written, then the attacker has successfully won the race.

      #!/bin/bash

      while true
      do
       ln -s /etc/passwd  /tmp/py.in
      done
  

Compromising the root account on the system requires a couple of additional steps.

The Condor architecture allows a user to specify attributes such as LocalSysCpu, LocalUserCpu, CumulativeSuspensionTime in the submit file, that Condor normally inserts into the job's ClassAd. If the user specifies these attributes, Condor does not overwrite them. Also, the Gratia Condor probe performs no validations on the ClassAd attributes. Hence, it is possible for an attacker to inject malicious strings in these attributes and get them written to an arbitrary file (by winning the race condition as described earlier)

An example Condor submit file exploiting the LocalUserCpu ClassAd attribute is shown below. The LocalCpuUser attribute is expected to be a floating point value, but users can set it to an arbitrary string value. The flow of the arbitrary string that gets injected is in bold.

This exploit overwrites 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 by setting the LocalUserCpu ClassAd to supply the injection data. There are other ClassAd attributes that could be used as well.

      Executable=helloworld
      Universe=vanilla
      input=data
      output=out
      error=error
      log=log
      +LocalUserCpu="::0:0::/tmp:/tmp/x"
      queue 1
   

The Condor history log for the sample job looks like:

      MyType = "Job"
      TargetType = "Machine"
      ClusterId = 18
      RemoteSysCpu="0.000000"
      LocalSysCpu="0.000000"
      LocalUserCpu="::0:0::/tmp:/tmp/x"
      .....
      .....
   

The Gratia Condor probe retrieves the attributes from the Condor logs. The corresponding code that gets written to /etc/passwd is as follows: ( ␣ represents the space character below)

      import Gratia
      Gratia.RegisterReporter("condor_meter.pl","$Revision: 3277 $ (tag 1.04.4d-1)")
      Gratia.RegisterService("Condor", "7.2.4 Jun 16 2009 BuildID: 159529  /
      I386-LINUX_RHEL5 ")
      Gratia.setProbeBatchManager("condor")
      Gratia.Initialize()
      # initialize and populate r
      r = Gratia.UsageRecord("Batch")
      ....
      ....
      r.TimeDuration(::0:0::/tmp:/tmp/x,␣"LocalUserCpu")
      r.TimeDuration(0.000000, "RemoteSysCpu")
      r.TimeDuration(0.000000, "LocalSysCpu")
      ....
      ....
      ....
      Gratia.Send(r)
   

The line r.TimeDuration(::0:0::/tmp:/tmp/x,␣"LocalUserCpu") is parsed (with : as a delimiter) and interpreted by the login process as follows:

Field Value Comment
Username: r.TimeDuration(
Password: empty no password
User id: 0 root account
Group id: 0 root account
GECOS: empty
Home directory: /tmp
Shell: /tmp/x,␣"LocalUserCpu")

The following code creates the new account's shell in a file named /tmp/x,␣"LocalUserCpu". This file just starts a standard shell.

     #!/bin/bash
     # Filename: x,␣"LocalUserCpu"

     /bin/bash
   

Root access can then be gained by using su as follows:

     su 'r.TimeDuration(' 
   

Thus gaining root access is essentially a four step process:

  1. Create a simple script for the new account's shell.
  2. Submit a Condor job with malicious job attribute.
  3. Win the race condition.
  4. login as the new account having root privileges.

Cause:

race condition
failure to drop privileges

The cause of this vulnerability is using the open call in an unsafe fashion by using O_CREAT without the O_EXCL flag to create a file in the /tmp directory which can be exploited by a file system race condition.

Proposed Fix:

 

If it is necessary to create the debug files, the effective user and group ids should be dropped to an unprivileged user and group before creating the files in /tmp.

The file should also be created in a directory that is not world writable; one that is only used by the Gratia Condor probe.

Another possible solution is to create the file with the O_CREAT and O_EXCL flags, using sysopen in Perl. O_EXCL has the semantics that if the file already exists, sysopen fails. Using O_CREAT in conjunction with O_EXCL also prevents the file from being opened if it is a symbolic link.

Actual Fix:

 

The condor_meter.pl script was modified to create the debug files only when the debug flag was on. Also, changes were made to create the debug files in a directory that is only writable by root.

Acknowledgment:

 

This research funded in part by Department of Homeland Security grant FA8750-10-2-0030 (funded through AFRL).