Rhino Security Labs

The Healthcare Industry is a large target for many online attacks.

Operation OwnedCloud: Exploitation and Post-exploitation Persistence

For a recent engagement, Rhino Security Lab’s was recruited to assess an internal network whose predominant operating system was Windows. After running tertiary scans and audits, nothing seemed to jump out at us besides an open OwnCloud webserver. Owncloud is a private storage solution that is easy to install and customize based on your environment.

Normally a login screen for any web app presents a problem for a penetration tester. To gain access one must have valid credentials, know of an authentication bypass or simply find another way onto the machine; however, we were able to gain access to the machine using a username gathered from the reconnaissance phase using the first password we tried.

Once logged into the application we noticed that this user had access to a shared folder that represented an external SMB storage device. We were able to determine that this folder was not accessible by everyone when monitoring requests through our intercepting proxy, as the apps/files_external/userglobalstorages/ID endpoint leaked usernames that had access to this device including the administrative user. As our non-admin user, we attempted to upload a PHP shell since PHP files were allowed to be uploaded; however, we could not determine where it was located on the server and thus could not browse to it.

Connecting to an invalid SMB share using improper credentials led to the BAD_NETWORK_NAME error on default configurations of SMB servers.

The faulty logic of the SMB authentication app returns a login if the only error thrown is “NT_STATUS_BAD_NETWORK_NAME”, meaning any username/password will work to login for default samba SMB server installations.

With nothing left in the tank, we decided to brute force the administrative account credentials. Surprisingly the first set of account credentials worked again of admin:admin. Logging in twice in a row on your first guess of credentials seemed too good to be true, and thus we decided to explore the web administrative console. This client had enabled external SMB authentication mechanisms so they would not have to create a new user for each previous SMB storage user; however, this is where the logic flaw laid. OwnCloud attempts to authenticate any current login by using the command “smbclient -L //host/dummy -Uusername%password”, where host in the SMB host, and the username and password are given at the login screen. However, in default SMB servers this command will return a listing of shares even if the user requesting them does not exist. The problem is that the SMB variable “map to guest” is not set to “never” by default, allowing for anyone to login using any username and password combination they pleased. Moreover, if the user did not exist before logging in with these fake credentials one would be created. To compound this, the external SMB storage they were using to store files had the actual username and password leaked in the administrative console as well.

In the administrative OwnCloud console, passwords for the external storage devices are stored in cleartext.

Thanks to the faulty authentication protocol used in the external authentication app, we were able to gain web admin but had yet to gain a foothold on the machine. After installing OwnCloud it was discovered that the data directory for all user files would, by default, be installed under the webroot in which OwnCloud was located. Further, after creating the data directory in this unsafe location OwnCloud failed to update the “.htaccess” file allowing a user to browse to their own files. As a simple proof of concept to see if the data directory was left within the host’s web-root, we browsed to the https://hostname/owncloud/data url and was not greeted with a 403 or redirect, and thus deduced we could browse to our file. We browsed to our previously uploaded PHP file located at https://hostname/data/username/files/cmd.php and began executing commands on the machine!

After setting up a replica of the client OwnCloud configuration on AWS, we uploaded our PHP shell and gained code execution.

Finally, our foothold had been established on the machine locally as the web user “www-data”. This foothold is a fragile one however as we had left a large indicator that our file, cmd.php, still uploaded under the compromised account. For post-exploitation persistence we decided to use the faulty SMB authentication command. When reading the source code both username and password are escaped for shell arguments but the host parameter was not. This allowed us to edit the configuration file and change the SMB host it authenticated against to run a reverse shell to our attacking machine each time a user attempted to login. Once we validated the command was running each time a user tried to login to the web app, we removed our “cmd.php” file and had established a strong backdoor onto the system.

VULNERABILITY DISCLOSURE

At the time of writing this, NextCloud has patched the authentication bypass vulnerability, while OwnCloud has chosen not to.
Disclosure Timeline:

  • Jun 28th: Authentication bypass disclosure to OwnCloud via HackerOne report.
  • Jul 1st: Response from OwnCloud investigating.
  • Jul 27th: Inquiry by Rhino Security Labs for an update.
  • Aug 2nd: Another inquiry for an update by Rhino Security Labs.
  • Aug 10th: NextCloud responder joins the ticket and recognizes vulnerability. Solution figured out.
  • Aug 22nd: Update requested by Rhino Security Labs on progress.
  • Sep 7th: Second OwnCloud representative joins conversation and says that they “Fail to see the impact” of the vulnerability.
  • Sep 12th: NextCloud recognizes the bypass and will integrate the solution into their application.
  • Sep 28th: NextCloud patches the application (https://nextcloud.com/changelog/).
  • Oct 11th: Advisory released. (https://nextcloud.com/security/advisory/?id=nc-sa-2016-006)
  • Nov 10th: OwnCloud advisory released. (https://owncloud.org/security/advisory/?id=oc-sa-2016-017)