BlackMarble

ZOHO - A Story Of Where Not To Store Keys

The second 0DayAllDay event was June 9th, 2018 from 10am to 9pm. It was organized by Spectant Security and Blackmarble.sh. More information on 0DayAllDay can be found here

Last 0DayAllDay event was focused around Password Managers, Thycotic, Keeper, ZOHO Vault were a some of the targets. Only bug that was found was for ZOHO Vault.

ZOHO Vault is an online password manager focused on businesses. Included in their software is a AD/LDAP provisioning application. The application ask some standard question like your master ZOHO Account Username and Password, Domain Administrator (What isn't really needed) Username and Password, connection details. After you fill this out, Application connects to the Domain Controller and you select the users you want to import into ZOHO Vault.

The AD/LDAP provisioning application stores the AES encryption key and IV in the source code. Obtaining these strings is trivial. You can use JetBrains.dotPeek for example to decompile the executable.

Once decompiled, you can see that Provisioning_Utils namespace has a CryptUtil class that uses a static string for both the Key and IV.

namespace Provisioning_Utils
{
    public class CryptUtil
{
private static UTF8Encoding encoding = new UTF8Encoding();
private static byte[] kBytes = CryptUtil.encoding.GetBytes("6ZUJiqpBKHuNuS@*");
private static byte[] tmpIV = CryptUtil.encoding.GetBytes("BJLTHGVTPJQMDEXO");

The vault.zoho.com account password and the Windows Administrator account password are stored in the provisioning.conf file as encrypted text. The Provisioning application can be ran on any computer on the domain. Access to this provisioning.conf file is not guaranteed to be protected. It some cases it would be fairly easy for unauthorized access to the provisioning.conf file.

I have successfully wrote a new standalone program that takes the encrypted text as an argument and decrypts the password showing the plain text password.

WorkingPoC

First, C# program I have made. It was pretty easy, just needed to copy and paste the decompiled code. Googled a few things, and surprisingly got it to build on the second try.

For full source code and binary check out my GitHub

You do need some other access to exploit this; however, for pentesters if they find this provisioning.conf file game over. Gain access to all the passwords saved on ZOHO Vault (Edit: You need a secondary password to decrypt the Vault) and have Domain Admin. It was reckless to have the keys to your kingdom so easily available.

ZOHO issued me their own CVE number: ZVE-2018-0976

Disclosure Timeline:
Found Vulnerability: June 8th, 2018
Disclosed to ZOHO: June 10th, 2018
ZOHO Closed: July 12th, 2018

Reward: Nothing :( 10 stupid points. I can't buy beer with points.

EDIT:

ZOHO Updates Ticket: July 13th, 2018

Reward: $100 and 10pts. We have beer money for the next event now.

After making a post I like to watch Google Analytics for my blog just to see the kind of response I get. Got a couple referrals from supportlab.zoho.com and docs.zoho.com less than a hour from posting on twitter. I think they have a twitter bot looking for their name. Anyways, they updated the ticket I had open with them.

response

It is true, I had an error. Even though you have the ZOHO Vault login password, you need a secondary encryption password to get access to the content (View Passwords).

They fixed the vulnerability by removing the unneeded ZOHO account password and using dynamic unique keys to encrypt scoped authentication token and AD Password for every installation.

Finial notes:

What this tells me is the Authentication token doesn't expire I thought this was true as I played around with it as well. Which was clear text before in the provisioning.conf. Now I am interested in the new way they are doing the keys. I'll have to take another look when I get some time.

Author image
About INIT_6
DFW Website
Jason is well known in the InfoSec field as an expert in hardware, web app, and mobile applications exploit research. Jason frequently speaks at security events, and active in the local community.