Code Monkey home page Code Monkey logo

kubiscan's Introduction

GitHub release License

A tool for scanning Kubernetes cluster for risky permissions in Kubernetes's Role-based access control (RBAC) authorization model. The tool was published as part of the "Securing Kubernetes Clusters by Eliminating Risky Permissions" research https://www.cyberark.com/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions/.

Overview

KubiScan helps cluster administrators identify permissions that attackers could potentially exploit to compromise the clusters. This can be especially helpful on large environments where there are lots of permissions that can be challenging to track. KubiScan gathers information about risky roles\clusterroles, rolebindings\clusterrolebindings, users and pods, automating traditional manual processes and giving administrators the visibility they need to reduce risk.

What can it do?

  • Identify risky Roles\ClusterRoles
  • Identify risky RoleBindings\ClusterRoleBindings
  • Identify risky Subjects (Users, Groups and ServiceAccounts)
  • Identify risky Pods\Containers
  • Dump tokens from pods (all or by namespace)
  • Get associated RoleBindings\ClusterRoleBindings to Role, ClusterRole or Subject (user, group or service account)
  • List Subjects with specific kind ('User', 'Group' or 'ServiceAccount')
  • List rules of RoleBinding or ClusterRoleBinding
  • Show Pods that have access to secret data through a volume or environment variables
  • Get bootstrap tokens for the cluster
  • CVE scan
  • EKS\AKS\GKE support

Usage

Container

You can run it like that:

./docker_run.sh <kube_config_file>
# For example: ./docker_run.sh ~/.kube/config

It will copy all the files linked inside the config file into the container and spwan a shell into the container.

To build the Docker image run:

docker build -t kubiscan .

Directly with Python3

Prerequisites:

Example for installation on Ubuntu:

apt-get update  
apt-get install -y python3 python3-pip 
pip3 install -r requirements.txt  

Run alias kubiscan='python3 /<KubiScan_folder>/KubiScan.py' to use kubiscan.

After installing all of the above requirements you can run it in two different ways:

With KubeConfig file:

Make sure you have access to ~/.kube/config file and all the relevant certificates, simply run:
kubiscan <command>
For example: kubiscan -rs will show all the risky subjects (users, service accounts and groups).

From a remote with ServiceAccount token

Some functionality requires a privileged service account with the following permissions:

  • resources: ["roles", "clusterroles", "rolebindings", "clusterrolebindings", "pods", "secrets"]
    verbs: ["get", "list"]
  • resources: ["pods/exec"]
    verbs: ["create", "get"]

But most of the functionalities are not, so you can use this settings for limited service account:
It can be created by running:

kubectl apply -f - << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubiscan-sa
  namespace: default
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: kubiscan-sa-secret
  annotations:
    kubernetes.io/service-account.name: kubiscan-sa
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata: 
  name: kubiscan-clusterrolebinding
subjects: 
- kind: ServiceAccount 
  name: kubiscan-sa
  namespace: default
  apiGroup: ""
roleRef: 
  kind: ClusterRole
  name: kubiscan-clusterrole
  apiGroup: ""
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata: 
  name: kubiscan-clusterrole
rules: 
- apiGroups: ["*"]
  resources: ["roles", "clusterroles", "rolebindings", "clusterrolebindings", "pods"]
  verbs: ["get", "list"]
EOF

Note that from Kubernetes 1.24, the creation of service account doesn't create a secret. This means that we need to create the secret.
Before 1.24, you can remove the Secret object from the above commands and save the service account's token to a file:
kubectl get secrets $(kubectl get sa kubiscan-sa -o=jsonpath='{.secrets[0].name}') -o=jsonpath='{.data.token}' | base64 -d > token

From 1.24, you don't need to change anything and save the token like that:

kubectl get secrets kubiscan-sa-secret -o=jsonpath='{.data.token}' | base64 -d > token  

After saving the token into the file, you can use it like that:
python3 ./KubiScan.py -ho <master_ip:master_port> -t /token <command>

For example:

alias kubiscan='python3 /<KubiScan_folder>/KubiScan.py
kubiscan -ho 192.168.21.129:8443 -t /token -rs

Notice that you can also use the certificate authority (ca.crt) to verify the SSL connection:

kubiscan -ho <master_ip:master_port> -t /token -c /ca.crt <command>

To remove the privileged service account, run the following commands:

