Talos Vulnerability Report

TALOS-2024-2061

Veertu Anka Build registry log files directory traversal vulnerability

October 3, 2024
CVE Number

CVE-2024-41922

SUMMARY

A directory traversal vulnerability exists in the log files download functionality of Veertu Anka Build 1.42.0. A specially crafted HTTP request can result in a disclosure of arbitrary files. An attacker can make an unauthenticated HTTP request to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Veertu Anka Build 1.42.0

PRODUCT URLS

Anka Build - https://veertu.com/anka-build/

CVSSv3 SCORE

7.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

CWE

CWE-22 - Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)

DETAILS

Anka Build is a suite of software tools designed for macOS virtualization, specifically for testing macOS or iOS applications in CI/CD environments. The suite comprises three main components: Controller, Registry, and Nodes. Anka Build Controller is centralized dashboard for managing nodes, VM instances, templates, tags, and logs. Anka Build Registry serves as the central repository for macOS VM templates and tags, facilitating easy access and version control. Anka Build Nodes are macOS hosts that run on-demand VM instances.

The default installation of the Controller LaunchDaemon runs on the port 80 and the Registry LaunchDaemon runs on the port 8089.

A directory traversal vulnerability exists in the Anka Build Controller and Registry LaunchDaemons. This vulnerability is triggered when an HTTP GET request is sent to the controller URI /api/v1/registry/log or to the Registry URI /log. Both requests ultimately invoke the veertu.com/veertu/registry/log_server.(*LogServer).HandleLogOutput method within the anka-registry binary. The decompiled code for the veertu.com/veertu/registry/log_server.(*LogServer).HandleLogOutput method is as follows:

  a2 = (unsigned int *)http_responsewriter.tab;
  v4 = net_url__ptr_URL_Query(x3_0->URL);
  service_param.ptr = (char *)&service;
  service_param.len = 7LL;
  service_value = net_url_Values_Get(v4, service_param); //<------------------- (1)
  if ( service_value.len )
  {
    v32.data = a2_8;
    v32.tab = a2;
    veertu_com_veertu_registry_log_server__ptr_LogServer_streamLog(a1, v32, a3, service_value); //<------------------- (2)
  }

At (1), the service parameter value is obtained from the URL. At (2), veertu.com/veertu/registry/log_server.(*LogServer).streamLog method is called. This method, in turn, calls veertu.com/veertu/registry/backend/disklogserver.(*Backend).TailServiceLog. The decompile code of veertu.com/veertu/registry/backend/disklogserver.(*Backend).TailServiceLog is as follows:

 while ( (unsigned __int64)&v12 <= *(_QWORD *)(v3 + 16) )
  {
    v19 = a1;
    ptr = service_value.ptr;
    len = service_value.len;
    runtime_morestack_noctxt(a1, service_value.ptr, service_value.len);
    a1 = v19;
    service_value.ptr = ptr;
    service_value.len = len;
  }
  LogFilePath = veertu_com_veertu_registry_backend_disklogserver__ptr_Backend_getLogFilePath(a1, service_value); //<---------------- (3)
  if ( LogFilePath.1.tab )
  {
    LogFilePath.0.ptr = 0LL;
    LogFilePath.0.len = (size_t)LogFilePath.1.tab;
    LogFilePath.1.tab = LogFilePath.1.data;
  }

  [...]

    v4 = os_Stat(LogFilePath.0.ptr, LogFilePath.0.len);
    filesize = (*(__int64 (__golang **)(__int64))(v4 + 56))(v5);
    v6 = runtime_newobject(&type_ZLVnh7lF);
    if ( filesize - 0x100000 > 0 )
      *v6 = filesize - 0x100000;
    LogFilePath.0.ptr = (char *)github_com_hpcloud_tail_TailFile(
                                  v18,
                                  v11,
                                  v6,
                                  1LL,
                                  1LL,
                                  1LL,
                                  0LL,
                                  0LL,
                                  (unsigned __int8)v12,
                                  v13,
                                  v14,
                                  v15);   //<---------------(4)

At (3), the TailServiceLog method invokes the veertu.com/veertu/registry/backend/disklogserver.(*Backend).getLogFilePath method. In getLogFilePath, the value of the service parameter is appended to the log directory path without any validation for directory traversal characters such as dot-dot-slash (../). Subsequently, the extension .log is added to the new path. This log path is returned by getLogFilePath and assigned to the LogFilePath variable.

At (4), the github.com/hpcloud/tail.TailFile method is called, which emulates the BSD tail program, displaying the last part of the file returned by the getLogFilePath method.

Here, the service HTTP Parameter is vulnerable to path traversal. By utilizing dot-dot-slash (../) sequences or their variations, it may be possible to access and download arbitrary log files from the system where the Registry LaunchDaemon is installed.

VENDOR RESPONSE

Fixed in 1.43.0 of the Anka Build Cloud.

TIMELINE

2024-08-12 - Vendor Disclosure
2024-08-12 - Initial Vendor Contact
2024-09-30 - Vendor Patch Release
2024-10-03 - Public Release

Credit

Discovered by KPC of Cisco Talos.