Bug 1107528 (CVE-2014-3486)

Summary: CVE-2014-3486 CFME: SSH Utility insecure tmp file creation leading to code execution as root
Product: [Other] Security Response Reporter: Kurt Seifried <kseifried>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: bdunne, dajohnso, dclarizi, gmccullo, jfrey, jrafanie, jrusnack, jvlcek, kseifried, lufu, mfeifer, obarenbo, security-response-team, xlecauch
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-06-30 23:23:18 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1107532, 1107533    
Bug Blocks: 1086525, 1107530    

Description Kurt Seifried 2014-06-10 06:59:18 UTC
Kurt Seifried of Red Hat Product Security reports:

========================================
./lib/util/MiqSshUtilV1.rb
  def shell_exec(cmd, doneStr=nil, shell=@shell)
    if shell
      # Writing to a temp remote script to handle cases where the cmd string is
      #   too long and is truncated.
      temp_remote_script = "/var/tmp/miq-#{Time.now.to_i}.sh"
      self.exec("echo \"#{cmd}\" > #{temp_remote_script}")
      self.exec("chmod 700 #{temp_remote_script}")
      out = shell.send_command(temp_remote_script)
      self.exec("rm -f #{temp_remote_script}")
      @status = out.status
      msg = out.stdout

      # Check if the first output return references the remote script and remove it.
      msgs = msg.split("\n")
      msg = msgs[1..-1].join("\n") if msgs[0].include?(temp_remote_script)

      raise "#{msg}" unless doneStr.nil? || msg.include?(doneStr)
      return msg
    else
      return self.exec(cmd, doneStr)
    end
  end
========================================
./lib/util/MiqSshUtilV2.rb
  def temp_cmd_file(cmd)
    temp_remote_script = "/var/tmp/miq-#{Time.now.to_i}.sh"
    self.exec("echo \"#{cmd}\" > #{temp_remote_script}")
    remote_cmd = "chmod 700 #{temp_remote_script}; #{temp_remote_script}; rm -f #{temp_remote_script}"
    yield(remote_cmd)
  end
========================================
Time.now.to_i = 1412123123
setup a file and a few hundred/thousand symlinks and you can cover an hour easily. 

Between the

self.exec("echo \"#{cmd}\" > #{temp_remote_script}")
self.exec("chmod 700 #{temp_remote_script}")

an attacker can replace the file, which is then executed as root.

It should use Ruby Tempfile:
http://kurt.seifried.org/2012/03/14/creating-temporary-files-securely/

Comment 2 Vincent Danen 2014-06-24 19:52:40 UTC
Acknowledgements:

This issue was discovered by Kurt Seifried of Red Hat Product Security.

Comment 3 errata-xmlrpc 2014-06-30 19:03:25 UTC
This issue has been addressed in following products:

  CloudForms Management Engine 5.x

Via RHSA-2014:0816 https://rhn.redhat.com/errata/RHSA-2014-0816.html