-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(scenarios): add build a backdoor
- Loading branch information
1 parent
a60d226
commit 1b9c39e
Showing
14 changed files
with
9,090 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
category: KubeCon | ||
difficulty: KubeCon | ||
kind: cp.simulator/scenario:1.0.0 | ||
objective: Undo Kubernetes controls to allow access to an exploitable application | ||
tasks: | ||
"1": | ||
hints: | ||
sortOrder: 1 | ||
startingPoint: | ||
mode: pod | ||
podName: jumpbox-terminal | ||
podNamespace: dmz | ||
summary: Can you build a backdoor for Hashjack to exploit? | ||
name: build-a-backdoor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
|
||
- name: Build a Backdoor | ||
hosts: bastion:master-1 | ||
become: yes | ||
vars: | ||
state: present | ||
socat_target_ip: "{{ hostvars['master-1']['ansible_facts']['default_ipv4']['address'] }}" | ||
roles: | ||
- build-a-backdoor | ||
- socat |
7,888 changes: 7,888 additions & 0 deletions
7,888
scenarios/roles/build-a-backdoor/files/manifests/01-kyverno-install.yaml
Large diffs are not rendered by default.
Oops, something went wrong.
77 changes: 77 additions & 0 deletions
77
scenarios/roles/build-a-backdoor/files/manifests/02-netpol-policies.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-networkpolicy-empty-podselector | ||
annotations: | ||
policies.kyverno.io/title: Restrict NetworkPolicy with Empty podSelector | ||
policies.kyverno.io/category: Other, Multi-Tenancy | ||
policies.kyverno.io/severity: medium | ||
policies.kyverno.io/subject: NetworkPolicy | ||
policies.kyverno.io/description: >- | ||
By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all | ||
network traffic is unencrypted. It is recommended to not use an empty podSelector in order to | ||
more closely control the necessary traffic flows. This policy requires that all NetworkPolicies | ||
other than that of `default-deny` not use an empty podSelector. | ||
spec: | ||
validationFailureAction: enforce | ||
background: true | ||
rules: | ||
- name: empty-podselector | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- NetworkPolicy | ||
exclude: | ||
any: | ||
- resources: | ||
kinds: | ||
- NetworkPolicy | ||
names: | ||
- default-deny | ||
validate: | ||
message: "SECOPS ALERT: NetworkPolicies must not use an empty podSelector." | ||
deny: | ||
conditions: | ||
any: | ||
- key: "{{request.object.spec.podSelector.keys(@) | length(@)}}" | ||
operator: Equals | ||
value: 0 | ||
--- | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-networkpolicy-allow-all-ingress | ||
annotations: | ||
policies.kyverno.io/title: Restrict NetworkPolicy with Allow All Ingress | ||
policies.kyverno.io/category: Other, Multi-Tenancy | ||
policies.kyverno.io/severity: medium | ||
policies.kyverno.io/subject: NetworkPolicy | ||
policies.kyverno.io/description: >- | ||
By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all | ||
network traffic is unencrypted. This custom policy prevents allow any ingress rules. | ||
spec: | ||
validationFailureAction: enforce | ||
background: true | ||
rules: | ||
- name: restrict-allow-all-ingress | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- NetworkPolicy | ||
exclude: | ||
any: | ||
- resources: | ||
kinds: | ||
- NetworkPolicy | ||
names: | ||
- default-deny | ||
validate: | ||
message: "SECOPS ALERT: NetworkPolicies must not use an allow all ingress." | ||
deny: | ||
conditions: | ||
any: | ||
- key: "{{request.object.spec.ingress[].ports[].keys(@) | length(@) }}" | ||
operator: Equals | ||
value: 0 |
33 changes: 33 additions & 0 deletions
33
scenarios/roles/build-a-backdoor/files/manifests/03-nodeport-policy.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-nodeport | ||
annotations: | ||
policies.kyverno.io/title: Disallow NodePort | ||
policies.kyverno.io/category: Best Practices | ||
policies.kyverno.io/minversion: 1.6.0 | ||
policies.kyverno.io/severity: medium | ||
policies.kyverno.io/subject: Service | ||
policies.kyverno.io/description: >- | ||
A Kubernetes Service of type NodePort uses a host port to receive traffic from | ||
any source. A NetworkPolicy cannot be used to control traffic to host ports. | ||
Although NodePort Services can be useful, their use must be limited to Services | ||
with additional upstream security checks. This policy validates that any new Services | ||
do not use the `NodePort` type. | ||
spec: | ||
validationFailureAction: enforce | ||
background: true | ||
rules: | ||
- name: validate-nodeport | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- Service | ||
namespaces: | ||
- ii-prod | ||
validate: | ||
message: "SECOPS ALERT: Services of type NodePort are restricted." | ||
pattern: | ||
spec: | ||
=(type): "!NodePort" |
205 changes: 205 additions & 0 deletions
205
scenarios/roles/build-a-backdoor/files/manifests/04-ingress-policies.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: disallow-ingress-nginx-custom-snippets | ||
annotations: | ||
policies.kyverno.io/title: Disallow Custom Snippets | ||
policies.kyverno.io/category: Security, NGINX Ingress | ||
policies.kyverno.io/subject: ConfigMap, Ingress | ||
policies.kyverno.io/minversion: "1.6.0" | ||
kyverno.io/kyverno-version: "1.6.0" | ||
kyverno.io/kubernetes-version: "1.23" | ||
policies.kyverno.io/description: >- | ||
Users that can create or update ingress objects can use the custom snippets | ||
feature to obtain all secrets in the cluster (CVE-2021-25742). This policy | ||
disables allow-snippet-annotations in the ingress-nginx configuration and | ||
blocks *-snippet annotations on an Ingress. | ||
See: https://github.com/kubernetes/ingress-nginx/issues/7837 | ||
spec: | ||
validationFailureAction: enforce | ||
rules: | ||
- name: check-config-map | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- ConfigMap | ||
validate: | ||
message: "ingress-nginx allow-snippet-annotations must be set to false" | ||
pattern: | ||
=(data): | ||
=(allow-snippet-annotations) : "false" | ||
- name: check-ingress-annotations | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- networking.k8s.io/v1/Ingress | ||
validate: | ||
message: "SECOPS ALERT: Blocking attempted Nginx exploit" | ||
pattern: | ||
metadata: | ||
=(annotations): | ||
X(*-snippet): "?*" | ||
--- | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-annotations | ||
annotations: | ||
policies.kyverno.io/title: Restrict NGINX Ingress annotation values | ||
policies.kyverno.io/category: Security, NGINX Ingress | ||
policies.kyverno.io/severity: high | ||
policies.kyverno.io/subject: Ingress | ||
policies.kyverno.io/minversion: "1.6.0" | ||
kyverno.io/kyverno-version: "1.6.0" | ||
kyverno.io/kubernetes-version: "1.23" | ||
policies.kyverno.io/description: >- | ||
This policy mitigates CVE-2021-25746 by restricting `metadata.annotations` to safe values. | ||
See: https://github.com/kubernetes/ingress-nginx/blame/main/internal/ingress/inspector/rules.go. | ||
This issue has been fixed in NGINX Ingress v1.2.0. For NGINX Ingress version 1.0.5+ the | ||
"annotation-value-word-blocklist" configuration setting is also recommended. | ||
Please refer to the CVE for details. | ||
spec: | ||
validationFailureAction: enforce | ||
rules: | ||
- name: check-ingress | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- networking.k8s.io/v1/Ingress | ||
validate: | ||
message: "SECOPS ALERT: Blocking attempted Nginx exploit" | ||
deny: | ||
conditions: | ||
any: | ||
- key: "{{request.object.metadata.annotations.values(@)[].regex_match('\\s*alias\\s*.*;', @)}}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{request.object.metadata.annotations.values(@)[].regex_match('\\s*root\\s*.*;', @)}}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{request.object.metadata.annotations.values(@)[].regex_match('/etc/(passwd|shadow|group|nginx|ingress-controller)', @)}}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{request.object.metadata.annotations.values(@)[].regex_match('/var/run/secrets', @)}}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{request.object.metadata.annotations.values(@)[].regex_match('.*_by_lua.*', @)}}" | ||
operator: AnyIn | ||
value: [true] | ||
--- | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-ingress-paths | ||
annotations: | ||
policies.kyverno.io/title: Restrict NGINX Ingress path values | ||
policies.kyverno.io/category: Security, NGINX Ingress | ||
policies.kyverno.io/severity: high | ||
policies.kyverno.io/subject: Ingress | ||
policies.kyverno.io/minversion: "1.6.0" | ||
kyverno.io/kyverno-version: "1.6.0" | ||
kyverno.io/kubernetes-version: "1.23" | ||
policies.kyverno.io/description: >- | ||
This policy mitigates CVE-2021-25745 by restricting `spec.rules[].http.paths[].path` to safe values. | ||
Additional paths can be added as required. This issue has been fixed in NGINX Ingress v1.2.0. | ||
Please refer to the CVE for details. | ||
spec: | ||
validationFailureAction: enforce | ||
rules: | ||
- name: check-paths | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- networking.k8s.io/v1/Ingress | ||
validate: | ||
message: "SECOPS ALERT: Blocking attempted Nginx exploit" | ||
deny: | ||
conditions: | ||
any: | ||
- key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc') }}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/secrets') }}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/root') }}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/kubernetes/serviceaccount') }}" | ||
operator: AnyIn | ||
value: [true] | ||
- key: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc/kubernetes/admin.conf') }}" | ||
operator: AnyIn | ||
value: [true] | ||
--- | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-ingress-classes | ||
annotations: | ||
policies.kyverno.io/title: Restrict Ingress Classes | ||
policies.kyverno.io/category: Sample | ||
policies.kyverno.io/severity: medium | ||
policies.kyverno.io/subject: Ingress | ||
policies.kyverno.io/minversion: 1.6.0 | ||
policies.kyverno.io/description: >- | ||
Ingress classes should only be allowed which match up to deployed Ingress controllers | ||
in the cluster. Allowing users to define classes which cannot be satisfied by a deployed | ||
Ingress controller can result in either no or undesired functionality. This policy checks | ||
Ingress resources and only allows those which define `HAProxy` or `nginx` in the respective | ||
annotation. This annotation has largely been replaced as of Kubernetes 1.18 with the IngressClass | ||
resource. | ||
spec: | ||
validationFailureAction: enforce | ||
background: true | ||
rules: | ||
- name: validate-ingress | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- Ingress | ||
validate: | ||
message: "SECOPS ALERT: Unknown Ingress Class defined" | ||
pattern: | ||
metadata: | ||
annotations: | ||
kubernetes.io/ingress.class: "nginx" | ||
--- | ||
apiVersion: kyverno.io/v1 | ||
kind: ClusterPolicy | ||
metadata: | ||
name: restrict-web-port-removal | ||
annotations: | ||
policies.kyverno.io/title: Restrict Web Port Removal | ||
policies.kyverno.io/category: Sample | ||
policies.kyverno.io/severity: medium | ||
policies.kyverno.io/subject: Ingress | ||
policies.kyverno.io/minversion: 1.6.0 | ||
policies.kyverno.io/description: >- | ||
The Ingress Web Port must not be removed to persist the service. | ||
spec: | ||
validationFailureAction: enforce | ||
background: true | ||
rules: | ||
- name: restrict-web-port-removal | ||
match: | ||
any: | ||
- resources: | ||
kinds: | ||
- Ingress | ||
validate: | ||
message: "SECOPS ALERT: Removal of the Web Port is restricted" | ||
pattern: | ||
spec: | ||
rules: | ||
- http: | ||
^(paths): | ||
- backend: | ||
service: | ||
port: | ||
number: 80 |
Oops, something went wrong.