Security

Unraveling the VigorConnect Vulnerability: A Journey of Discovery and Correction

The article uncovers an Arbitrary File Read vulnerability in VigorConnect that lets attackers access sensitive files. The issue originates from improper input validation in file handling methods.

Thu 12 September 2024

Introduction

This article investigates an Arbitrary File Read vulnerability found in VigorConnect, a DrayTek VigorAP & VigorSwitch management server designed to automate tasks like firmware updates and configuration backups. By analyzing the decompiled code of the application, particularly the handling of file operations, we demonstrate how the vulnerability can be exploited to access sensitive files. We've confirmed the issue and pinpointed the code responsible for this flaw.

Initial Vulnerability Discovery

The Arbitrary File Read vulnerability was identified through several endpoints that allowed unauthorized file read operations. These endpoints indicate insecure handling of file paths and user input:

/ACSServer/DownloadFileServlet?table_action=Save&show_file_name=../../../../../../windows/win.ini&type=uploadfile&path=anything
/ACSServer/DownloadFileServlet?table_action=Save&show_file_name=../../../../../../etc/passwd&type=uploadfile&path=anything

These seemingly innocuous URLs are actually powerful skeleton keys, leading to unlocking access to sensitive system files across the entire server.

For this part, we downloaded the binary of VigorConnect/v1.5.2 from their official link and installed it in a local machine by following the steps in this Installation Guide.

The installation of VigorConnect requires sudo privileges. This elevated access allows the software to interact with system-level files and resources. As a result, we were able to confirm the arbitrary file read vulnerability by accessing sensitive files like /etc/passwd and windows/win.ini.

Code Analysis

Our journey to uncover the true nature of this vulnerability took us through a maze of code and assumptions. What started as a straightforward hypothesis evolved into a complex exploration, reminding us of the importance of thorough analysis whenever investigating a serious vulnerability.

Root Cause Analysis: Vulnerability in FileServerController

First, the binary was reversed using binwalk:

binwalk -e <binary>

The VigorConnect firmware used during this research is VigorConnectLinuxSetup_1.5.2. We confirmed CVE-2021-20123 in this version before moving forward with the investigation.

etc_passwd.png
etc/passwd

Inside the extracted contents, several binaries were found. The primary focus was placed on the VigorConnect binary.

disassembled_vigorconnect.png
Content of VigorConnectLinuxSetup

At first glance, when looking at the disassembled code for the VigorConnect binary, the culprit seemed obvious: the SaveToFile method within the Beego web framework. This method, responsible for saving uploaded files, appeared to lack proper input validation:

func (c *Controller) SaveToFile(fromfile, tofile string) error {
    file, _, err := c.Ctx.Request.FormFile(fromfile)
    if err != nil {
        return err
    }
    defer file.Close()
    f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
    if err != nil {
        return err
    }
    defer f.Close()
    io.Copy(f, file)
    return nil
}

The absence of checks to sanitize the tofile path seemed to be a textbook case of a vulnerability allowing directory traversal attacks. It was a compelling theory, one that many security researchers might have been tempted to run with. However, the journey to truth in cybersecurity is often more winding than we anticipate.

Driven by a nagging suspicion that there might be more to the story, we decided to dig deeper. This decision led us to employ more traditional debugging techniques, setting the stage for a revelation that would challenge our initial assumptions. Armed with the powerful GNU Debugger (GDB), we embarked on a more thorough investigation. The process was methodical:

  1. Started GDB with the VigorConnect binary: gdb ./VigorConnect
  2. Ran the program in debug mode: r -d &

img.png
Debugging VigorConnect Binary

After triggering the Arbitrary File Read Vulnerability, we started setting up breakpoints at multiple functions until one was triggered: os.OpenFile

  1. We set a breakpoint at the os.OpenFile function: br os.OpenFile and examined the function arguments: info args

br_at_osOpenFile.png
Breakpoint at os.OpenFile

The disassembled code for os.OpenFile was retrieved after opening the binary with Ghidra and applying all its analyzers:

