May 7, 2018

CVE Number

Summary

Multiple exploitable remote command injection vulnerabilities exist
in the MySQL Master-Master Replication Manager (MMM) mmm_agentd
daemon 2.2.1. mmm_agentd commonly runs with root privileges and does not
require authentication by default. A specially crafted MMM protocol
message can cause a shell command injection resulting in arbitrary
command execution with the privileges of the mmm_agentd process. An
attacker that can initiate a TCP session with mmm_agentd can trigger
these vulnerabilities.

Tested Versions

MMM 2.2.1

Product URLs

http://mysql-mmm.org/

CVSSv3 Score

9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

CWE

CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection')

Details

MMM, the Multi-Master Replication Manager for MySQL, provides high
availability to MySQL database clusters. Though superseded by more
modern approaches, MMM was commonly used in high availability MySQL
environments up through MySQL version 5.5. In an MMM environment,
each MySQL server host runs the mmm_agentd agent. In its default
configuration, mmm_agentd does not require authentication and
typically runs as root because it requires sufficient privileges to
reconfigure network interfaces.

mmm_agentd contains multiple remotely exploitable command injection
vulnerabilities. Therefore, in many MMM environments, if an
unauthenticated network attacker can make a TCP connection to the
mmm_agentd process, they can run arbitrary commands as root. This
vulnerability occurs because mmm_agentd includes attacker-supplied
input in shell commands in multiple locations without appropriate
sanitization.

For example, the MMM SET_STATUS protocol message can be used to
assign a number of roles to an mmm_agentd host. Roles are specified
as a comma-separated list of role_name(ip_addr) pairs
(e.g. role_a(10.10.10.10),role_b(10.10.10.11)).
MMM::Common::Role::from_string() in lib/Common/Role.pm uses the
following regular expression to parse the role name and IP address:
/(.*)\((.*)\)/. Thus, everything before the last opening
parenthesis will interpreted as the role name and all remaining
characters up to the last closing parenthesis will be interpreted as
the role IP address. An attacker can construct malicious IP address
values that will cause subsequent role handling code to invoke
arbitrary commands. For example:

role_a(10.10.10.10`malicious_command`)

Malicious IP address values are subject to interpretation by the shell
both in mmm_agentd and in helper applications called by mmm_agentd.

Role IP address values should be validated to ensure that only
expected values are specified. However, because other data flows may
allow malicious input to reach vulnerable functions, all dynamic
values incorporated into shell commands should be sanitized to ensure
that shell metacharacters do not introduce additional arguments or
execute unintended commands.

Limitations:

Due to the mmm_agentd protocol format, injected commands cannot
contain the following characters: ',', '|', '(', and '\n'

CVE-2017-14474 - MMM::Agent::Helpers::_execute()

The MMM::Agent::Helpers::_execute() function accepts a command and
an string containing arguments for the command. It constructs a
Bourne shell command line by concatenating the path to the requested
command, the mmm_agentd config file, and the specified arguments.
_execute() runs the resulting command using the the Perl backtick
operator as follows.

Because _execute() does not sanitize $params, any shell
metacharacters present in $params will be interpreted by the shell.

There are several code paths that can cause _execute() to be called
with untrusted input in the $params variable. To handle roles that
have been added and removed, mmm_agentd will invoke
MMM::Agent::Helpers::configure_ip($if, $ip) for each added role and
MMM::Agent::Helpers::clear_ip($if, $ip) for each deleted role with
$ip set to the IP address value specified for the role. Both,
functions pass $ip to _execute() without sanitization.

As noted above role IP addresses can contain arbitrary content, modulo
a few character restrictions, allowing an attacker to execute
arbitrary shell commands.

Additionally, the GET_SYSTEM_STATUS and CLEAR_BAD_ROLES MMM
protocol messages can be used to invoke
MMM::Agent::Helpers::check_ip($if, $ip) on the IP address value of
each role. check_ip() also passes the untrusted $ip value to
_execute() without further sanitization.

Because input may be derived from a variety of (potentially untrusted)
sources, _execute() should be modified to take an array of discrete
command arguments and to either avoid shell interpretation by using
execv-like functionality or quote command arguments to prevent shell
interpretation.

