Month: May 2012

Recently, the new version 4.0 of the OwnCloud open-source software has been released. According to Wikipedia, “OwnCloud is a software suite that provides a location-independent storage area for data (cloud storage). The project was launched in January 2010 from KDE developer Frank Karlitschek to create a free alternative to commercial cloud providers. In contrast to commercial storage services, ownCloud can be installed on a private server at no additional cost“. So, anybody sensitive to the privacy of his own data, but still willing to store them in the cloud, might be tempted to install the feature-rich OwnCloud application on a dedicated server. Even more interestingly, the feature list of the latest version mentions the following:

Do you want to make sure that your files remain secure on the server? With the Encryption Application enabled, all files stored on the ownCloud server are encrypted to your password so not even the admin can look inside your files. Add to this an SSL connection, and your files are secure while in motion and at rest.

I did not resist to take a closer look at these claims…

The file encryption capabilities are implemented as the OC_Crypt class. Here is a quick summary of my findings:

The key is generated using four calls to the mt_rand() PHP routine, which implements the Mersenne Twister pseudo-random generator and is unfortunately not of cryptographic quality:

Let us assume a moment that the Mersenne Twister would be a cryptographically strong PRNG. Unfortunately, the seeding mechanism of the mt_rand() routine is also not very robust:

C

1

2

#define GENERATE_SEED() (((long) (time(0) * getpid())) ^\

((long)(1000000.0*php_combined_lcg(TSRMLS_C))))

Note that it depends on the current time, on the PID of the PHP interpreter and on a pseudo-random number taken out of another pseudo-random generator of the PHP engine. This one is a

C

1

2

3

4

5

6

/*

* combinedLCG() returns a pseudo random number in the range of (0, 1).

* The function combines two CGs with periods of

* 2^31 - 85 and 2^31 - 249. The period of this function

* is equal to the product of both primes.

*/

and is seeded as follows:

C

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

staticvoidlcg_seed(TSRMLS_D)

{

structtimeval tv;if(gettimeofday(&amp;tv,NULL)==0){

LCG(s1)=tv.tv_sec^(tv.tv_usec&lt;&lt;11);

}else{

LCG(s1)=1;

}

#ifdef ZTS

LCG(s2)=(long)tsrm_thread_id();

#else

LCG(s2)=(long)getpid();

#endif

/* Add entropy to s2 by calling gettimeofday() again */

if(gettimeofday(&amp;tv,NULL)==0){

LCG(s2)^=(tv.tv_usec&lt;&lt;11);

}

LCG(seeded)=1;

}

The computation of the overall entropy, and thus the effort to guess a key, is left to the reader… Not to mention the maximal achievable amount of bits of entropy, which are far from the recommended minimal value of 80 bits.

The generated key is encrypted using the provided user password with help of Blowfish in ECB mode and then stored in a file named encryption.key. Anybody able to steal this file will be in position to brute-force the password.

Note that this key is the same for all files stored by a same user, and that files are encrypted … server-side! So, the encryption key can be stolen in other scenarios:

The password encrypting it is transmitted in clear from the client to the server using the HTTP Basic mechanism. If the communication is not secured with HTTPS, then anybody able to snoop at the communication will steal the password, be able to access the OwnCloud account and get the data.

The encryption key is stored in clear in the session data

PHP

1

2

3

4

5

6

7

8

9

10

publicstaticfunctioninit($login,$password){

$view=newOC_FilesystemView('/'.$login);

OC_FileProxy::$enabled=false;

if(!$view-&gt;file_exists('/encryption.key')){// does key exist?

OC_Crypt::createkey($login,$password);

}

$key=$view-&gt;file_get_contents('/encryption.key');

OC_FileProxy::$enabled=true;

$_SESSION['enckey']=OC_Crypt::decrypt($key,$password);

}

Those session data are stored in clear on the server side, most of the time into the /tmp directory. Hence, a malicious OwnCloud server administrator will have no difficulty to decrypt data. Note that, as the encryption is performed server-side, a malicious sysadmin would have no difficulty to modify the OwnCloud application for recovering the data anyway.