kubectl delete clusterroles kubiscan-clusterrole  
kubectl delete clusterrolebindings kubiscan-clusterrolebinding   
kubectl delete sa kubiscan-sa  
kubectl delete secrets kubiscan-sa-secret

Examples

To see all the examples, run python3 KubiScan.py -e or from within the container kubiscan -e.

Demo

A small example of KubiScan usage:

Risky Roles YAML

There is a file named risky_roles.yaml. This file contains templates for risky roles with priority.
Although the kind in each role is Role, these templates will be compared against any Role\ClusterRole in the cluster.
When each of these roles is checked against a role in the cluster, it checks if the role in the cluster contains the rules from the risky role. If it does, it will be marked as risky.
We added all the roles we found to be risky, but because each one can define the term "risky" in a different way, you can modify the file by adding\removing roles you think are more\less risky.

❤️ Showcase

License

Copyright (c) 2020 CyberArk Software Ltd. All rights reserved
This repository is licensed under GPL-3.0 License - see LICENSE for more details.

References:

For more comments, suggestions or questions, you can contact Eviatar Gerzi (@g3rzi) and CyberArk Labs.

kubiscan's People

Contributors

2nik67 avatar 2niknatan avatar alonbenhorin avatar brikelly avatar disconnect3d avatar elreydetoda avatar g3rzi avatar gparvin avatar jpts avatar k-popov avatar mindfulmonk avatar snorwin avatar vidbina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kubiscan's Issues

Python error not handled when command result is empty

Hello !

Here's the commands I used that triggered the error

python3 /KubiScan/KubiScan.py -ho $KUBERNETES_ENDPOINT:$PORT -t /token -c /ca.crt -rp
or
python3 /KubiScan/KubiScan.py -ho $KUBERNETES_ENDPOINT:$PORT -t /token -c /ca.crt -pp

 Traceback (most recent call last):
   File "/KubiScan/KubiScan.py", line 635, in <module>
     main()
   File "/KubiScan/KubiScan.py", line 568, in main
     print_all_risky_containers(priority=args.priority, namespace=args.namespace, read_token_from_container=args.deep)
   File "/KubiScan/KubiScan.py", line 113, in print_all_risky_containers
     pods = engine.utils.get_risky_pods(namespace, read_token_from_container)
   File "/KubiScan/engine/utils.py", line 350, in get_risky_pods
     risky_containers = get_risky_containers(pod, risky_users, deep_analysis)
   File "/KubiScan/engine/utils.py", line 331, in get_risky_containers
     for volume in pod.spec.volumes:
 TypeError: 'NoneType' object is not iterable

Not sure if this happen with the other commands because when I run them they actually returning a result.

Cheers !

Support running on MacOS

Currently the tool does not work on MacOS as there is no cgroupfs there, as used in

def running_in_docker_container():
with open('/proc/self/cgroup', 'r') as procfile:
for line in procfile:
fields = line.strip().split('/')
if 'docker' in fields or '/docker-' in line:
return True
return False

This can be fixed by checking if the running OS is MacOS and if so, not executing the is_running_in_container function.

Provide more info how run `KubiScan`on EKS cluster

Description

I want to run KubiScan on the EKS cluster. But I did not find anything in the documentation or on the Internet about how to do it correctly.
Below is a description of the problems I encountered

  1. The documentation says that this tool should be launched on the master node - but it is impossible for EKS. There are just nodes.

  2. There are no details on whether this tool can be run on a local machine and remotely test something.

  3. There is very little documentation and it is confusing.

Please can you clarify the steps on how to run this tool on the EKS cluster and update the readme file because many things look non-obvious?

setup file

Would it be possible to create a setup.py or a pyproject.toml so I could package this correctly for blackarch linux ?

Thank you.
Sincerely

New Feature: Adding support on contexts

Currently KubiScan is running on the current context (kubectl config current-context) but sometimes there are more contexts.
For example, when using minishift:

root@ubuntu:~/KubiScan# kubectl config get-contexts
CURRENT   NAME                                         CLUSTER               AUTHINFO                           NAMESPACE
          minikube                                     minikube              minikube                           
*         minishift                                    192-168-42-132:8443   developer/192-168-42-132:8443      myproject
          myproject/192-168-42-132:8443/developer      192-168-42-132:8443   developer/192-168-42-132:8443      myproject
          myproject/192-168-42-132:8443/system:admin   192-168-42-132:8443   system:admin/192-168-42-132:8443   myproject