CVE-2017-14475 - MMM::Agent::Helpers::Network::add_ip() (Linux)

As seen above, in order to configure a new IP address mmm_agentd
invokes:

/path/to/agent/configure_ip /path/to/mmm_agent.conf $if $ip

To add the IP address to the specified interface, the configure_ip
helper command invokes MMM::Agent::Helpers::Network::add_ip().
Which runs the following command on Linux hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to add_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14476 - MMM::Agent::Helpers::Network::add_ip() (Solaris)

As seen above, in order to configure a new IP address mmm_agentd
invokes:

/path/to/agent/configure_ip /path/to/mmm_agent.conf $if $ip

To add the IP address to the specified interface, the configure_ip
helper command invokes MMM::Agent::Helpers::Network::add_ip().
Which runs the following command on Solaris hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to add_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14477 - MMM::Agent::Helpers::Network::add_ip() (FreeBSD)

As seen above, in order to configure a new IP address mmm_agentd
invokes:

/path/to/agent/configure_ip /path/to/mmm_agent.conf $if $ip

To add the IP address to the specified interface, the configure_ip
helper command invokes MMM::Agent::Helpers::Network::add_ip().
Which runs the following command on FreeBSD hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to add_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14478 - MMM::Agent::Helpers::Network::clear_ip() (Linux)

As seen above, to remove a deleted role's IP address, mmm_agentd
invokes:

/path/to/agent/clear_ip /path/to/mmm_agent.conf $if $ip

To remove the IP address from the specified interface, the clear_ip
helper command invokes MMM::Agent::Helpers::Network::clear_ip().
Which runs the following command on Linux hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to clear_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14479 - MMM::Agent::Helpers::Network::clear_ip() (Solaris)

As seen above, to remove a deleted role's IP address, mmm_agentd
invokes:

/path/to/agent/clear_ip /path/to/mmm_agent.conf $if $ip

To remove the IP address from the specified interface, the clear_ip
helper command invokes MMM::Agent::Helpers::Network::clear_ip().
Which runs the following command on Solaris hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to clear_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14480 - MMM::Agent::Helpers::Network::clear_ip() (FreeBSD)

As seen above, to remove a deleted role's IP address, mmm_agentd
invokes:

/path/to/agent/clear_ip /path/to/mmm_agent.conf $if $ip

To remove the IP address from the specified interface, the clear_ip
helper command invokes MMM::Agent::Helpers::Network::clear_ip().
Which runs the following command on FreeBSD hosts:

As a result, a malicious role IP address value that has been quoted to
prevent interpretation in MMM::Agent::Helpers::_execute() will
arrive to clear_ip() in unquoted form allowing the execution of
arbitrary commands.

CVE-2017-14481 - MMM::Agent::Helpers::Network::send_arp() (Solaris)

After a new IP address has been configured successfully, the
implementation of the configure_ip helper command will send
gratuitous ARPs:

send_arp() does not sanitize the value of $ip before interpolating
it into shell commands on Solaris systems. While dangerous, this
particular instance may not be currently exploitable because
send_arp() is only called if add_ip() succeeds and add_ip() will
return with failure if MMM::Agent::Helpers::Network::check_ip()
cannot verify that the IP address configuration attempt succeeded.
check_ip() currently attempts to match the the full text of the role
IP address against the value obtained from the operating system.
Thus, additional non-IP address characters in $ip will cause
check_ip() to return false:

Nevertheless, send_arp() should be fixed to sanitize its shell
command arguments as well, because this behavior may change in
subsequent releases.

Mitigation

The impact of these vulnerabilities can be lessened by configuring
mmm_agentd to require TLS mutual authentication and by using network
ACLs to prevent hosts other than legitimate mmm_mond hosts from
accessing mmm_agentd.

Generate unique mmm_agentd and mmm_mond CAs for MMM. mmm_agentd
and mmm_mond will accept any certificate signed by the CA that they
have been configured to trust. Therefore, to prevent non-MMM nodes
from connecting to mmm_agentd and to prevent malicious mmm_agentd
hosts from impersonating mmm_mond, fresh separate CAs should be
created to endorse mmm_agentd and mmm_mond certificates.