Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 4a47e72

Browse files
committed
Add proper(ish) kube-hunter parser
1 parent 1fb2d85 commit 4a47e72

File tree

4 files changed

+128
-4
lines changed

4 files changed

+128
-4
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`parses result from kind-1.18-in-cluster-scan correctly 1`] = `
4+
Array [
5+
Object {
6+
"attributes": Object {
7+
"evidence": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkNabmY2NVgxUmR1ZnQzbHJVQVAzZFFUNjBiR0hUVE9SRDNPcURyenlkODgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imx1cmNoZXItdG9rZW4tcGpmNGIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoibHVyY2hlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjUzOGVhYjdmLTY1YjAtNDE4Yy04MGI2LTI1NGQxNDQ4ODU3NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Omx1cmNoZXIifQ.cGtQHagQ2xxlAFnWwFRNgGJIkaeZIKnqoYYb8GmxN94ry0wwxCbgBm4Kg33A903wDBxd8iuITTk-r8UPZyYJHoxlVu0pHt-3SAc4NT0ob50R2acVXQ2qj_yJOOQHurCWeOJMkGqtCyUoZ8Xcnc6z32Ao-NWzKD-0wV7ndpKm-ytHP0YpHb9bLUPcQGvFoh_UF132yjeJqzwLPRX6hStMYOa8LNhJGyhdejW3BIOylzVPNkKE5lEjWv9f853qnTKG-TzXHBbth7qV8UHwSoY8YFoMezK3zazQt4dN1VG_wYmZ0ujikTC7TRTGr500kFxfpACKwdQ1M1fXgKJhNv9UgA",
8+
"kubeHunterRule": "Access Secrets",
9+
},
10+
"category": "Access Risk",
11+
"description": " Accessing the pod service account token gives an attacker the option to use the server API ",
12+
"location": "10.244.0.1",
13+
"name": "Read access to pod's service account token",
14+
"reference": Object {
15+
"id": "KHV050",
16+
"source": "https://aquasecurity.github.io/kube-hunter/kb/KHV050",
17+
},
18+
"severity": "LOW",
19+
},
20+
Object {
21+
"attributes": Object {
22+
"evidence": "",
23+
"kubeHunterRule": "Pod Capabilities Hunter",
24+
},
25+
"category": "Access Risk",
26+
"description": "CAP_NET_RAW is enabled by default for pods. If an attacker manages to compromise a pod, they could potentially take advantage of this capability to perform network attacks on other pods running on the same node",
27+
"location": "10.244.0.1",
28+
"name": "CAP_NET_RAW Enabled",
29+
"reference": Object {},
30+
"severity": "LOW",
31+
},
32+
Object {
33+
"attributes": Object {
34+
"evidence": "['/var/run/secrets/kubernetes.io/serviceaccount/namespace', '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', '/var/run/secrets/kubernetes.io/serviceaccount/token', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/ca.crt', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/token', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/namespace']",
35+
"kubeHunterRule": "Access Secrets",
36+
},
37+
"category": "Access Risk",
38+
"description": " Accessing the pod's secrets within a compromised pod might disclose valuable data to a potential attacker",
39+
"location": "10.244.0.1",
40+
"name": "Access to pod's secrets",
41+
"reference": Object {},
42+
"severity": "LOW",
43+
},
44+
Object {
45+
"attributes": Object {
46+
"evidence": "v1.18.0",
47+
"kubeHunterRule": "Api Version Hunter",
48+
},
49+
"category": "Information Disclosure",
50+
"description": "The kubernetes version could be obtained from the /version endpoint ",
51+
"location": "10.96.0.1:443",
52+
"name": "K8s Version Disclosure",
53+
"reference": Object {
54+
"id": "KHV002",
55+
"source": "https://aquasecurity.github.io/kube-hunter/kb/KHV002",
56+
},
57+
"severity": "MEDIUM",
58+
},
59+
Object {
60+
"attributes": Object {
61+
"evidence": "b'{\\"kind\\":\\"APIVersions\\",\\"versions\\":[\\"v1\\"],\\"serverAddressByClientCIDRs\\":[{\\"clientCIDR\\":\\"0.0.0.0/0\\",\\"serverAddress\\":\\"172.17.0.2:6443\\"}]}\\\\n'",
62+
"kubeHunterRule": "API Server Hunter",
63+
},
64+
"category": "Information Disclosure",
65+
"description": " The API Server port is accessible. Depending on your RBAC settings this could expose access to or control of your cluster. ",
66+
"location": "10.96.0.1:443",
67+
"name": "Access to API using service account token",
68+
"reference": Object {
69+
"id": "KHV005",
70+
"source": "https://aquasecurity.github.io/kube-hunter/kb/KHV005",
71+
},
72+
"severity": "MEDIUM",
73+
},
74+
]
75+
`;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"nodes": [{"type": "Node/Master", "location": "10.244.0.1"}, {"type": "Node/Master", "location": "10.96.0.1"}], "services": [{"service": "Kubelet API", "location": "10.244.0.1:10250", "description": "The Kubelet is the main component in every Node, all pod operations goes through the kubelet"}, {"service": "Metrics Server", "location": "10.244.0.1:6443", "description": "The Metrics server is in charge of providing resource usage metrics for pods and nodes to the API server."}, {"service": "API Server", "location": "10.96.0.1:443", "description": "The API server is in charge of all operations on the cluster."}], "vulnerabilities": [{"location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)", "vid": "KHV050", "category": "Access Risk", "severity": "low", "vulnerability": "Read access to pod's service account token", "description": " Accessing the pod service account token gives an attacker the option to use the server API ", "evidence": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkNabmY2NVgxUmR1ZnQzbHJVQVAzZFFUNjBiR0hUVE9SRDNPcURyenlkODgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imx1cmNoZXItdG9rZW4tcGpmNGIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoibHVyY2hlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjUzOGVhYjdmLTY1YjAtNDE4Yy04MGI2LTI1NGQxNDQ4ODU3NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Omx1cmNoZXIifQ.cGtQHagQ2xxlAFnWwFRNgGJIkaeZIKnqoYYb8GmxN94ry0wwxCbgBm4Kg33A903wDBxd8iuITTk-r8UPZyYJHoxlVu0pHt-3SAc4NT0ob50R2acVXQ2qj_yJOOQHurCWeOJMkGqtCyUoZ8Xcnc6z32Ao-NWzKD-0wV7ndpKm-ytHP0YpHb9bLUPcQGvFoh_UF132yjeJqzwLPRX6hStMYOa8LNhJGyhdejW3BIOylzVPNkKE5lEjWv9f853qnTKG-TzXHBbth7qV8UHwSoY8YFoMezK3zazQt4dN1VG_wYmZ0ujikTC7TRTGr500kFxfpACKwdQ1M1fXgKJhNv9UgA", "hunter": "Access Secrets"}, {"location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)", "vid": "None", "category": "Access Risk", "severity": "low", "vulnerability": "CAP_NET_RAW Enabled", "description": "CAP_NET_RAW is enabled by default for pods. If an attacker manages to compromise a pod, they could potentially take advantage of this capability to perform network attacks on other pods running on the same node", "evidence": "", "hunter": "Pod Capabilities Hunter"}, {"location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)", "vid": "None", "category": "Access Risk", "severity": "low", "vulnerability": "Access to pod's secrets", "description": " Accessing the pod's secrets within a compromised pod might disclose valuable data to a potential attacker", "evidence": "['/var/run/secrets/kubernetes.io/serviceaccount/namespace', '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', '/var/run/secrets/kubernetes.io/serviceaccount/token', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/ca.crt', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/token', '/var/run/secrets/kubernetes.io/serviceaccount/..2020_04_03_14_52_24.460746409/namespace']", "hunter": "Access Secrets"}, {"location": "10.96.0.1:443", "vid": "KHV002", "category": "Information Disclosure", "severity": "medium", "vulnerability": "K8s Version Disclosure", "description": "The kubernetes version could be obtained from the /version endpoint ", "evidence": "v1.18.0", "hunter": "Api Version Hunter"}, {"location": "10.96.0.1:443", "vid": "KHV005", "category": "Information Disclosure", "severity": "medium", "vulnerability": "Access to API using service account token", "description": " The API Server port is accessible. Depending on your RBAC settings this could expose access to or control of your cluster. ", "evidence": "b'{\"kind\":\"APIVersions\",\"versions\":[\"v1\"],\"serverAddressByClientCIDRs\":[{\"clientCIDR\":\"0.0.0.0/0\",\"serverAddress\":\"172.17.0.2:6443\"}]}\\n'", "hunter": "API Server Hunter"}], "kburl": "https://aquasecurity.github.io/kube-hunter/kb/{vid}"}
Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
1-
async function parse() {
2-
return [];
1+
async function parse({ vulnerabilities = [], nodes = [] }) {
2+
return vulnerabilities.map(vulnerability => {
3+
const reference = {}
4+
5+
if ( vulnerability.vid !== "None") {
6+
reference.id = vulnerability.vid
7+
reference.source = `https://aquasecurity.github.io/kube-hunter/kb/${vulnerability.vid}`
8+
}
9+
10+
let location = vulnerability.location;
11+
if (location.startsWith('Local to Pod')) {
12+
// This is a pod specific vulnarability.
13+
// As this does not fit the secureCodeBox model to well we will scope this to the first "Node/Master" type node of the cluster.
14+
// This is subject to change.
15+
16+
for (const node of nodes) {
17+
if (node.type === "Node/Master") {
18+
location = node.location
19+
break;
20+
}
21+
}
22+
}
23+
24+
return {
25+
name: vulnerability.vulnerability,
26+
description: vulnerability.description,
27+
location,
28+
severity: vulnerability.severity.toUpperCase(),
29+
category: vulnerability.category,
30+
reference,
31+
attributes: {
32+
evidence: vulnerability.evidence,
33+
kubeHunterRule: vulnerability.hunter,
34+
}
35+
};
36+
});
337
}
438

539
module.exports.parse = parse;
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1-
test('passes', async () => {
2-
expect(true).toBe(true);
1+
const fs = require('fs');
2+
const util = require('util');
3+
4+
// eslint-disable-next-line security/detect-non-literal-fs-filename
5+
const readFile = util.promisify(fs.readFile);
6+
7+
const { parse } = require('./parser');
8+
9+
test('parses result from kind-1.18-in-cluster-scan correctly', async () => {
10+
const fileContent = JSON.parse(
11+
await readFile(__dirname + '/__testFiles__/kind-1.18-in-cluster-scan.json', {
12+
encoding: 'utf8',
13+
})
14+
);
15+
16+
expect(await parse(fileContent)).toMatchSnapshot();
317
});

0 commit comments

Comments
 (0)