The current workaround is to set a new current context with use-context:
kubectl config use-context minikube

We want to give kubiscan an option to do it without changed the current context.

Dependecy issue in the Dockerfile in pip requirements. Can't build the docker image.

What happened (please include outputs or screenshots):

There is a dependecy issue in the Dockerfile in pip requirements. The docker image cannot be built.

$ docker build -t kubiscan .
Sending build context to Docker daemon  8.144MB
Step 1/12 : ARG DOCKER_REGISTRY=index.docker.io
Step 2/12 : ARG PYTHON_IMAGE=${DOCKER_REGISTRY}/python:3.8.0-slim-buster
Step 3/12 : FROM ${PYTHON_IMAGE} AS build-image
3.8.0-slim-buster: Pulling from library/python
000eee12ec04: Pull complete 
ddc2d83f8229: Pull complete 
3ae1660fa0d9: Pull complete 
ef709117d3d3: Pull complete 
487a0421e8fa: Pull complete 
Digest: sha256:8e243f41e500238f78f7a29a81656114d3fe603d5c34079a462d090f71c4b225
Status: Downloaded newer image for python:3.8.0-slim-buster
 ---> 577b86e4ee11
Step 4/12 : WORKDIR /tmp/build-kubiscan
 ---> Running in fa152e3fc358
Removing intermediate container fa152e3fc358
 ---> bddd52bfd7d8
Step 5/12 : COPY requirements.txt requirements.txt
 ---> ee687ab1ba46
Step 6/12 : RUN pip3 install -r requirements.txt
 ---> Running in d77da43ddcf6
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f35eebdf490>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/kubernetes/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f35eebdf9a0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/kubernetes/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f35eebdf7f0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/kubernetes/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f35eebdf580>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/kubernetes/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f35eebdf2e0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/kubernetes/
ERROR: Could not find a version that satisfies the requirement kubernetes==11.0.0 (from -r requirements.txt (line 1)) (from versions: none)
ERROR: No matching distribution found for kubernetes==11.0.0 (from -r requirements.txt (line 1))
The command '/bin/sh -c pip3 install -r requirements.txt' returned a non-zero code: 1

What you expected to happen:

Build the kubiscan docker image.

How to reproduce it (as minimally and precisely as possible):

Tested on repository with the latest commit b8e7f42
Clone the repo and run

$ docker build -t kubiscan .

Anything else we need to know?:

Environment:

Docker version 20.10.12, build 20.10.12-0ubuntu2~20.04.1
Linux ubuntu 5.15.0-56-generic

ConnectionRefusedError: [Errno 61] Connection refused

Summary

Kubiscan used to work perfectly, but have been constantly, for the past few weeks, been getting "ConnectionRefusedError".

Steps to Reproduce

  1. Run any command, example kubiscan -rb

Expected Results

Get a list of all risky rolebindings

