7. What do we know ?
80
Internal IP
5000
https://github.com/snyk-labs/kubernetes-goof
8. What do we know ?
80
Internal IP
IP Address
5000
https://github.com/snyk-labs/kubernetes-goof
9. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Credentials
Pod Token
Available
inside pod
https://github.com/snyk-labs/kubernetes-goof
10. What do we know ?
80
Internal IP
IP Address
5000
External IP
https://github.com/snyk-labs/kubernetes-goof
11. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Credentials
Pod Token
Available
inside pod
Permissions
Pod Token
Allows access
to endpoints
API
https://github.com/snyk-labs/kubernetes-goof
12. What do we know ?
80
Internal IP
External IP
5000
https://github.com/snyk-labs/kubernetes-goof
13. What do we know ?
80
Internal IP
External IP
Default
Secure
IP Address
5000
https://github.com/snyk-labs/kubernetes-goof
14. confidential apiVersion: v1
kind: ServiceAccount
metadata: name: insecure
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: allow_pod_read
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs: ["create", "get", "watch", "list", "patch",
"delete", "deletecollection", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: allow_pod_read_bind
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: allow_pod_read
subjects:
- kind: ServiceAccount
name: insecure
● Allows service account too many permissions
● Likely bound to the ‘secure’ namespace
○ No permissions in the default namespace
Insecure Role
https://github.com/snyk-labs/kubernetes-goof
15. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Roles
Role
Gives service
account too
many
permissions in
namespace
Permissions
Pod Token
Allows access
to endpoints
API
Credentials
Pod Token
Available
inside pod
https://github.com/snyk-labs/kubernetes-goof
17. What do we know ?
80
Internal IP
External IP
IP Address
Secure Default
5000
https://github.com/snyk-labs/kubernetes-goof
18. confidential spec:
privileged: false
# Required to prevent escalations to root.
# allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege
escalation,
# but we can provide it for defense in depth.
volumes:
- '*'
runAsUser:
# Require the container to run without root
privileges.
rule: 'MustRunAsNonRoot'
seLinux:
# This policy assumes the nodes are using AppArmor
rather than SELinux.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
● Allows service account too many permissions
● Likely bound to the ‘secure’ namespace
○ No permissions in the default namespace
● allowPrivilegeEscalation is NOT redundant
Pod Security Policy
https://github.com/snyk-labs/kubernetes-goof
19. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Roles
Role
Gives service
account too
many
permissions in
namespace
Credentials
Pod Token
Available
inside pod
Permissions
Pod Token
Allows access
to endpoints
API
Permissions
PSP
Did not
disallow
privilege
escalation
https://github.com/snyk-labs/kubernetes-goof
20. What do we know ?
80
Internal IP
External IP
5000
Default
Secure
IP Address
IP Address
8080
https://github.com/snyk-labs/kubernetes-goof
21. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Roles
Role
Gives service
account too
many
permissions in
namespace
Credentials
Pod Token
Available
inside pod
Permissions
Pod Token
Allows access
to endpoints
API
Policy
Network
No network
controls in
place
Permissions
PSP
Did not
disallow
privilege
escalation
https://github.com/snyk-labs/kubernetes-goof
22. What do we know ?
80
Internal IP
External IP
5000
Default
Secure
IP Address
IP Address
5001
8080
https://github.com/snyk-labs/kubernetes-goof
23. What do we know ?
80
Internal IP
External IP
5000
Default
Secure
IP Address IP Address
8080
https://github.com/snyk-labs/kubernetes-goof
24. What do we know ?
80
Internal IP
External IP
5000
Default
Secure
IP Address IP Address
8080
PRIVILEGED
HOST
https://github.com/snyk-labs/kubernetes-goof
25. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Roles
Role
Gives service
account too
many
permissions in
namespace
Credentials
Pod Token
Available
inside pod
Permissions
Pod Token
Allows access
to endpoints
API
Permissions
PSP
Did not
disallow
privilege
escalation
Policy
Network
No network
controls in
place
Permissions
PSP
No
restrictions
in default ns
https://github.com/snyk-labs/kubernetes-goof
26. What do we know ?
5000
5000
Default
Secure
IP Address IP Address
8080
PRIVILEGED
Kube-System
HOST
https://github.com/snyk-labs/kubernetes-goof
27. What do we know ?
80
5000
Default
Secure
IP Address IP Address
8080
PRIVILEGED
Kube-System
HOST
https://github.com/snyk-labs/kubernetes-goof
28. Timeline of Doom
Time
Scope
Initial Exploit
App Vuln
Allows RCE in
container
Roles
Role
Gives service
account too
many
permissions in
namespace
Credentials
Pod Token
Available
inside pod
Permissions
Pod Token
Allows access
to endpoints
API
Permissions
PSP
Did not
disallow
privilege
escalation
Policy
Network
No network
controls in
place
Permissions
PSP
No
restrictions
in default ns
Game Over
Cluster
Cluster
admin
rights
gained
https://github.com/snyk-labs/kubernetes-goof
29.
30. confidential
● Scan your application code
● Scan your container images
● Scan your Kubernetes YAML
● Don’t trust defaults / Be explicit
● Use Network Policies
● Use Admission Controls
How could we have
prevented this ?
31. With thanks and props to :
Mark Manning ( @antitree ), Ian Coldwater ( @iancoldwater ),
Duffie Cooley ( @mauilion ) , Rory McCune ( @raesene )
K8s SIG-Security, CNCF TAG-Security, OpenSSF,
and many others in the Kubernetes Security community
@ericsmalling