#!/bin/bash
# Define color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
BOLD='\033[1m'
BG_RED='\033[41m'
BG_GREEN='\033[42m'
BG_BLUE='\033[44m'
NC='\033[0m' # No Color
# Function for colorful section headers
print_header() {
echo -e "\n${BG_BLUE}${BOLD}${WHITE} $1 ${NC}"
echo -e "${BLUE}$(printf '=%.0s' {1..70})${NC}"
}
# Function for sub-headers
print_subheader() {
echo -e "\n${BOLD}${CYAN} $1 ${NC}"
echo -e "${CYAN}$(printf '-%.0s' {1..70})${NC}"
}
# Function to show status
show_status() {
if [ "$2" == "OK" ]; then
echo -e "[$1] ${GREEN}✓ $3${NC}"
elif [ "$2" == "WARN" ]; then
echo -e "[$1] ${YELLOW}⚠ $3${NC}"
else
echo -e "[$1] ${RED}✗ $3${NC}"
fi
}
# Start minikube if not running
print_header "KUBERNETES SECURITY TEST SUITE"
echo -e "${YELLOW}Initializing test environment...${NC}"
show_status "SETUP" "WARN" "Checking if minikube is running"
if minikube status &> /dev/null; then
show_status "SETUP" "OK" "Minikube is running"
else
show_status "SETUP" "WARN" "Starting minikube"
minikube start
show_status "SETUP" "OK" "Minikube started successfully"
fi
# Wait for default service account
show_status "SETUP" "WARN" "Waiting for default service account"
while ! kubectl get serviceaccount default &> /dev/null; do
sleep 2
echo -n -e "${YELLOW}.${NC}"
done
show_status "SETUP" "OK" "Default service account is available"
# Ensure bc is installed on minikube node
show_status "SETUP" "WARN" "Checking if bc is installed in minikube"
minikube ssh "command -v bc &> /dev/null || { echo 'Installing bc...'; sudo apt-get update && sudo apt-get install -y bc; }"
show_status "SETUP" "OK" "bc is available in minikube"
# Function to check namespaces and capabilities
check_container() {
POD_NAME=$1
echo "CHECKING CONTAINER: $POD_NAME"
# Get container ID
CONTAINER_ID=$(kubectl get pod $POD_NAME -o 'jsonpath={.status.containerStatuses[0].containerID}' | sed 's/docker:\/\///')
echo -e "${BOLD}Container ID:${NC} ${YELLOW}$CONTAINER_ID${NC}"
# Check namespaces and compare with host
minikube ssh "
# Get container PID
CONTAINER_PID=\$(sudo docker inspect --format='{{.State.Pid}}' $CONTAINER_ID)
echo -e \"Container PID on host: \${CONTAINER_PID}\"
echo \"\"
# Compare namespaces
echo -e \"\033[1;36m--- Namespace Comparison ---\033[0m\"
echo -e \"\033[1mNAMESPACE HOST-ID CONTAINER-ID STATUS\033[0m\"
echo -e \"\033[36m---------- ----------------------- ------------------------ --------\033[0m\"
for NS in cgroup ipc mnt net pid user uts; do
HOST_NS=\$(sudo readlink /proc/1/ns/\$NS)
CONTAINER_NS=\$(sudo readlink /proc/\$CONTAINER_PID/ns/\$NS)
# Extract just the ID number for cleaner display
HOST_ID=\$(echo \$HOST_NS | sed 's/.*\\[\\(.*\\)\\]/\\1/')
CONTAINER_ID=\$(echo \$CONTAINER_NS | sed 's/.*\\[\\(.*\\)\\]/\\1/')
SHARED=\$([ \"\$HOST_NS\" = \"\$CONTAINER_NS\" ] && echo -e \"\033[31mSHARED\033[0m\" || echo -e \"\033[32mISOLATED\033[0m\")
printf \"%-10s %-25s %-24s %b\\n\" \"\$NS\" \"\$HOST_ID\" \"\$CONTAINER_ID\" \"\$SHARED\"
done
echo \"\"
echo -e \"\033[1;36m--- Capability Information ---\033[0m\"
echo \"Checking capabilities from /proc/\$CONTAINER_PID/status:\"
echo \"\"
echo -e \"\033[1;33m### Container Capabilities ###\033[0m\"
CONT_CAP_EFF=\$(sudo grep CapEff /proc/\$CONTAINER_PID/status | awk '{print \$2}')
CONT_CAP_PRM=\$(sudo grep CapPrm /proc/\$CONTAINER_PID/status | awk '{print \$2}')
CONT_CAP_INH=\$(sudo grep CapInh /proc/\$CONTAINER_PID/status | awk '{print \$2}')
CONT_CAP_BND=\$(sudo grep CapBnd /proc/\$CONTAINER_PID/status | awk '{print \$2}')
CONT_CAP_AMB=\$(sudo grep CapAmb /proc/\$CONTAINER_PID/status | awk '{print \$2}')
echo -e \"\033[1mCapEff (Effective): \033[0m \033[33m\$CONT_CAP_EFF\033[0m\"
echo -e \"\033[1mCapPrm (Permitted): \033[0m \033[33m\$CONT_CAP_PRM\033[0m\"
echo -e \"\033[1mCapInh (Inheritable):\033[0m \033[33m\$CONT_CAP_INH\033[0m\"
echo -e \"\033[1mCapBnd (Bounding): \033[0m \033[33m\$CONT_CAP_BND\033[0m\"
echo -e \"\033[1mCapAmb (Ambient): \033[0m \033[33m\$CONT_CAP_AMB\033[0m\"
# Save effective capabilities for summary comparison
echo \$CONT_CAP_EFF > /tmp/${POD_NAME}_capeff
# Decode effective capabilities
echo \"\"
echo -e \"\033[1;33m### Decoded Effective Capabilities ###\033[0m\"
echo \"The effective capabilities (CapEff) determine what privileged operations a process can actually perform.\"
echo \"\"
# Using bc to decode capabilities
echo \"Using bc to decode capabilities...\"
# Using a simplified list of common capabilities for demonstration
cap_map=(
\"0:CAP_CHOWN - Change file ownership and group\"
\"1:CAP_DAC_OVERRIDE - Bypass file read, write, and execute permission checks\"
\"2:CAP_DAC_READ_SEARCH - Bypass file read permission checks\"
\"3:CAP_FOWNER - Bypass permission checks on operations that normally require the file system UID to match the process's\"
\"4:CAP_FSETID - Don't clear set-user-ID and set-group-ID mode bits when a file is modified\"
\"5:CAP_KILL - Bypass permission checks for sending signals\"
\"6:CAP_SETGID - Make arbitrary manipulations of process GIDs\"
\"7:CAP_SETUID - Make arbitrary manipulations of process UIDs\"
\"8:CAP_SETPCAP - Modify process capabilities\"
\"9:CAP_LINUX_IMMUTABLE - Set the FS_APPEND_FL and FS_IMMUTABLE_FL flags\"
\"10:CAP_NET_BIND_SERVICE - Bind a socket to Internet domain privileged ports\"
\"11:CAP_NET_BROADCAST - Make socket broadcasts and listen to multicasts\"
\"12:CAP_NET_ADMIN - Perform network administration tasks\"
\"13:CAP_NET_RAW - Use raw sockets\"
\"14:CAP_IPC_LOCK - Lock memory\"
\"15:CAP_IPC_OWNER - Bypass permissions on message queues and shared memory\"
\"16:CAP_SYS_MODULE - Load and unload kernel modules\"
\"17:CAP_SYS_RAWIO - Perform I/O port operations\"
\"18:CAP_SYS_CHROOT - Use chroot()\"
\"19:CAP_SYS_PTRACE - Trace arbitrary processes\"
\"20:CAP_SYS_PACCT - Configure process accounting\"
\"21:CAP_SYS_ADMIN - Perform various system administration operations\"
\"22:CAP_SYS_BOOT - Use reboot() and kexec_load()\"
\"23:CAP_SYS_NICE - Raise process nice value and change nice value for arbitrary processes\"
\"24:CAP_SYS_RESOURCE - Override resource limits\"
\"25:CAP_SYS_TIME - Set system clock\"
\"26:CAP_SYS_TTY_CONFIG - Configure TTY devices\"
\"27:CAP_MKNOD - Create special files\"
\"28:CAP_LEASE - Establish leases on files\"
\"29:CAP_AUDIT_WRITE - Write records to kernel auditing log\"
\"30:CAP_AUDIT_CONTROL - Configure audit subsystem\"
\"31:CAP_SETFCAP - Set file capabilities\"
\"32:CAP_MAC_OVERRIDE - Override MAC restrictions\"
\"33:CAP_MAC_ADMIN - Configure MAC\"
\"34:CAP_SYSLOG - Perform privileged syslog operations\"
\"35:CAP_WAKE_ALARM - Trigger wake alarms\"
\"36:CAP_BLOCK_SUSPEND - Block system suspend\"
\"37:CAP_AUDIT_READ - Read audit log\"
)
# Convert hex to binary
binary=\$(printf \"%064s\" \$(bc <<< \"obase=2;ibase=16;\${CONT_CAP_EFF^^}\") | tr ' ' '0')
# Reverse for bit position
reversed_binary=\$(echo \$binary | rev)
echo -e \"Capability hex: \033[36m\$CONT_CAP_EFF\033[0m\"
# Check each bit and display capability if set
for cap in \"\${cap_map[@]}\"; do
pos=\$(echo \$cap | cut -d':' -f1)
desc=\$(echo \$cap | cut -d':' -f2-)
if [ \"\${reversed_binary:\$pos:1}\" = \"1\" ]; then
echo -e \" - \033[32m\$desc\033[0m\"
fi
done
"
echo ""
}
print_header "KUBERNETES NAMESPACE & CAPABILITY TESTS"
# 1. Create a baseline pod (no special privileges)
echo "CREATING POD 1: baseline-pod (no special privileges)"
POD_MANIFEST=$(cat </dev/null)" != "Running" ]; do
sleep 2
echo -n -e "${YELLOW}.${NC}"
done
echo -e " ${GREEN}Running!${NC}"
done
echo -e "${GREEN}All pods are running${NC}"
echo ""
# Check capabilities for all pods
for pod in "${PODS[@]}"; do
check_container "$pod"
done
# Generate a capabilities comparison summary
print_header "CAPABILITIES COMPARISON SUMMARY"
echo "This table shows which critical capabilities are granted to each pod configuration."
echo ""
# Use minikube to generate the comparison
minikube ssh "
# Define key capabilities to check for
declare -a CAPS=(
'21:SYS_ADMIN'
'12:NET_ADMIN'
'19:SYS_PTRACE'
'16:SYS_MODULE'
'7:SETUID'
'24:SYS_RESOURCE'
'17:SYS_RAWIO'
)
# Print table header with colors
printf \"\033[1;36m%-20s\" \"POD NAME\"
for cap in \"\${CAPS[@]}\"; do
capname=\$(echo \$cap | cut -d':' -f2)
printf \"\033[1;36m%-12s\" \"\$capname\"
done
printf \"\033[0m\\n\"
# Print separator
printf \"\033[36m%s\" \"--------------------\"
for cap in \"\${CAPS[@]}\"; do
printf \"%s\" \"------------\"
done
printf \"\033[0m\\n\"
# Check each pod
for pod in baseline-pod privileged-pod hostnetwork-pod hostpid-pod hostipc-pod; do
if [ -f \"/tmp/\${pod}_capeff\" ]; then
capeff=\$(cat /tmp/\${pod}_capeff)
# Convert hex to binary
binary=\$(printf \"%064s\" \$(bc <<< \"obase=2;ibase=16;\${capeff^^}\") | tr ' ' '0')
# Reverse for bit position
reversed_binary=\$(echo \$binary | rev)
# Print pod name
printf \"\033[1;33m%-20s\033[0m\" \"\$pod\"
# Check each capability
for cap in \"\${CAPS[@]}\"; do
pos=\$(echo \$cap | cut -d':' -f1)
if [ \"\${reversed_binary:\$pos:1}\" = \"1\" ]; then
printf \"\033[1;32m%-12s\033[0m\" \"YES\"
else
printf \"\033[1;31m%-12s\033[0m\" \"NO\"
fi
done
printf \"\\n\"
else
printf \"\033[1;33m%-20s \033[1;31mCAPABILITY DATA NOT FOUND\033[0m\\n\" \"\$pod\"
fi
done
"
# Cleanup
print_header "CLEANUP"
echo -e "${YELLOW}Cleaning up resources...${NC}"
for pod in "${PODS[@]}"; do
kubectl delete pod $pod --force --wait=false 2>/dev/null
show_status "CLEANUP" "OK" "Deleted pod: $pod"
done
minikube ssh "sudo rm -f /tmp/*_capeff"
echo -e "${GREEN}${BOLD}All done! Tests completed successfully!${NC}"