Actual Results (including error logs, if applicable)

Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 169, in _new_conn
conn = connection.create_connection(
File "/usr/local/lib/python3.9/site-packages/urllib3/util/connection.py", line 96, in create_connection
raise err
File "/usr/local/lib/python3.9/site-packages/urllib3/util/connection.py", line 86, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 234, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1255, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1301, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1250, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 1010, in _send_output
self.send(msg)
File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/http/client.py", line 950, in send
self.connect()
File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 200, in connect
conn = self._new_conn()
File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 181, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x109dcac70>: Failed to establish a new connection: [Errno 61] Connection refused

Reproducible

  • Always

Version/Tag number

v1.5

Environment setup

  1. Cloud provider - AWS EKS
  2. Running Kubiscan locally on my laptop
  3. I have full RO permissions to the Clusters

Additional Information

Looks like kubiscan is not automatically picking up the configs from ~/.kube/config file. I tried adding the master IP and port and that didn't work either

'docker_run.sh' script returning permission denied error when trying to copy into the container

Summary

When running 'docker_run.sh' script, the 'docker cp' command is returning an error as such:
ERRO[0000] Can't add file /root/.minikube/profiles/minikube/client.crt to tar: open /root/.minikube/profiles/minikube/client.crt: permission denied

Steps to Reproduce

  1. Running 'docker_run.sh' script

Expected Results

All files are copied

Actual Results

Getting 'When running 'docker_run.sh' script, the 'docker cp' command is returning an error as such:
ERRO[0000] Can't add file /root/.minikube/profiles/minikube/client.crt to tar: open /root/.minikube/profiles/minikube/client.crt: permission denied' error

Reproducible

  • [* ] Always
  • Sometimes
  • Non-Reproducible

Environment setup

Ubuntu

Enhancements for output

For a better integration with other tool, it could be interesting to have options to:

  • Hide the banner (Kind of quiet mode with -q)
  • Write the output matrix to a file (-o outputfile.txt). It can open future opportunities on file format: json or yaml for exemple.

Thanks for this great tool!

Issue in /KubiScan/engine/jwt_token.py

Summary

I'm getting an error when running the kubiscan with --kube-config flag.
It seems that the issue is in jwt_token.py functions which (naturally) accept only JWT tokens.
I'm getting non-JWT tokens passed into the

def decode_jwt_token_data(jwt_token):
    splitted_string = jwt_token.split(".")

Details

After running

# kubiscan --kube-config "/root/.kube/config" -rp

I get the stack trace

Traceback (most recent call last):
  File "/KubiScan/KubiScan.py", line 675, in <module>
    main()
  File "/KubiScan/KubiScan.py", line 606, in main
    print_all_risky_containers(priority=args.priority, namespace=args.namespace, read_token_from_container=args.deep)
  File "/KubiScan/KubiScan.py", line 141, in print_all_risky_containers
    pods = engine.utils.get_risky_pods(namespace, read_token_from_container)
  File "/KubiScan/engine/utils.py", line 435, in get_risky_pods
    risky_containers = get_risky_containers(pod, risky_users, deep_analysis)
  File "/KubiScan/engine/utils.py", line 348, in get_risky_containers
    risky_users_set = get_risky_users_from_container(container, risky_users, pod, volumes_dict)
  File "/KubiScan/engine/utils.py", line 380, in get_risky_users_from_container
    risky_user = get_jwt_and_decode(pod, risky_users, volumes_dict[volume_mount.name])
  File "/KubiScan/engine/utils.py", line 421, in get_jwt_and_decode
    decoded_data = decode_base64_jwt_token(secret.data['token'])
  File "/KubiScan/engine/jwt_token.py", line 7, in decode_base64_jwt_token
    return decode_jwt_token_data(decode_base64_bytes_to_string(decode_base64(base64_token)))
  File "/KubiScan/engine/jwt_token.py", line 13, in decode_jwt_token_data
    decoded_data_base64 = decode_base64(splitted_string[1])
IndexError: list index out of range

I echoed some values for debug purposes

[DEBUG] File /KubiScan/engine/utils.py, line 418, in get_jwt_and_decode
[DEBUG] secret: {'api_version': 'v1',
 'data': {'namespace': 'Yy1tLWR4YzI5N2s1',
          'token': '<base64-token>',
          'url': '<corp-url>'},
 'immutable': None,
 'kind': 'Secret',
 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"v1","data":{"namespace":"Yy1tLWR4YzI5N2s1","token":"<base64-token>","url":"<corp-url>"},"kind":"Secret","metadata":{"annotations":{},"name":"cattle-credentials-384a8b6","namespace":"cattle-system"},"type":"Opaque"}\n'},
              'creation_timestamp': datetime.datetime(2022, 11, 18, 8, 36, 9, tzinfo=tzlocal()),
...
...
...

The problem is that b64 decoded token in

'token': '<base64-token>',

doesn't contain 'dot', it doesn't seem to be a valid JWT token. It looks something like

msdtd24l2hg5vrzr8w9dnl897nkbfrbxd5sbljxg9hhbbwwkqr2cx2

When this data is passed to

splitted_string = jwt_token.split(".")

then

splitted_string[1]

is empty and kubiscan throws an error.

Additionally the same .kubeconfig file works perfectly with kubectl CLI.

Listing secret not capturing as a risky rule

My RBAC (ServiceAccount,Role & RoleBinding) as follows, which has a role of listing secrets.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: listsecrets
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-list-secrets
rules:
- apiGroups: ["*"]
  resources: ["secrets"]
  verbs: ["list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rolebinding-list-secrets
subjects:
- kind: ServiceAccount
  name: listsecrets
  namespace: testing
roleRef:
  kind: Role
  name: role-list-secrets
  apiGroup: rbac.authorization.k8s.io

image

But kubiscan -rr does not capturing/show as a risky rule.

image

Not sure what is the criteria of risky rule?

Linux Package of the tool (FR)

I would like to have a running Linux binary of this tool because almost of the pen tests are offline
I tried to use pyinstaller for this propose but did not work.
thanx

cannot run KubiScan

Summary

Cannot run kubiscan -rr or any kubiscan command
Provide brief overview and context for the discovered bug.

Steps to Reproduce

$kubiscan -rr
File "/root/KubiScan/KubiScan.py", line 105
match cve_severity:
^
SyntaxError: invalid syntax

Static Scan

Is your feature request related to a problem? Please describe.

some time's you as Pen-Tester or Read Team Member get access to Role Definition Yaml Files and would like to do a static scan on them.

Describe the solution you would like

implementing Static Scan without the use of the API Kubernetes Client
implementing Parser for YAML File

Todo's

role.py : add parse method to create role object from a yaml file
rule.py : add parse method to create role object from a yaml file
subject : add parse method to create role object from a yaml file
utils.py : add get_roles_by_kind_from_file(kind) that open file and parse all Yaml File and create objects from the data
utils.py : add get_risky_role_by_kind_from_file(kind,roles) same as get_risky_role_by_kind but using get_roles_by_kind_from_file
kubiscan.py : add args for the new feature

Privacy Declaration?

Summary

This is more of a question rather than a bug. Does kubiscan contact any internet server as part of the scan? Since your recommended method to run is a docker container. I was not sure what it can / will do? I cannot run this in corporate environment unless there is explicit clarity on whether kubiscan phones home with any data or not.

Steps to Reproduce

run kubiscan

Expected Results

kubiscan works without sending any information to any 3rd party server.

Actual Results

Currently, it is unclear if kubiscan sends any information to any 3rd party server or not.

Reproducible

  • Always
  • Sometimes
  • Non-Reproducible

Insecured option

Not an issue but insecure option should be added if only "TOKEN" is used.

otherwise every command run we will get following error ..

/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

Support for kubeconfig credentials directly in kubeconfig file

I have kubeconfig file which doesn't contain

certificate-authority:
client-certificate:

keys.

Instead the credentials are included directly in the kubeconfig file via

certificate-authority-data:
client-certificate-data:

Can I pass such kubeconfig directly to kubiscan or do I need to move the credentials into separate files and use

certificate-authority:
client-certificate:

?

anonymous permissions

anonymous

After creating a clusterrolebinding for the user system: anonymous, I didn't see in the list of Risky report.

Failed chmod when not specifying AWS info

Summary

When not providing an aws_dir as an argument to the ./docker_run.sh script, the mkdir -p command doesn't run. Causing the chmod command to fail.

While this doesn't prevent you from exec'ing inside the container it is still confusing (made me think the script didn't finish initially).

Steps to Reproduce

  1. Clone repo
  2. Execute ./docker_run.sh ~/.kube/config
  3. See error

(the same error happens no matter if I'm using @2niknatan's natan2nik/kubiscan image or build locally and use that image's name)

Expected Results

No errors (i.e. picture below)

image

Actual Results

chmod error

image

Reproducible

  • Always
  • Sometimes
  • Non-Reproducible

Version/Tag number

commit: cd670a6
(current master branch's latest commit)

Environment setup

In proxmox VM running Kali Linux 2023.1 with docker version:

Client: Docker Engine - Community
 Version:           23.0.6
 API version:       1.42
 Go version:        go1.19.9
 Git commit:        ef23cbc
 Built:             Fri May  5 21:18:28 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.6
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.9
  Git commit:       9dbdbd4
  Built:            Fri May  5 21:18:28 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Effectively running in this Vagrantfile (used the same script to install docker).

Additional Information

N/a

JSON output failure

Hi
I executed below command to store output in JSON, but KubiScan only stores ] in JSONfile.
$ sudo python3 /usr/bin/KubiScan/KubiScan.py -a -q -j ~/a.json

The out put is:

$ cat ~/a.json
]

Kubernetes PSP (Pod Security Policy) using kubiscan

In my last discussion we discussed about risky pod. In this context if you think kubernetes PSP (Pod Security Policy) can be implemented along with kubiscan that will be great as a part of enhancement.

invalid start byte for kubiscan -rp

Running from the google cloud shell against a faily vanilla GKE deployment.
kubiscan -rp

main()

File "/KubiScan/KubiScan.py", line 469, in main
print_all_risky_containers()
File "/KubiScan/KubiScan.py", line 92, in print_all_risky_containers
pods = engine.utils.get_risky_pods()
File "/KubiScan/engine/utils.py", line 307, in get_risky_pods
risky_containers = get_risky_containers(pod, risky_users)
File "/KubiScan/engine/utils.py", line 290, in get_risky_containers
jwt_body, _ = get_jwt_token_from_container(pod, container.name)
File "/KubiScan/engine/utils.py", line 276, in get_jwt_token_from_container
decoded_data = decode_jwt_token_data(resp)
File "/KubiScan/engine/jwt_token.py", line 7, in decode_jwt_token_data
return decoded_data.decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte

Invalid value for `rules`, must not be `None`

Hi,

I'm trying to use Kubiscan in my AWS EKS environment. I ran with docker and copied my ~/.aws and aws-iam-authentication to the container and I was able to run kubiscan -rr for example without problems but some commands I got the following stack trace:

below are some args that are I tried

  • -rcr
  • -rar
  • -rb
  • -rcb
  • -rs
  • -rp
  • --all

Traceback (most recent call last):
File "/KubiScan/KubiScan.py", line 534, in
main()
File "/KubiScan/KubiScan.py", line 469, in main
print_all_risky_containers()
File "/KubiScan/KubiScan.py", line 92, in print_all_risky_containers
pods = engine.utils.get_risky_pods()
File "/KubiScan/engine/utils.py", line 306, in get_risky_pods
risky_users = get_all_risky_subjects()
File "/KubiScan/engine/utils.py", line 219, in get_all_risky_subjects
all_risky_rolebindings = get_all_risky_rolebinding()
File "/KubiScan/engine/utils.py", line 186, in get_all_risky_rolebinding
all_risky_roles = get_risky_roles_and_clusterroles()
File "/KubiScan/engine/utils.py", line 134, in get_risky_roles_and_clusterroles
risky_clusterroles = get_risky_clusterroles()
File "/KubiScan/engine/utils.py", line 144, in get_risky_clusterroles
return get_risky_role_by_kind('ClusterRole')
File "/KubiScan/engine/utils.py", line 124, in get_risky_role_by_kind
all_roles = get_roles_by_kind(kind)
File "/KubiScan/engine/utils.py", line 117, in get_roles_by_kind
all_roles = api_client.RbacAuthorizationV1Api.list_cluster_role()
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/apis/rbac_authorization_v1_api.py", line 1618, in list_cluster_role
(data) = self.list_cluster_role_with_http_info(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/apis/rbac_authorization_v1_api.py", line 1715, in list_cluster_role_with_http_info
collection_formats=collection_formats)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 321, in call_api
_return_http_data_only, collection_formats, _preload_content, _request_timeout)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 163, in __call_api
return_data = self.deserialize(response_data, response_type)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 236, in deserialize
return self.__deserialize(data, response_type)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 276, in __deserialize
return self.__deserialize_model(data, klass)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 620, in __deserialize_model
kwargs[attr] = self.__deserialize(value, attr_type)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 254, in __deserialize
for sub_data in data]
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 254, in
for sub_data in data]
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 276, in __deserialize
return self.__deserialize_model(data, klass)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/api_client.py", line 622, in __deserialize_model
instance = klass(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/models/v1_cluster_role.py", line 69, in init
self.rules = rules
File "/usr/local/lib/python3.6/dist-packages/kubernetes/client/models/v1_cluster_role.py", line 184, in rules
raise ValueError("Invalid value for rules, must not be None")
ValueError: Invalid value for rules, must not be None

Discussion about unsecure default resources in managed K8S Cluster that cause noise in response for automated process.

Hello again ! :)

When I run Kubiscan against an Amazon EKS cluster, I find a lot of HIGH and CRITICAL resources (mostly system:controller: stuff) that lives inside the cluster per default. (I supposed doing so on GKE or AKS would pretty much do the same).

I believe their extended privileges access is necessary for the cluster to work, so how should I interpret the response of Kubiscan regarding those resources. Can we safely ignore them ?
Should we add some knowledge about these resources in Kubiscan so they are not reported in the response ? (Could be heavy in the code base and hard to maintain as kubernetes evolves quickly.. )

I'm trying to script an automated job that will use Kubiscan to detect unsafe resources, and notify me when new ones are detected. At the moment I filter the response with grep -v to avoid being notified for all the system:controller resources but I'm wondering if there would be a better approach.

Any idea ?
How do you guys leverage this in your environments ?

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.