osOpenFile_func.png
Disassembled os.OpenFile Function

This function seems to be a low-level file opening operation. It could potentially be exploited if not properly restricted, or if called with unsanitized input from a higher-level function.

  1. Traced back the call stack: bt 20

bt_20.png
Printing the Backtrace

Our analysis revealed the following key points:

  1. The vulnerable file path being accessed is /usr/local/VigorConnect/FileRoot/tftp./../../../../../etc/passwd.

vulnerable_file.png
Vulnerable File Path

BeegoOutput_Download.png
Disassembled BeegoOutput.Download Function

This is the Download method of the BeegoOutput struct from the Beego web framework. It's responsible for serving files for download.

The GDB output confirms that the function is being called with a vulnerable file path: /FileRoot/tftp./../../../../../etc/passwd

This path uses directory traversal (../) to access the /etc/passwd file, which is outside the intended directory.

The decompiled function doesn't show any clear path validation or sanitization. It directly uses the provided file path to call os.Stat and eventually net/http.ServeFile.

  1. This path is being processed by the Get method of the FileServerController.

FileServerController_GET.png
Args of FileServerController.GET Function

Let's now deep dive into what this method does from its disassembled code:

The method uses the Beego framework’s GetString function to retrieve query parameters from incoming HTTP requests, such as the filename or path to be downloaded:

github.com/astaxie/beego.(*Controller).GetString
((github.com/astaxie/beego.Controller *)self_00,key,
*([]string *)((long)register0x00000020 + -0x208),~r2_01);

These query parameters are directly used to determine which file to serve. Critically, there is no strict input validation or sanitization on these inputs, allowing attackers to inject directory traversal sequences (e.g., ../../../../../) to access files outside the intended directory.

The method then processes different types of requests, including ConfigDownload and uploadfile, both of which involve serving files to the client:

if (*plVar2 != 0x696664616f6c7075) {
  return;
}
if (*(short *)(plVar2 + 1) != 0x656c) {
  return;
}

In the case of file downloads, the method constructs a file path using user-provided input, which is then passed to the BeegoOutput.Download function. Since there is no input validation, an attacker can manipulate this path to point to sensitive system files.

The implications of this vulnerability extend far beyond mere technical curiosity. In the hands of malicious actors, this flaw could lead to unauthorized access to sensitive configuration files, exposure of user credentials, and potentially serve as a launching pad for more severe system compromises. For instance:

  • Database credentials: The app.conf file reveals that VigorConnect uses an SQLite database (DbType = sqlite3). An attacker could potentially access the database file at sqlite/VigorConnect.db, exposing all stored data.
  • HTTPS certificates: The file paths for HTTPSCertFile and HTTPSKeyFile are specified. Accessing these could compromise the SSL/TLS security of the entire system.
  • CLI credentials: The CliUser and CliPassword fields, if populated, could give an attacker direct command-line access to the system.
  • Log files: With AcsLog set to file and AcsLogSrc enabled, an attacker could access log files containing sensitive operational data and potentially user activities.
  • InfluxDB's configuration: The presence of an InfluxDB folder suggests that VigorConnect uses InfluxDB, likely for storing time-series data. The influxdb.conf file in this folder could contain database credentials and connection details.

These examples illustrate how this vulnerability could be exploited to gain deep access to the VigorConnect system, potentially compromising not just the management server but all connected network devices.

Conclusion

Our analysis not only confirms a critical Arbitrary File Read vulnerability in VigorConnect but also serves as a stark reminder of the constant vigilance required in cybersecurity. This flaw underscores the importance of rigorous code review, the principle of least privilege, and the need for defense in depth in software design. As we continue to rely more heavily on centralized management systems like VigorConnect, the security community must remain ever watchful, ready to uncover and address the next hidden threat lurking in our digital infrastructure.

We do newsletters, too


Get the latest news, updates, and product innovations from Ostorlab right in your inbox.

Table of Contents