PageSourceSearch

https://www.securecodebox.io/assets/js/edd86307.abea2889.js

js securecodebox.io collected 2026-10-03 23:18:12 UTC 33,218 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunksecurecodebox=globalThis.webpackChunksecurecodebox||[]).push([[6318],{6656(e,s,n){n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>t,toc:()=>h});const t=JSON.parse('{"id":"scanners/kube-hunter","title":"Kube Hunter","description":"Kubernetes Vulnerability Scanner","source":"@site/docs/scanners/kube-hunter.md","sourceDirName":"scanners","slug":"/scanners/kube-hunter","permalink":"/docs/scanners/kube-hunter","draft":false,"unlisted":false,"editUrl":"https://github.com/secureCodeBox/secureCodeBox/edit/main/scanners/kube-hunter/.helm-docs.gotmpl","tags":[],"version":"current","frontMatter":{"title":"Kube Hunter","category":"scanner","type":"Kubernetes","state":"released","appVersion":"0.6.8","usecase":"Kubernetes Vulnerability Scanner","description":"Kubernetes Vulnerability Scanner","custom_edit_url":"https://github.com/secureCodeBox/secureCodeBox/edit/main/scanners/kube-hunter/.helm-docs.gotmpl"},"sidebar":"docs","previous":{"title":"Gitleaks","permalink":"/docs/scanners/gitleaks"},"next":{"title":"Ncrack","permalink":"/docs/scanners/ncrack"}}');var r=n(4848),i=n(8453),c=n(4865),o=n(9365);const a={title:"Kube Hunter",category:"scanner",type:"Kubernetes",state:"released",appVersion:"0.6.8",usecase:"Kubernetes Vulnerability Scanner",description:"Kubernetes Vulnerability Scanner",custom_edit_url:"https://github.com/secureCodeBox/secureCodeBox/edit/main/scanners/kube-hunter/.helm-docs.gotmpl"},l=void 0,d={},h=[{value:"What is kube-hunter?",id:"what-is-kube-hunter",level:2},{value:"Deployment",id:"deployment",level:2},{value:"Scanner Configuration",id:"scanner-configuration",level:2},{value:"Requirements",id:"requirements",level:2},{value:"Values",id:"values",level:2},{value:"License",id:"license",level:2},{value:"CPU architectures",id:"cpu-architectures",level:2},{value:"Examples",id:"examples",level:2},{value:"in-cluster",id:"in-cluster",level:3}];function u(e){const s={a:"a",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{src:"https://raw.githubusercontent.com/aquasecurity/kube-hunter/main/kube-hunter.png",alt:"kube-hunter logo"})}),"\n",(0,r.jsxs)("p",{align:"center",children:[(0,r.jsx)("a",{href:"https://opensource.org/licenses/Apache-2.0",children:(0,r.jsx)("img",{alt:"License Apache-2.0",src:"https://img.shields.io/badge/License-Apache%202.0-blue.svg"})}),(0,r.jsx)("a",{href:"https://github.com/secureCodeBox/secureCodeBox/releases/latest",children:(0,r.jsx)("img",{alt:"GitHub release (latest SemVer)",src:"https://img.shields.io/github/v/release/secureCodeBox/secureCodeBox?sort=semver"})}),(0,r.jsx)("a",{href:"https://owasp.org/www-project-securecodebox/",children:(0,r.jsx)("img",{alt:"OWASP Lab Project",src:"https://img.shields.io/badge/OWASP-Lab%20Project-yellow"})}),(0,r.jsx)("a",{href:"https://artifacthub.io/packages/search?repo=securecodebox",children:(0,r.jsx)("img",{alt:"Artifact HUB",src:"https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/securecodebox"})}),(0,r.jsx)("a",{href:"https://github.com/secureCodeBox/secureCodeBox/",children:(0,r.jsx)("img",{alt:"GitHub Repo stars",src:"https://img.shields.io/github/stars/secureCodeBox/secureCodeBox?logo=GitHub"})}),(0,r.jsx)("a",{href:"https://infosec.exchange/@secureCodeBox",children:(0,r.jsx)("img",{alt:"Mastodon Follower",src:"https://img.shields.io/mastodon/follow/111902499714281911?domain=https%3A%2F%2Finfosec.exchange%2F"})})]}),"\n",(0,r.jsx)(s.h2,{id:"what-is-kube-hunter",children:"What is kube-hunter?"}),"\n",(0,r.jsx)(s.p,{children:"kube-hunter hunts for security weaknesses in Kubernetes clusters. The tool was developed to increase awareness and visibility for security issues in Kubernetes environments. You should NOT run kube-hunter on a Kubernetes cluster that you don't own!"}),"\n",(0,r.jsxs)(s.p,{children:["To learn more about the kube-hunter scanner itself visit ",(0,r.jsx)(s.a,{href:"https://github.com/aquasecurity/kube-hunter",children:"kube-hunter GitHub"})," or ",(0,r.jsx)(s.a,{href:"https://kube-hunter.aquasec.com/",children:"kube-hunter Website"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"deployment",children:"Deployment"}),"\n",(0,r.jsx)(s.p,{children:"The kube-hunter chart can be deployed via helm:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"# Install HelmChart (use -n to configure another namespace)\nhelm upgrade --install kube-hunter oci://ghcr.io/secureco
1debox/helm/kube-hunter\n"})}),"\n",(0,r.jsx)(s.h2,{id:"scanner-configuration",children:"Scanner Configuration"}),"\n",(0,r.jsxs)(s.p,{children:["The following security scan configuration example are based on the ",(0,r.jsx)(s.a,{href:"https://github.com/aquasecurity/kube-hunter#scanning-options",children:"kube-hunter Documentation"}),", please take a look at the original documentation for more configuration examples."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["To specify remote machines for hunting, select option 1 or use the --remote option. Example: ",(0,r.jsx)(s.code,{children:"kube-hunter --remote some.node.com"})]}),"\n",(0,r.jsxs)(s.li,{children:["To specify interface scanning, you can use the --interface option (this will scan all the machine's network interfaces). Example: ",(0,r.jsx)(s.code,{children:"kube-hunter --interface"})]}),"\n",(0,r.jsxs)(s.li,{children:["To specify a specific CIDR to scan, use the --cidr option. Example: ",(0,r.jsx)(s.code,{children:"kube-hunter --cidr 192.168.0.0/24"})]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(s.p,{children:["Kubernetes: ",(0,r.jsx)(s.code,{children:">=v1.11.0-0"})]}),"\n",(0,r.jsx)(s.h2,{id:"values",children:"Values"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Key"}),(0,r.jsx)(s.th,{children:"Type"}),(0,r.jsx)(s.th,{children:"Default"}),(0,r.jsx)(s.th,{children:"Description"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"cascadingRules.enabled"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"false"})}),(0,r.jsx)(s.td,{children:"Enables or disables the installation of the default cascading rules for this scanner"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"imagePullSecrets"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Define imagePullSecrets when a private registry is used (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.affinity"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["Optional affinity settings that control how the parser job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.env"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional environment variables mapped into each parseJob (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/",children:"https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.image.pullPolicy"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'"IfNotPresent"'})}),(0,r.jsxs)(s.td,{children:["Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if ",":latest"," tag is specified, or IfNotPresent otherwise. More info: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/containers/images#updating-images",children:"https://kubernetes.io/docs/concepts/containers/images#updating-images"})]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.image.repository"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'"docker.io/securecodebox/parser-kube-hunter"'})}),(0,r.jsx)(s.td,{children:"Parser image repository"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.image.tag"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:"defaults to the charts version"}),(0,r.jsx)(s.td,{children:"Parser image tag"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.nodeSelector"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["Optional nodeSelector settings that control how the scanner job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.resources"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'{ requests: { cpu: "200m", memory: "100Mi" }, limits: { cpu: "400m", memory: "200Mi" } }'})}),(0,r.jsxs)(s.td,{children:["Optional resources lets you control resource limits and requests for the parser container. See ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/",children:"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/"})]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.scopeLimiterAliases"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsx)(s.td,{children:"Optional finding aliases to be used in the scopeLimiter."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.tolerations"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional tolerations settings that control how the parser job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/",children:"https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"parser.ttlSecondsAfterFinished"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"nil"})}),(0,r.jsxs)(s.td,{children:["seconds after which the Kubernetes job for the parser will be deleted. Requires the Kubernetes TTLAfterFinished controller: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/",children:"https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/"})]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.activeDeadlineSeconds"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"nil"})}),(0,r.jsxs)(s.td,{children:["There are situations where you want to fail a scan Job after some amount of time. To do so, set activeDeadlineSeconds to define an active deadline (in seconds) when considering a scan Job as failed. (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup",children:"https://kubernetes.io/docs/concepts/workloads/controllers/job/#job-termination-and-cleanup"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.affinity"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["Optional affinity settings that control how the scanner job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.backoffLimit"}),(0,r.jsx)(s.td,{children:"int"}),(0,r.jsx)(s.td,{children:"3"}),(0,r.jsxs)(s.td,{children:["There are situations where you want to fail a scan Job after some amount of retries due to a logical error in configuration etc. To do so, set backoffLimit to specify the number of retries before considering a scan Job as failed. (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy",children:"https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.env"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional environment variables mapped into each scanJob (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/",children:"https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.extraContainers"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional additional Containers started with each scanJob (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/init-containers/",children:"https://kubernetes.io/docs/concepts/workloads/pods/init-containers/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.extraVolumeMounts"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional VolumeMounts mapped into each scanJob (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"https://kubernetes.io/docs/concepts/storage/volumes/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.extraVolumes"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional Volumes mapped into each scanJob (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/storage/volumes/",children:"https://kubernetes.io/docs/concepts/storage/volumes/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.image.pullPolicy"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'"IfNotPresent"'})}),(0,r.jsxs)(s.td,{children:["Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if ",":latest"," tag is specified, or IfNotPresent otherwise. More info: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/containers/images#updating-images",children:"https://kubernetes.io/docs/concepts/containers/images#updating-images"})]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.image.repository"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'"docker.io/secureco
1debox/scanner-kube-hunter"'})}),(0,r.jsx)(s.td,{children:"Container Image to run the scan"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.image.tag"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"nil"})}),(0,r.jsx)(s.td,{children:"defaults to the charts appVersion"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.nameAppend"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"nil"})}),(0,r.jsx)(s.td,{children:"append a string to the default scantype name."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.nodeSelector"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["Optional nodeSelector settings that control how the scanner job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.podSecurityContext"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["Optional securityContext set on scanner pod (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.resources"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{}"})}),(0,r.jsxs)(s.td,{children:["CPU/memory resource requests/limits (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/"}),", ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext"}),(0,r.jsx)(s.td,{children:"object"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'{"allowPrivilegeEscalation":false,"capabilities":{"drop":["all"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsNonRoot":false}'})}),(0,r.jsxs)(s.td,{children:["Optional securityContext set on scanner container (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/",children:"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext.allowPrivilegeEscalation"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"false"})}),(0,r.jsx)(s.td,{children:"Ensure that users privileges cannot be escalated"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext.capabilities.drop[0]"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:'"all"'})}),(0,r.jsx)(s.td,{children:"This drops all linux privileges from the container."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext.privileged"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"false"})}),(0,r.jsx)(s.td,{children:"Ensures that the scanner container is not run in privileged mode"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext.readOnlyRootFilesystem"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"true"})}),(0,r.jsx)(s.td,{children:"Prevents write access to the containers file system"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.securityContext.runAsNonRoot"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"false"})}),(0,r.jsx)(s.td,{children:"Enforces that the scanner image is run as a non root user"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.suspend"}),(0,r.jsx)(s.td,{children:"bool"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"false"})}),(0,r.jsxs)(s.td,{children:["if set to true the scan job will be suspended after creation. You can then resume the job using ",(0,r.jsx)(s.code,{children:"kubectl resume <jobname>"})," or using a job scheduler like kueue"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.tolerations"}),(0,r.jsx)(s.td,{children:"list"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"[]"})}),(0,r.jsxs)(s.td,{children:["Optional tolerations settings that control how the scanner job is scheduled (see: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/",children:"https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/"}),")"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"scanner.ttlSecondsAfterFinished"}),(0,r.jsx)(s.td,{children:"string"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"nil"})}),(0,r.jsxs)(s.td,{children:["seconds after which the Kubernetes job for the scanner will be deleted. Requires the Kubernetes TTLAfterFinished controller: ",(0,r.jsx)(s.a,{href:"https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/",children:"https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/"})]})]})]})]}),"\n",(0,r.jsx)(s.h2,{id:"license",children:"License"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.a,{href:"https://opensource.org/licenses/Apache-2.0",children:(0,r.jsx)(s.img,{src:"https://img.shields.io/badge/License-Apache%202.0-blue.svg",alt:"License"})})}),"\n",(0,r.jsxs)(s.p,{children:["Code of secureCodeBox is licensed under the ",(0,r.jsx)(s.a,{href:"https://github.com/secureCodeBox/secureCodeBox/blob/master/LICENSE",children:"Apache License 2.0"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"cpu-architectures",children:"CPU architectures"}),"\n",(0,r.jsx)(s.p,{children:"The scanner is currently supported for these CPU architectures:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"linux/amd64"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"examples",children:"Examples"}),"\n","\n",(0,r.jsx)(s.h3,{id:"in-cluster",children:"in-cluster"}),"\n",(0,r.jsxs)(c.A,{defaultValue:"scan",values:[{label:"Scan",value:"scan"},{label:"Findings",value:"findings"}],children:[(0,r.jsx)(o.A,{value:"scan",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'# SPDX-FileCopyrightText: the secureCodeBox authors\n#\n# SPDX-License-Identifier: Apache-2.0\n\napiVersion: "execution.securecodebox.io/v1"\nkind: Scan\nmetadata:\n  name: "kube-hunter-in-cluster"\nspec:\n  scanType: "kube-hunter"\n  parameters:\n    - "--pod"\n\n'})})}),(0,r.jsx)(o.A,{value:"findings",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'# SPDX-FileCopyrightText: the secureCodeBox authors\n#\n# SPDX-License-Identifier: Apache-2.0\n\n{\n  "nodes":\n    [\n      {"type": "Node/Master", "location": "10.0.0.1"},\n      {"type": "Node/Master", "location": "10.96.0.1"},\n    ],\n  "services":\n    [\n      {\n        "service": "Kubelet API",\n        "location": "10.0.0.1:10250",\n        "description": "The Kubelet is the main component in every Node, all pod operations goes through the kubelet",\n      },\n      {\n        "service": "Metrics Server",\n        "location": "10.0.0.1:6443",\n        "description": "The Metrics server is in charge of providing resource usage metrics for pods and nodes to the API server.",\n      },\n      {\n        "service": "API Server",\n        "location": "10.96.0.1:443",\n        "description": "The API server is in charge of all operations on the cluster.",\n      },\n    ],\n  "vulnerabilities":\n    [\n      {\n        "location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)",\n        "vid": "KHV050",\n        "category": "Access Risk",\n        "severity": "low",\n        "vulnerability": "Read access to pod\'s service account token",\n        "description": " Accessing the pod service account token gives an attacker the option to use the server API ",\n        "evidence": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkNabmY2NVgxUmR1ZnQzbHJVQVAzZFFUNjBiR0hUVE9SRDNPcURyenlkODgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imx1cmNoZXItdG9rZW4tcGpmNGIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoibHVyY2hlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjUzOGVhYjdmLTY1YjAtNDE4Yy04MGI2LTI1NGQxNDQ4ODU3NiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Omx1cmNoZXIifQ.
1cGtQHagQ2xxlAFnWwFRNgGJIkaeZIKnqoYYb8GmxN94ry0wwxCbgBm4Kg33A903wDBxd8iuITTk-r8UPZyYJHoxlVu0pHt-3SAc4NT0ob50R2acVXQ2qj_yJOOQHurCWeOJMkGqtCyUoZ8Xcnc6z32Ao-NWzKD-0wV7ndpKm-ytHP0YpHb9bLUPcQGvFoh_UF132yjeJqzwLPRX6hStMYOa8LNhJGyhdejW3BIOylzVPNkKE5lEjWv9f853qnTKG-TzXHBbth7qV8UHwSoY8YFoMezK3zazQt4dN1VG_wYmZ0ujikTC7TRTGr500kFxfpACKwdQ1M1fXgKJhNv9UgA",\n        "hunter": "Access Secrets",\n      },\n      {\n        "location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)",\n        "vid": "None",\n        "category": "Access Risk",\n        "severity": "low",\n        "vulnerability": "CAP_NET_RAW Enabled",\n        "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",\n        "evidence": "",\n        "hunter": "Pod Capabilities Hunter",\n      },\n      {\n        "location": "Local to Pod(scan-kube-hunter-in-cluster-4rfff)",\n        "vid": "None",\n        "category": "Access Risk",\n        "severity": "low",\n        "vulnerability": "Access to pod\'s secrets",\n        "description": " Accessing the pod\'s secrets within a compromised pod might disclose valuable data to a potential attacker",\n        "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\']",\n        "hunter": "Access Secrets",\n      },\n      {\n        "location": "10.96.0.1:443",\n        "vid": "KHV002",\n        "category": "Information Disclosure",\n        "severity": "medium",\n        "vulnerability": "K8s Version Disclosure",\n        "description": "The kubernetes version could be obtained from the /version endpoint ",\n        "evidence": "v1.18.0",\n        "hunter": "Api Version Hunter",\n      },\n      {\n        "location": "10.96.0.1:443",\n        "vid": "KHV005",\n        "category": "Information Disclosure",\n        "severity": "medium",\n        "vulnerability": "Access to API using service account token",\n        "description": " The API Server port is accessible. Depending on your RBAC settings this could expose access to or control of your cluster. ",\n        "evidence": "b\'{\\"kind\\":\\"APIVersions\\",\\"versions\\":[\\"v1\\"],\\"serverAddressByClientCIDRs\\":[{\\"clientCIDR\\":\\"0.0.0.0/0\\",\\"serverAddress\\":\\"172.17.0.2:6443\\"}]}\\\\n\'",\n        "hunter": "API Server Hunter",\n      },\n    ],\n  "kburl": "https://aquasecurity.github.io/kube-hunter/kb/{vid}",\n}\n\n'})})})]})]})}function p(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},9365(e,s,n){n.d(s,{A:()=>a});n(6540);var t=n(4164),r=n(7751);const i="tabItem_Ymn6";var c=n(4848);function o(e){let{children:s,className:n,hidden:r}=e;return(0,c.jsx)("div",{role:"tabpanel",className:(0,t.A)(i,n),hidden:r,children:s})}function a(e){let{children:s,className:n,value:t}=e;const{selectedValue:i,lazy:a}=(0,r.uc)(),l=t===i;return!l&&a?null:(0,c.jsx)(o,{className:n,hidden:!l,children:s})}},4865(e,s,n){n.d(s,{A:()=>x});n(6540);var t=n(4164),r=n(7559),i=n(7751),c=n(3104),o=n(2303);const a="tabList__CuJ",l="tabItem_LNqP";var d=n(4848);function h(e){let{className:s}=e;const{selectedValue:n,selectValue:r,tabValues:o,block:a}=(0,i.uc)(),h=[],{blockElementScrollPositionUntilNextRender:u}=(0,c.a_)(),p=e=>{const s=e.currentTarget,t=h.indexOf(s),i=o[t].value;i!==n&&(u(s),r(i))},x=e=>{let s=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const n=h.indexOf(e.currentTarget)+1;s=h[n]??h[0];break}case"ArrowLeft":{const n=h.indexOf(e.currentTarget)-1;s=h[n]??h[h.length-1];break}}s?.focus()};return(0,d.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":a},s),children:o.map((e=>{let{value:s,label:r,attributes:i}=e;return(0,d.jsx)("li",{role:"tab",tabIndex:n===s?0:-1,"aria-selected":n===s,ref:e=>{h.push(e)},onKeyDown:x,onClick:p,...i,className:(0,t.A)("tabs__item",l,i?.className,{"tabs__item--active":n===s}),children:r??s},s)}))})}function u(e){let{children:s}=e;return(0,d.jsx)("div",{className:"margin-top--md",children:s})}function p(e){let{className:s,children:n}=e;return(0,d.jsxs)("div",{className:(0,t.A)(r.G.tabs.container,"tabs-container",a),children:[(0,d.jsx)(h,{className:s}),(0,d.jsx)(u,{children:n})]})}function x(e){const s=(0,o.A)(),n=(0,i.OC)(e);return(0,d.jsx)(i.O_,{value:n,children:(0,d.jsx)(p,{className:e.className,children:(0,i.vT)(e.children)})},String(s))}}
1,7751(e,s,n){n.d(s,{OC:()=>x,O_:()=>f,uc:()=>b,vT:()=>d});var t=n(6540),r=n(6347),i=n(205),c=n(7485),o=n(679),a=n(1682),l=n(4848);function d(e){return t.Children.toArray(e).filter((e=>"\n"!==e))}function h(e){const{values:s,children:n}=e;return(0,t.useMemo)((()=>{const e=s??function(e){return t.Children.toArray(e).flatMap((e=>{if(!e)return[];if((0,t.isValidElement)(e)&&function(e){const{props:s}=e;return!!s&&"object"==typeof s&&"value"in s}(e))return[e];const s="string"==typeof e.type?e.type:e.type.name;throw new Error(`Docusaurus error: Bad <Tabs> child <${s}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.\nIf you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)})).map((e=>{let{props:{value:s,label:n,attributes:t,default:r}}=e;return{value:s,label:n,attributes:t,default:r}}))}(n);return function(e){const s=(0,a.XI)(e,((e,s)=>e.value===s.value));if(s.length>0)throw new Error(`Docusaurus error: Duplicate values "${s.map((e=>`'${e.value}'`)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[s,n])}function u(e){let{value:s,tabValues:n}=e;return n.some((e=>e.value===s))}function p(e){let{queryString:s=!1,groupId:n}=e;const i=(0,r.W6)(),o=function(e){let{queryString:s=!1,groupId:n}=e;if("string"==typeof s)return s;if(!1===s)return null;if(!0===s&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:s,groupId:n});return[(0,c.aZ)(o),(0,t.useCallback)((e=>{if(!o)return;const s=new URLSearchParams(i.location.search);s.set(o,e),i.replace({...i.location,search:s.toString()})}),[o,i])]}function x(e){const{defaultValue:s,queryString:n=!1,groupId:r}=e,c=h(e),[a,l]=(0,t.useState)((()=>function(e){let{defaultValue:s,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(s){if(!u({value:s,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${s}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return s}const t=n.find((e=>e.default))??n[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:s,tabValues:c}))),[d,x]=p({queryString:n,groupId:r}),[j,b]=function(e){let{groupId:s}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(s),[r,i]=(0,o.Dv)(n);return[r,(0,t.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),f=(()=>{const e=d??j;return u({value:e,tabValues:c})?e:null})();(0,i.A)((()=>{f&&l(f)}),[f]);return{selectedValue:a,selectValue:(0,t.useCallback)((e=>{if(!u({value:e,tabValues:c}))throw new Error(`Can't select invalid tab value=${e}`);l(e),x(e),b(e)}),[x,b,c]),tabValues:c,lazy:e.lazy??!1,block:e.block??!1}}const j=(0,t.createContext)(null);function b(){const e=t.useContext(j);if(!e)throw new Error("useTabsContext() must be used within a Tabs component");return e}function f(e){return(0,l.jsx)(j.Provider,{value:e.value,children:e.children})}},8453(e,s,n){n.d(s,{R:()=>c,x:()=>o});var t=n(6540);const r={},i=t.createContext(r);function c(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.