Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2024-27630 PoC — GNU Savane 安全漏洞

Source
Associated Vulnerability
Title:GNU Savane 安全漏洞 (CVE-2024-27630)
Description:GNU Savane是美国GNU社区的一套合作软件发展管理系统。 GNU Savane v.3.12及之前版本存在安全漏洞,该漏洞源于存在不安全直接对象引用,允许远程攻击者通过精心设计的输入来删除任意文件。
Description
CVE-2024–27630 Reference
Readme
# CVE-2024–27630 Vulnerability Details

## Overview

In Savane v3.12 and prior, a lack of validation on the `file_id` parameter when deleting a file from `/bugs/index.php` leads to an Insecure Direct Object Reference (IDOR) vulnerability that can cause an authenticated administrator of a group with a bug tracker to arbitrarily delete file attachments of any bug tracker, leading to a lack of availability of these files. Since the file IDs increment with each new upload, it is possible to create a script that iteratively deletes all file attachments on the server by `file_id`.

**CWE Classification:** CWE-639: Authorization Bypass Through User-Controlled Key

**Reported By:** Ally Petitt 

**Affected Product**: Savane

**Affected Versions**: 3.12 and prior

## Technical Details

The function responsible for deleting file attachments on bug trackers is `trackers_data_delete_file()`, which is defined in the code block below. 

_frontend/php/include/trackers/data.php:2417_
```
function trackers_data_delete_file ($group_id, $item_id, $file_id)
{
  global $sys_trackers_attachments_dir;
  # Make sure the attachment belongs to the group.
  $res = db_execute ("
    SELECT bug_id from " . ARTIFACT . " WHERE bug_id = ? AND group_id = ?",
    [$item_id, $group_id]
  );
  if (db_numrows ($res) <= 0)
    {
      # TRANSLATORS: the argument is item id (a number).
      $msg = sprintf (
        _("Item #%s doesn't belong to project"), $item_id
      );
      fb ($msg, 1);
      return;
    }

  $result = false;
  # Delete the attachment.
  if (unlink ("$sys_trackers_attachments_dir/$file_id")) 
    $result = db_execute ("
      DELETE FROM trackers_file WHERE item_id = ?  AND file_id = ?",
      [$item_id, $file_id]
    );
```

The function begins with a SQL query to verify that the group that the bug ID specified in `item_id` is in the group that the attacker is a part of, known as the `$group_id`. The function fails to check whether the `file_id` is part of the group as well, meaning that as long as the `item_id` cooresponds to a valid bug in the attacker's group, the attacker can modify the `file_id` to point to any file within the upload directory `/var/lib/savane/trackers_attachments`. 

Additionally, this function is only reachable for bug tracker admins.

_frontend/php/bugs/index.php:586_
```
  case 'delete_file':
    # Remove an attached file.
    if ($is_trackeradmin)
      {
        trackers_data_delete_file($group_id, $item_id, $item_file_id);

         # Unset previous settings and return to the item.
         $depends_search = $reassign_change_project_search = $add_cc
           = $input_file = $changed = $vfl = $details = null;
         include '../include/trackers_run/mod.php';
      }
    else
      exit_permission_denied ();
    break;
```

## Validation Steps
These steps demonstrate deleting one file that is unauthorized, however, note that an attacker could automate the deletion of all files by their ID since they are predictable.

1. Have an account that is an admin of a group with a bugtracker (attacker account).
2. With a separate user account (victim), upload a file attachment in a bug report to a group that the attacker is not an admin of. A sample of the subsequent upload directory is as follows where the file `40231` was uploaded by the victim:

```
root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226  40227  40230  40231
```

3. Visit the homepage of the group that the attacker is an admin of. Then, visit Bugs > Browse and note a valid Item ID on the leftmost column of the table. This ID will be used in the next step.
4. As the attacker, make a get request to the path /bugs/index.php?func=delete_file&item_id=<ATTACKER_ITEM_ID>&item_file_id=<FILE_ID_TO_DELETE>.

    In my case, this looks like http://172.17.0.2:7890/bugs/index.php?func=delete_file&item_id=50697&item_file_id=40231.

5. Verify that the victim’s file (from a group the attacker doesn’t have privileges on) has been deleted. For example:

```
root@60ae93fe131f:/var/lib/savane/trackers_attachments# ls
40226  40227  40230
```


## Mitigation

Upgrade to Savane version 3.13 or higher. The patch can be found [here](https://git.savannah.nongnu.org/cgit/administration/savane.git/commit/?h=i18n&id=39180aea8f38425035b4d1e73819b58007ac6e83).



File Snapshot

[4.0K] /data/pocs/4e746c6b80655c9ff080b9770c7d35e99d7ebeb1 └── [4.2K] README.md 0 directories, 1 file
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.