Show Notes

195 - Stealing Secrets with Security Advisories and CorePlague

A nice use of the a CRLF Injection to exploit a seemingly unexploitable injection because the browser wouldn’t render the page when a Location header was present. Basically just used the CRLF injection ot inject a Connection: Location header, telling the proxy to treat the Location header as a hop-by-hop header and drop it before passing it on to the end-user. Without the location header present even though it was a HTTP 302 response the browser would render the page with attacker controlled content.

A lot of wrong turns, eventually leading to some parameter brute forcing and the discovery of an href param when submitting a Forgot Password request. The href value would be used to craft the forgot password link with the actual token appended to it that is reflected in the Forgot Password email. If any victim were to click the link in the email (which originates legitimately from HubSpot) they’d be taken to an attacker controlled location revealing the token to the attacker.

An information disclosure in GitHub through the Security Advisories feature. GitHub allows maintainers to draft public advisories, and in doing so you can create a temporary private fork to collaborate on and review fixes without disclosing them publicly. Around November of last year, GitHub added the ability for organizations to allow external users to report vulns to their public repositories. In these cases, the reporter is added as a collaborator to the vuln report and gets some special permissions to comment on the advisory and such. When a private fork is made, the reporter is also automatically added as a collaborator to the repo with limited access.

However, the access wasn’t limited enough, as they could still access the codespace feature (GitHub’s cloud-hosted dev environment for collaboration). As part of that, codespace secrets is used for storing API keys, SSH keys, passwords, tokens, etc. A malicious user can utilize their access via the private fork to access codespace and exfiltrate those secrets from the environment via env.

The XSS here is fairly basic, attacker controlled data reflected without sanitization, whats a bit more interesting is the input source, plugin metadata processed by the global Jenkin’s Update Center. There is a bit of a process to getting plugins listed in the Update Center, submitted a PR and the first plugin needs to be manually approved, though the authors note that this is mostly a procedural thing. Once approved though an attacker could update their plugins without any additional process.

From the plugin metadata, the Jenkins-Version (this is supposed to be the minimum required Jenkins version) value may be reflected in two locations one is on the update.jenkins.io domain and the other on the actual Jenkins server.

CVE-2023-27905 - When access the plugin’s page directly on the update.jenkins.io the required Jenkins version is reflected directly onto the page without sanitization. Resulting on XSS on that domain. CVE-2023-27898 - On the Jenkins server available plugins can be listed, in this list a version check is performed, comparing the required version to the server’s version. If the server’s version is earlier than the required version then a warning message will be displayed. Again, reflecting the required version without an sanitization this time resulting in XSS on the Jenkins server.

There is a bit of a hurdle to overcome with the second instance though, The Update Center generates a number of JSON files containing all the plugins that are compatible with each version of Jenkins. When a server requests theplugins list, it is essentially already filtering out those that are incompatible and so a malicious plugin with a high version simply would never be seen by anyone. The exception to this is very old versions, the Update Center only maintains the files going back so far, so versions older than the oldest maintained version (approximately 400 days old) will display plugins compatible with the oldest maintained list, so those instances may display the vulnerable warning.

With XSS on the Jenkins server, RCE is trivial given that the functionality of Jenkins is to run code. A POST to the /script endpoint can result in code execution from a provided Groovy script.