mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2026-04-28 03:43:23 -07:00
Improve container and runtime enumeration (#624)
* Improve container and runtime enumeration * Fix CI failures for PR #624 --------- Co-authored-by: chack-agent <chack-agent@users.noreply.github.com>
This commit is contained in:
@@ -1,35 +1,15 @@
|
||||
# Title: Container - Container details
|
||||
# ID: CT_Container_details
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 07-03-2024
|
||||
# Description: Get detailed container information relevant to privilege escalation:
|
||||
# - Container type and runtime
|
||||
# - Running containers
|
||||
# - Container configuration
|
||||
# - Common vulnerable scenarios:
|
||||
# * Misconfigured containers
|
||||
# * Privileged containers
|
||||
# * Exposed container APIs
|
||||
# * Container networking
|
||||
# - Exploitation methods:
|
||||
# * Container breakout: Exploit container misconfigurations
|
||||
# * Common attack vectors:
|
||||
# - Runtime escape
|
||||
# - Privilege escalation
|
||||
# - Container breakout
|
||||
# - Network escape
|
||||
# * Exploit techniques:
|
||||
# - Container misconfiguration abuse
|
||||
# - Privileged container exploitation
|
||||
# - Container API abuse
|
||||
# - Network escape techniques
|
||||
# Last Update: 21-03-2026
|
||||
# Description: Gather general container runtime context, local runtime CLIs, and visible container-management surfaces relevant to privilege escalation.
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Mitre: T1613,T1611
|
||||
# Functions Used: containerCheck, echo_no, print_2title, print_list, warn_exec
|
||||
# Functions Used: containerCheck, echo_no, enumerateDockerSockets, print_2title, print_list, warn_exec
|
||||
# Global Variables: $containerType
|
||||
# Initial Functions: containerCheck
|
||||
# Generated Global Variables: $dockercontainers, $podmancontainers, $lxccontainers, $rktcontainers, $containerCounts
|
||||
# Generated Global Variables: $containerCounts, $crictlcontainers, $ctrcontainers, $dockercontainers, $lxccontainers, $nerdctlcontainers, $podmancontainers, $rktcontainers
|
||||
# Fat linpeas: 0
|
||||
# Small linpeas: 1
|
||||
|
||||
@@ -44,6 +24,14 @@ if [ -f "/run/systemd/container" ]; then
|
||||
print_list "Systemd Container ..............$NC $(cat /run/systemd/container)"
|
||||
fi
|
||||
|
||||
if [ -f "/run/.containerenv" ]; then
|
||||
print_list "Podman/OCI marker ..............$NC /run/.containerenv"
|
||||
fi
|
||||
|
||||
if [ -f "/.dockerenv" ]; then
|
||||
print_list "Docker marker ..................$NC /.dockerenv"
|
||||
fi
|
||||
|
||||
# Get container runtime info
|
||||
if [ "$(command -v docker || echo -n '')" ]; then
|
||||
print_list "Docker version ...............$NC "
|
||||
@@ -66,13 +54,58 @@ if [ "$(command -v lxc || echo -n '')" ]; then
|
||||
warn_exec lxc info
|
||||
fi
|
||||
|
||||
if [ "$(command -v crio || echo -n '')" ]; then
|
||||
print_list "CRI-O version ..............$NC "
|
||||
warn_exec crio --version
|
||||
fi
|
||||
|
||||
if [ "$(command -v runc || echo -n '')" ]; then
|
||||
print_list "runc version ...............$NC "
|
||||
warn_exec runc --version
|
||||
fi
|
||||
|
||||
if [ "$(command -v crun || echo -n '')" ]; then
|
||||
print_list "crun version ...............$NC "
|
||||
warn_exec crun --version
|
||||
fi
|
||||
|
||||
if [ "$(command -v nerdctl || echo -n '')" ]; then
|
||||
print_list "nerdctl version ............$NC "
|
||||
warn_exec nerdctl version
|
||||
fi
|
||||
|
||||
if [ "$(command -v crictl || echo -n '')" ]; then
|
||||
print_list "crictl version .............$NC "
|
||||
warn_exec crictl version
|
||||
fi
|
||||
|
||||
if [ "$(command -v ctr || echo -n '')" ]; then
|
||||
print_list "ctr version ................$NC "
|
||||
warn_exec ctr version
|
||||
fi
|
||||
|
||||
print_list "Interesting runtime sockets ... "$NC
|
||||
enumerateDockerSockets
|
||||
|
||||
print_list "Any running containers? ........ "$NC
|
||||
# Get counts of running containers for each platform
|
||||
dockercontainers=$(docker ps --format "{{.Names}}" 2>/dev/null | wc -l)
|
||||
podmancontainers=$(podman ps --format "{{.Names}}" 2>/dev/null | wc -l)
|
||||
lxccontainers=$(lxc list -c n --format csv 2>/dev/null | wc -l)
|
||||
rktcontainers=$(rkt list 2>/dev/null | tail -n +2 | wc -l)
|
||||
if [ "$dockercontainers" -eq "0" ] && [ "$lxccontainers" -eq "0" ] && [ "$rktcontainers" -eq "0" ] && [ "$podmancontainers" -eq "0" ]; then
|
||||
dockercontainers=0
|
||||
podmancontainers=0
|
||||
lxccontainers=0
|
||||
rktcontainers=0
|
||||
nerdctlcontainers=0
|
||||
crictlcontainers=0
|
||||
ctrcontainers=0
|
||||
|
||||
if [ "$(command -v docker || echo -n '')" ]; then dockercontainers=$(docker ps --format "{{.Names}}" 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v podman || echo -n '')" ]; then podmancontainers=$(podman ps --format "{{.Names}}" 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v lxc || echo -n '')" ]; then lxccontainers=$(lxc list -c n --format csv 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v rkt || echo -n '')" ]; then rktcontainers=$(rkt list 2>/dev/null | tail -n +2 | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v nerdctl || echo -n '')" ]; then nerdctlcontainers=$(nerdctl ps --format "{{.Names}}" 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v crictl || echo -n '')" ]; then crictlcontainers=$(crictl ps -q 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
if [ "$(command -v ctr || echo -n '')" ]; then ctrcontainers=$(ctr -n k8s.io containers list -q 2>/dev/null | wc -l | tr -d ' '); fi
|
||||
|
||||
if [ "$dockercontainers" -eq "0" ] && [ "$lxccontainers" -eq "0" ] && [ "$rktcontainers" -eq "0" ] && [ "$podmancontainers" -eq "0" ] && [ "$nerdctlcontainers" -eq "0" ] && [ "$crictlcontainers" -eq "0" ] && [ "$ctrcontainers" -eq "0" ]; then
|
||||
echo_no
|
||||
else
|
||||
containerCounts=""
|
||||
@@ -80,6 +113,9 @@ else
|
||||
if [ "$podmancontainers" -ne "0" ]; then containerCounts="${containerCounts}podman($podmancontainers) "; fi
|
||||
if [ "$lxccontainers" -ne "0" ]; then containerCounts="${containerCounts}lxc($lxccontainers) "; fi
|
||||
if [ "$rktcontainers" -ne "0" ]; then containerCounts="${containerCounts}rkt($rktcontainers) "; fi
|
||||
if [ "$nerdctlcontainers" -ne "0" ]; then containerCounts="${containerCounts}nerdctl($nerdctlcontainers) "; fi
|
||||
if [ "$crictlcontainers" -ne "0" ]; then containerCounts="${containerCounts}crictl($crictlcontainers) "; fi
|
||||
if [ "$ctrcontainers" -ne "0" ]; then containerCounts="${containerCounts}ctr($ctrcontainers) "; fi
|
||||
echo "Yes $containerCounts" | sed -${E} "s,.*,${SED_RED},"
|
||||
|
||||
# List any running containers with more details
|
||||
@@ -111,7 +147,22 @@ else
|
||||
#rkt status $(rkt list --format=json 2>/dev/null | jq -r '.[].id') 2>/dev/null | grep -E "privileged|capabilities|security" | sed -${E} "s,true|privileged|host,${SED_RED},g"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$nerdctlcontainers" -ne "0" ]; then
|
||||
echo "Running nerdctl Containers" | sed -${E} "s,.*,${SED_RED},"
|
||||
nerdctl ps -a 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
if [ "$crictlcontainers" -ne "0" ]; then
|
||||
echo "Running CRI Containers" | sed -${E} "s,.*,${SED_RED},"
|
||||
crictl ps -a 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
if [ "$ctrcontainers" -ne "0" ]; then
|
||||
echo "Running ctr Containers (k8s.io namespace)" | sed -${E} "s,.*,${SED_RED},"
|
||||
ctr -n k8s.io containers list 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
@@ -19,7 +19,7 @@ if echo "$containerType" | grep -qi "docker"; then
|
||||
print_2title "Docker Container details" "T1613"
|
||||
inDockerGroup
|
||||
print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Looking and enumerating Docker Sockets (if any):\n"$NC
|
||||
print_list "Looking and enumerating runtime sockets:\n"$NC
|
||||
enumerateDockerSockets
|
||||
print_list "Docker version .................$NC$dockerVersion"
|
||||
checkDockerVersionExploits
|
||||
@@ -35,4 +35,4 @@ if echo "$containerType" | grep -qi "docker"; then
|
||||
print_2title "Docker Overlays" "T1613"
|
||||
df -h | grep docker
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,54 +1,22 @@
|
||||
# Title: Container - Container & breakout enumeration
|
||||
# ID: CT_Container_breakout
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 07-03-2024
|
||||
# Description: Container breakout enumeration to identify potential escape vectors:
|
||||
# - Container runtime vulnerabilities
|
||||
# - Mount point misconfigurations
|
||||
# - Capability abuse
|
||||
# - Namespace escape
|
||||
# - Common vulnerable scenarios:
|
||||
# * Privileged containers
|
||||
# * Misconfigured mounts
|
||||
# * Excessive capabilities
|
||||
# * Namespace isolation bypass
|
||||
# * Runtime vulnerabilities
|
||||
# * Container escape tools
|
||||
# * Shared kernel exploits
|
||||
# * Container escape CVEs
|
||||
# - Exploitation methods:
|
||||
# * Mount escape: Abuse mount misconfigurations
|
||||
# * Capability abuse: Exploit excessive capabilities
|
||||
# * Namespace escape: Break out of container namespaces
|
||||
# * Runtime escape: Exploit container runtime vulnerabilities
|
||||
# * Common attack vectors:
|
||||
# - Mount point manipulation
|
||||
# - Capability exploitation
|
||||
# - Namespace breakout
|
||||
# - Runtime vulnerability abuse
|
||||
# - Kernel exploit abuse
|
||||
# - Container escape tool usage
|
||||
# * Exploit techniques:
|
||||
# - Mount point abuse
|
||||
# - Capability escalation
|
||||
# - Namespace escape
|
||||
# - Runtime exploitation
|
||||
# - Kernel exploitation
|
||||
# - Container escape tool execution
|
||||
# Last Update: 21-03-2026
|
||||
# Description: Enumerate container hardening, breakout surfaces, runtime exposure, and high-impact escape vectors from inside a container.
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Mitre: T1611
|
||||
# Functions Used: checkContainerExploits, checkProcSysBreakouts, containerCheck, enumerateDockerSockets, print_2title, print_3title, print_info, print_list, warn_exec
|
||||
# Global Variables: $binfmt_misc_breakout, $containercapsB, $containerType, $core_pattern_breakout, $dev_mounted, $efi_efivars_writable, $efi_vars_writable, $GREP_IGNORE_MOUNTS, $inContainer, $kallsyms_readable, $kcore_readable, $kmem_readable, $kmem_writable, $kmsg_readable, $mem_readable, $mem_writable, $modprobe_present, $mountinfo_readable, $panic_on_oom_dos, $panic_sys_fs_dos, $proc_configgz_readable, $proc_mounted, $run_unshare, $release_agent_breakout1, $release_agent_breakout2, $release_agent_breakout3, $sched_debug_readable, $security_present, $security_writable, $sysreq_trigger_dos, $uevent_helper_breakout, $vmcoreinfo_readable, $VULN_CVE_2019_5021, $self_mem_readable
|
||||
# Global Variables: $binfmt_misc_breakout, $containercapsB, $containerType, $core_pattern_breakout, $debugfs_present, $debugfs_readable, $dev_mounted, $efi_efivars_writable, $efi_vars_writable, $GREP_IGNORE_MOUNTS, $inContainer, $kallsyms_readable, $kcore_readable, $kmem_readable, $kmem_writable, $kmsg_readable, $mem_readable, $mem_writable, $modprobe_binary, $modprobe_config_writable, $mountinfo_readable, $panic_on_oom_dos, $panic_sys_fs_dos, $proc_configgz_readable, $proc_keys_readable, $proc_mounted, $proc_timer_list_readable, $release_agent_breakout1, $release_agent_breakout2, $release_agent_breakout3, $run_unshare, $sched_debug_readable, $security_present, $security_writable, $self_mem_readable, $sys_firmware_readable, $sysreq_trigger_dos, $thermal_present, $thermal_readable, $uevent_helper_breakout, $vmcoreinfo_readable, $VULN_CVE_2019_5021
|
||||
# Initial Functions: containerCheck
|
||||
# Generated Global Variables: $defautl_docker_caps, $containerd_version, $runc_version, $seccomp_mode_num, $seccomp_mode_desc
|
||||
# Generated Global Variables: $container_breakout_tools, $containerd_version, $defautl_docker_caps, $gid_map_value, $host_process_count, $host_process_indicators, $no_new_privs_num, $proc_comm, $root_mount_mode, $runc_version, $seccomp_mode_desc, $seccomp_mode_num, $selinux_context, $selinux_status, $setgroups_value, $tool, $uid_map_value
|
||||
# Fat linpeas: 0
|
||||
# Small linpeas: 0
|
||||
|
||||
if [ "$inContainer" ]; then
|
||||
echo ""
|
||||
print_2title "Container & breakout enumeration" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/index.html"
|
||||
|
||||
# Basic container info
|
||||
print_list "Container ID ...................$NC $(cat /etc/hostname && echo -n '\n')"
|
||||
@@ -56,8 +24,8 @@ if [ "$inContainer" ]; then
|
||||
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
|
||||
fi
|
||||
|
||||
# Security mechanisms
|
||||
print_3title "Security Mechanisms" "T1611"
|
||||
# Hardening and isolation controls
|
||||
print_3title "Hardening & isolation" "T1611"
|
||||
seccomp_mode_num="$(awk '/^Seccomp:/{print $2}' /proc/self/status 2>/dev/null)"
|
||||
seccomp_mode_desc="unknown"
|
||||
case "$seccomp_mode_num" in
|
||||
@@ -74,17 +42,57 @@ if [ "$inContainer" ]; then
|
||||
awk '/^Seccomp_filters:/{print $2}' /proc/self/status 2>/dev/null | sed -${E} "s,^[0-9]+$,${SED_GREEN}&,"
|
||||
fi
|
||||
|
||||
print_list "AppArmor profile? .............. "$NC
|
||||
no_new_privs_num="$(awk '/^NoNewPrivs:/{print $2}' /proc/self/status 2>/dev/null)"
|
||||
print_list "NoNewPrivs ..................... "$NC
|
||||
case "$no_new_privs_num" in
|
||||
1) printf "enabled (1)\n" | sed -${E} "s,enabled,${SED_GREEN}," ;;
|
||||
0) printf "disabled (0)\n" | sed -${E} "s,disabled,${SED_RED_YELLOW}," ;;
|
||||
*) printf "unknown\n" ;;
|
||||
esac
|
||||
|
||||
print_list "AppArmor profile ............... "$NC
|
||||
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
|
||||
|
||||
print_list "User proc namespace? ........... "$NC
|
||||
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then
|
||||
(printf "enabled"; cat /proc/self/uid_map) | sed "s,enabled,${SED_GREEN},";
|
||||
echo ""
|
||||
echo " Mappings (Container -> Host -> Range):"
|
||||
cat /proc/self/uid_map | awk '{print " " $1 " -> " $2 " -> " $3}'
|
||||
else
|
||||
echo "disabled" | sed "s,disabled,${SED_RED},";
|
||||
selinux_status="disabled"
|
||||
if command -v getenforce >/dev/null 2>&1; then
|
||||
selinux_status="$(getenforce 2>/dev/null || echo disabled)"
|
||||
elif [ -r /sys/fs/selinux/enforce ]; then
|
||||
if [ "$(cat /sys/fs/selinux/enforce 2>/dev/null)" = "1" ]; then
|
||||
selinux_status="Enforcing"
|
||||
else
|
||||
selinux_status="Permissive"
|
||||
fi
|
||||
fi
|
||||
print_list "SELinux status ................. "$NC
|
||||
printf "%s\n" "$selinux_status" | sed -${E} "s,Enforcing,${SED_GREEN},g" | sed -${E} "s,Permissive,${SED_RED_YELLOW},g" | sed -${E} "s,disabled,${SED_RED},g"
|
||||
|
||||
selinux_context="$(cat /proc/self/attr/current 2>/dev/null | grep -E ':' || true)"
|
||||
if [ "$selinux_context" ]; then
|
||||
print_list "SELinux context ................ "$NC
|
||||
printf "%s\n" "$selinux_context" | sed -${E} "s,container_t|spc_t,${SED_RED_YELLOW}&,g"
|
||||
fi
|
||||
|
||||
uid_map_value="$(cat /proc/self/uid_map 2>/dev/null)"
|
||||
gid_map_value="$(cat /proc/self/gid_map 2>/dev/null)"
|
||||
setgroups_value="$(cat /proc/self/setgroups 2>/dev/null)"
|
||||
print_list "User namespace mappings ....... "$NC
|
||||
if echo "$uid_map_value" | grep -Eq "^[[:space:]]*0[[:space:]]+0[[:space:]]+4294967295[[:space:]]*$"; then
|
||||
echo "initial user namespace" | sed -${E} "s,initial user namespace,${SED_RED_YELLOW},"
|
||||
elif [ "$uid_map_value" ]; then
|
||||
echo "remapped user namespace" | sed -${E} "s,remapped user namespace,${SED_GREEN},"
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
if [ "$uid_map_value" ]; then
|
||||
echo " UID map (container -> host -> range):"
|
||||
echo "$uid_map_value" | awk '{print " " $1 " -> " $2 " -> " $3}'
|
||||
fi
|
||||
if [ "$gid_map_value" ]; then
|
||||
echo " GID map (container -> host -> range):"
|
||||
echo "$gid_map_value" | awk '{print " " $1 " -> " $2 " -> " $3}'
|
||||
fi
|
||||
if [ "$setgroups_value" ]; then
|
||||
echo " setgroups: $setgroups_value"
|
||||
fi
|
||||
|
||||
# Known vulnerabilities
|
||||
@@ -93,8 +101,17 @@ if [ "$inContainer" ]; then
|
||||
print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
|
||||
# Check for container escape tools
|
||||
print_list "Container escape tools present .. "$NC
|
||||
(command -v nsenter || command -v unshare || command -v chroot || command -v capsh || command -v setcap || command -v getcap || command -v docker || command -v kubectl || command -v ctr || command -v runc || command -v containerd || command -v crio || command -v podman || command -v lxc || command -v rkt || command -v nerdctl || echo "No") | sed -${E} "s,nsenter|unshare|chroot|capsh|setcap|getcap|docker|kubectl|ctr|runc|containerd|crio|podman|lxc|rkt|nerdctl,${SED_RED},g"
|
||||
container_breakout_tools="$(
|
||||
for tool in nsenter unshare chroot capsh setcap getcap docker kubectl ctr runc containerd crio podman lxc rkt nerdctl; do
|
||||
command -v "$tool" 2>/dev/null
|
||||
done
|
||||
)"
|
||||
print_list "Container escape tools present . "$NC
|
||||
if [ "$container_breakout_tools" ]; then
|
||||
printf "%s\n" "$container_breakout_tools" | sed -${E} "s,.*,${SED_RED}&,"
|
||||
else
|
||||
echo "No"
|
||||
fi
|
||||
|
||||
# Runtime vulnerabilities
|
||||
print_3title "Runtime Vulnerabilities" "T1611"
|
||||
@@ -129,30 +146,32 @@ if [ "$inContainer" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mount escape vectors
|
||||
print_3title "Breakout via mounts" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.html"
|
||||
# Mount, procfs and sysfs escape surfaces
|
||||
print_3title "Mount, procfs & sysfs surfaces" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/sensitive-host-mounts.html"
|
||||
|
||||
checkProcSysBreakouts
|
||||
print_list "/proc mounted? ................. $proc_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "/dev mounted? .................. $dev_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
root_mount_mode="$(awk '$5=="/"{print $6; exit}' /proc/self/mountinfo 2>/dev/null | cut -d',' -f1)"
|
||||
print_list "/proc heavily populated ........ $proc_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "/dev heavily populated ......... $dev_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Root filesystem mode ........... ${root_mount_mode:-unknown}\n" | sed -${E} "s,rw,${SED_RED_YELLOW}," | sed -${E} "s,ro,${SED_GREEN},"
|
||||
print_list "Run unshare .................... $run_unshare\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "release_agent breakout 3........ $release_agent_breakout3\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "release_agent surface 1 ........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "release_agent surface 2 ........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "release_agent surface 3 ........ $release_agent_breakout3\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Writable core_pattern .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Writable binfmt_misc/register .. $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Writable uevent_helper ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
|
||||
# Additional mount checks
|
||||
print_list "Docker socket mounted? ......... "$NC
|
||||
(mount | grep -E "docker.sock|/var/run/docker.sock" || echo "No") | sed -${E} "s,Yes|docker.sock,${SED_RED},"
|
||||
print_list "Mounted runtime sockets ........ "$NC
|
||||
(mount | grep -E "docker.sock|containerd.sock|crio.sock|podman.sock|buildkitd.sock|kubelet.sock|firecracker-containerd.sock" || echo "No") | sed -${E} "s,docker.sock|containerd.sock|crio.sock|podman.sock|buildkitd.sock|kubelet.sock|firecracker-containerd.sock,${SED_RED},g"
|
||||
|
||||
print_list "Common host filesystem mounted? "$NC
|
||||
(mount | grep -E "host|/host|/mnt/host" || echo "No") | sed -${E} "s,Yes|host,${SED_RED},"
|
||||
(mount | grep -E "host|/host|/mnt/host|/rootfs" || echo "No") | sed -${E} "s,host|/host|/mnt/host|/rootfs,${SED_RED},g"
|
||||
|
||||
print_list "Interesting mounts ............. "$NC
|
||||
mount | grep -E "docker|container|overlay|kubelet" | grep -v "proc" | sed -${E} "s,docker.sock|host|privileged,${SED_RED},g"
|
||||
mount | grep -E "docker|container|overlay|kubelet|buildkit|crio|podman|/host|/rootfs" | grep -v "proc" | sed -${E} "s,docker.sock|containerd.sock|crio.sock|podman.sock|kubelet.sock|buildkitd.sock|host|rootfs|privileged,${SED_RED},g"
|
||||
|
||||
# Check for writable mount points
|
||||
print_list "Writable mount points ......... "$NC
|
||||
@@ -164,7 +183,7 @@ if [ "$inContainer" ]; then
|
||||
|
||||
# Capability checks
|
||||
print_3title "Capability Checks" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/capabilities-abuse-escape.html"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/protections/capabilities.html"
|
||||
|
||||
print_list "Dangerous capabilities ......... "$NC
|
||||
if [ "$(command -v capsh || echo -n '')" ]; then
|
||||
@@ -179,70 +198,67 @@ if [ "$inContainer" ]; then
|
||||
(grep "CapAmb:" /proc/self/status 2>/dev/null | grep -v "0000000000000000" | sed "s,CapAmb:.,," || echo "No") | sed -${E} "s,No,${SED_GREEN}," | sed -${E} "s,[0-9a-fA-F]\+,${SED_RED}&,"
|
||||
|
||||
# Additional capability checks
|
||||
print_list "Dangerous syscalls allowed ... "$NC
|
||||
print_list "ptrace_scope (host) ........... "$NC
|
||||
if [ -f "/proc/sys/kernel/yama/ptrace_scope" ]; then
|
||||
(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null || echo "Not found") | sed -${E} "s,0,${SED_RED},"
|
||||
else
|
||||
echo "Not found"
|
||||
fi
|
||||
|
||||
# Namespace checks
|
||||
print_3title "Namespace Checks" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/namespaces/index.html"
|
||||
# Namespace checks. From inside a container we often cannot prove host namespace sharing directly,
|
||||
# so prefer raw namespace handles and practical indicators over misleading "host namespace = yes/no" guesses.
|
||||
print_3title "Namespaces & sharing indicators" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/protections/namespaces/index.html"
|
||||
|
||||
print_list "Current namespaces ............. "$NC
|
||||
ls -l /proc/self/ns/
|
||||
|
||||
print_list "Host network namespace? ........ "$NC
|
||||
if [ "$(ip netns list 2>/dev/null)" ]; then
|
||||
echo "Yes - Host network namespace accessible" | sed -${E} "s,Yes,${SED_RED},"
|
||||
if ps -e -o pid= >/dev/null 2>&1; then
|
||||
host_process_count="$(ps -e -o pid= 2>/dev/null | wc -l | tr -d ' ')"
|
||||
host_process_indicators="$(ps -eo comm= 2>/dev/null | grep -E '^(systemd|init|kthreadd|dockerd|containerd|kubelet|sshd|udevd|NetworkManager|dbus-daemon)$' | sort -u)"
|
||||
else
|
||||
echo "No"
|
||||
host_process_count="$(ls -d /proc/[0-9]* 2>/dev/null | wc -l | tr -d ' ')"
|
||||
host_process_indicators="$(for proc_comm in /proc/[0-9]*/comm; do cat "$proc_comm" 2>/dev/null; done | grep -E '^(systemd|init|kthreadd|dockerd|containerd|kubelet|sshd|udevd|NetworkManager|dbus-daemon)$' | sort -u)"
|
||||
fi
|
||||
|
||||
# Additional namespace checks
|
||||
print_list "Host IPC namespace? ........... "$NC
|
||||
if [ "$(ls -l /proc/self/ns/ipc 2>/dev/null)" = "$(ls -l /proc/1/ns/ipc 2>/dev/null)" ]; then
|
||||
echo "Yes - Host IPC namespace shared" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "Processes visible .............. $host_process_count\n" | sed -${E} "s,^[^0-9]*([5-9][0-9]|[1-9][0-9]{2,}).*,${SED_RED_YELLOW}&,"
|
||||
print_list "Host-like processes visible .... "$NC
|
||||
if [ "$host_process_indicators" ]; then
|
||||
printf "%s\n" "$host_process_indicators" | sed -${E} "s,.*,${SED_RED_YELLOW}&,"
|
||||
else
|
||||
echo "No"
|
||||
echo "No obvious host daemons"
|
||||
fi
|
||||
|
||||
print_list "Host PID namespace? ........... "$NC
|
||||
if [ "$(ls -l /proc/self/ns/pid 2>/dev/null)" = "$(ls -l /proc/1/ns/pid 2>/dev/null)" ]; then
|
||||
echo "Yes - Host PID namespace shared" | sed -${E} "s,Yes,${SED_RED},"
|
||||
|
||||
print_list "Network interfaces ............. "$NC
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
ip -o link show 2>/dev/null | awk -F': ' '{print $2}'
|
||||
else
|
||||
echo "No"
|
||||
ls /sys/class/net 2>/dev/null
|
||||
fi
|
||||
|
||||
print_list "Host UTS namespace? ........... "$NC
|
||||
if [ "$(ls -l /proc/self/ns/uts 2>/dev/null)" = "$(ls -l /proc/1/ns/uts 2>/dev/null)" ]; then
|
||||
echo "Yes - Host UTS namespace shared" | sed -${E} "s,Yes,${SED_RED},"
|
||||
else
|
||||
echo "No"
|
||||
fi
|
||||
|
||||
|
||||
print_list "Looking and enumerating Docker Sockets (if any):\n"$NC
|
||||
|
||||
print_list "Namespace inode summary ........ "$NC
|
||||
for ns in cgroup ipc mnt net pid time user uts; do
|
||||
if [ -L "/proc/self/ns/$ns" ]; then
|
||||
printf "%s -> %s\n" "$ns" "$(readlink "/proc/self/ns/$ns" 2>/dev/null)"
|
||||
fi
|
||||
done
|
||||
|
||||
print_list "Looking and enumerating runtime sockets:\n"$NC
|
||||
enumerateDockerSockets
|
||||
|
||||
# Additional breakout vectors
|
||||
print_3title "Additional Breakout Vectors" "T1611"
|
||||
print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED},"
|
||||
print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_3title "Writable kernel helper paths" "T1611"
|
||||
print_list "modprobe helper binary ......... $modprobe_binary\n" | sed -${E} "s,/.*,${SED_RED},"
|
||||
print_list "modprobe path writable ......... $modprobe_config_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "panic_on_oom writable .......... $panic_on_oom_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "suid_dumpable writable ......... $panic_sys_fs_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
|
||||
# Check for container escape tools in PATH
|
||||
print_list "Container escape tools in PATH . "$NC
|
||||
(which nsenter 2>/dev/null || which unshare 2>/dev/null || which chroot 2>/dev/null || which capsh 2>/dev/null || which setcap 2>/dev/null || which getcap 2>/dev/null || echo "No") | sed -${E} "s,nsenter|unshare|chroot|capsh|setcap|getcap,${SED_RED},g"
|
||||
|
||||
print_3title "Extra Breakout Vectors" "T1611"
|
||||
print_3title "Sensitive procfs/sysfs exposure" "T1611"
|
||||
print_list "/proc/config.gz readable ....... $proc_configgz_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/keys readable ............ $proc_keys_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/timer_list readable ...... $proc_timer_list_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/self/mem readable ........ $self_mem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
@@ -251,6 +267,13 @@ if [ "$inContainer" ]; then
|
||||
print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/firmware readable ......... $sys_firmware_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/debug present ...... $debugfs_present\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/debug readable ..... $debugfs_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/class/thermal present ..... $thermal_present\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "/sys/class/thermal readable .... $thermal_readable\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
@@ -270,10 +293,10 @@ if [ "$inContainer" ]; then
|
||||
|
||||
# Additional container runtime checks
|
||||
print_list "Container runtime sockets .. "$NC
|
||||
(find /var/run -name "*.sock" 2>/dev/null | grep -E "docker|containerd|crio|podman|lxc|rkt" || echo "No") | sed -${E} "s,docker|containerd|crio|podman|lxc|rkt,${SED_RED},g"
|
||||
(find /var/run /run -name "*.sock" 2>/dev/null | grep -E "docker|containerd|crio|podman|lxc|rkt|kubelet|buildkit|firecracker" || echo "No") | sed -${E} "s,docker|containerd|crio|podman|lxc|rkt|kubelet|buildkit|firecracker,${SED_RED},g"
|
||||
|
||||
print_list "Container runtime configs .. "$NC
|
||||
(find /etc -name "*.conf" -o -name "*.json" 2>/dev/null | grep -E "docker|containerd|crio|podman|lxc|rkt" || echo "No") | sed -${E} "s,docker|containerd|crio|podman|lxc|rkt,${SED_RED},g"
|
||||
(find /etc -name "*.conf" -o -name "*.json" 2>/dev/null | grep -E "docker|containerd|crio|podman|lxc|rkt|kubelet|buildkit|firecracker" || echo "No") | sed -${E} "s,docker|containerd|crio|podman|lxc|rkt|kubelet|buildkit|firecracker,${SED_RED},g"
|
||||
|
||||
# Kubernetes specific checks
|
||||
if echo "$containerType" | grep -qi "kubernetes"; then
|
||||
|
||||
@@ -21,7 +21,7 @@ containerCheck
|
||||
if [ "$inContainer" ]; then
|
||||
echo ""
|
||||
print_2title "Container - Writable bind mounts w/o nosuid (SUID persistence risk)" "T1611"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/index.html#writable-bind-mounts"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/privileged-containers.html#writable-bind-mounts"
|
||||
|
||||
if [ -r /proc/self/mountinfo ]; then
|
||||
CT_RW_bind_mounts_matches=$(grep -E "(^| )bind( |$)" /proc/self/mountinfo 2>/dev/null | grep -E "(^|,)rw(,|$)" | grep -v "nosuid" || true)
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
# Title: Software Information - containerd installed
|
||||
# ID: SI_Containerd
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 22-08-2023
|
||||
# Description: containerd installed
|
||||
# Last Update: 21-03-2026
|
||||
# Description: containerd and related CRI/containerd client tooling installed
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Mitre: T1613
|
||||
# Functions Used: print_2title, print_info
|
||||
# Global Variables: $DEBUG, $SEARCH_IN_FOLDER
|
||||
# Initial Functions:
|
||||
# Generated Global Variables: $containerd
|
||||
# Generated Global Variables: $containerd, $containerd_cli, $crictl_cli, $nerdctl_cli
|
||||
# Fat linpeas: 0
|
||||
# Small linpeas: 1
|
||||
|
||||
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
containerd=$(command -v ctr || echo -n '')
|
||||
if [ "$containerd" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Checking if containerd(ctr) is available" "T1613"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#containerd-ctr-privilege-escalation"
|
||||
containerd=$(command -v containerd || echo -n '')
|
||||
containerd_cli=$(command -v ctr || echo -n '')
|
||||
nerdctl_cli=$(command -v nerdctl || echo -n '')
|
||||
crictl_cli=$(command -v crictl || echo -n '')
|
||||
if [ "$containerd" ] || [ "$containerd_cli" ] || [ "$nerdctl_cli" ] || [ "$crictl_cli" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Checking if containerd/CRI tooling is available" "T1613"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/runtime-api-and-daemon-exposure.html"
|
||||
if [ "$containerd" ]; then
|
||||
echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
echo "containerd was found in $containerd" | sed -${E} "s,.*,${SED_RED},"
|
||||
fi
|
||||
if [ "$containerd_cli" ]; then
|
||||
echo "ctr was found in $containerd_cli, you may be able to inspect or manage containerd content with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
ctr image list 2>&1
|
||||
fi
|
||||
if [ "$nerdctl_cli" ]; then
|
||||
echo "nerdctl was found in $nerdctl_cli, you may be able to interact with containerd namespaces and containers with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
nerdctl images 2>&1
|
||||
fi
|
||||
if [ "$crictl_cli" ]; then
|
||||
echo "crictl was found in $crictl_cli, you may be able to inspect CRI-managed containers with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
crictl images 2>&1
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
if [ "$PSTORAGE_DOCKER" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching docker files (limit 70)" "T1613"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/docker-security/index.html#docker-breakout--privilege-escalation"
|
||||
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/container-security/index.html"
|
||||
printf "%s\n" "$PSTORAGE_DOCKER" | head -n 70 | while read f; do
|
||||
ls -l "$f" 2>/dev/null
|
||||
if ! [ "$IAMROOT" ] && [ -S "$f" ] && [ -w "$f" ]; then
|
||||
@@ -24,4 +24,4 @@ if [ "$PSTORAGE_DOCKER" ] || [ "$DEBUG" ]; then
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -14,12 +14,15 @@
|
||||
|
||||
|
||||
checkCreateReleaseAgent(){
|
||||
cat /proc/$$/cgroup 2>/dev/null | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$' | while read -r ss
|
||||
do
|
||||
if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $ss cgroup /tmp/cgroup_3628d4 2>&1 >/dev/null && test -w /tmp/cgroup_3628d4/release_agent" >/dev/null 2>&1 ; then
|
||||
release_agent_breakout3="Yes (unshare with $ss)";
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
release_agent_breakout3="${release_agent_breakout3:-No}"
|
||||
for ss in $(awk -F: '/^[0-9]+:/{print $2}' /proc/$$/cgroup 2>/dev/null); do
|
||||
if unshare -UrmC --propagation=unchanged sh -c "mount -t cgroup -o $ss cgroup /tmp/cgroup_3628d4 >/dev/null 2>&1 && test -w /tmp/cgroup_3628d4/release_agent" >/dev/null 2>&1 ; then
|
||||
release_agent_breakout3="Yes (unshare with $ss)"
|
||||
umount /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
rm -rf /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
break
|
||||
fi
|
||||
umount /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
rm -rf /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
# Title: Container - checkProcSysBreakouts
|
||||
# ID: checkProcSysBreakouts
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 22-08-2023
|
||||
# Description: Check if the container is vulnerable to several breakouts abusing /sys and /proc folders
|
||||
# Last Update: 21-03-2026
|
||||
# Description: Check whether procfs/sysfs/cgroup surfaces exposed inside a container could be used for breakout, host discovery, or high-impact abuse.
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Functions Used: checkCreateReleaseAgent
|
||||
# Global Variables:
|
||||
# Initial Functions:
|
||||
# Generated Global Variables: $dev_mounted, $proc_mounted, $run_unshare, $release_agent_breakout1, $release_agent_breakout2, $core_pattern_breakout, $modprobe_present, $panic_on_oom_dos, $panic_on_oom, $panic_on, $panic_sys_fs_dos, $binfmt_misc_breakout, $proc_configgz_readable, $sysreq_trigger_dos, $kmsg_readable, $kallsyms_readable, $self_mem_readable, $mem_readable, $kmem_readable, $kmem_writable, $mem_writable, $sched_debug_readable, $mountinfo_readable, $uevent_helper_breakout, $vmcoreinfo_readable, $security_present, $security_writable, $efi_vars_writable, $efi_efivars_writable, $kcore_readable
|
||||
# Generated Global Variables: $dev_mounted, $proc_mounted, $run_unshare, $release_agent_breakout1, $release_agent_breakout2, $core_pattern_breakout, $modprobe_binary, $modprobe_config_writable, $panic_on_oom_dos, $panic_on_oom, $panic_on, $panic_sys_fs_dos, $binfmt_misc_breakout, $proc_configgz_readable, $sysreq_trigger_dos, $kmsg_readable, $kallsyms_readable, $self_mem_readable, $mem_readable, $kmem_readable, $kmem_writable, $mem_writable, $sched_debug_readable, $mountinfo_readable, $mountinfo_file, $uevent_helper_breakout, $vmcoreinfo_readable, $security_present, $security_writable, $efi_vars_writable, $efi_efivars_writable, $kcore_readable, $proc_keys_readable, $proc_timer_list_readable, $sys_firmware_readable, $debugfs_present, $debugfs_readable, $thermal_present, $thermal_readable, $thermal_file
|
||||
# Fat linpeas: 0
|
||||
# Small linpeas: 1
|
||||
|
||||
|
||||
checkProcSysBreakouts(){
|
||||
can_open_for_write() {
|
||||
if [ -e "$1" ] && command -v dd >/dev/null 2>&1 && dd if=/dev/null of="$1" bs=1 count=0 conv=notrunc >/dev/null 2>&1; then
|
||||
echo Yes
|
||||
else
|
||||
echo No
|
||||
fi
|
||||
}
|
||||
|
||||
dev_mounted="No"
|
||||
if [ $(ls -l /dev | grep -E "^c" | wc -l) -gt 50 ]; then
|
||||
dev_mounted="Yes";
|
||||
@@ -24,7 +32,9 @@ checkProcSysBreakouts(){
|
||||
proc_mounted="Yes";
|
||||
fi
|
||||
|
||||
run_unshare=$(unshare -UrmC bash -c 'echo -n Yes' 2>/dev/null)
|
||||
if command -v unshare >/dev/null 2>&1 && command -v sh >/dev/null 2>&1; then
|
||||
run_unshare=$(unshare -UrmC sh -c 'echo -n Yes' 2>/dev/null)
|
||||
fi
|
||||
if ! [ "$run_unshare" = "Yes" ]; then
|
||||
run_unshare="No"
|
||||
fi
|
||||
@@ -36,15 +46,17 @@ checkProcSysBreakouts(){
|
||||
fi
|
||||
|
||||
release_agent_breakout2="No"
|
||||
mkdir /tmp/cgroup_3628d4
|
||||
mkdir -p /tmp/cgroup_3628d4
|
||||
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
release_agent_breakout2="Yes";
|
||||
umount /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
else
|
||||
mount -t cgroup -o rdma cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
release_agent_breakout2="Yes";
|
||||
umount /tmp/cgroup_3628d4 >/dev/null 2>&1
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
else
|
||||
checkCreateReleaseAgent
|
||||
@@ -52,27 +64,48 @@ checkProcSysBreakouts(){
|
||||
fi
|
||||
rm -rf /tmp/cgroup_3628d4 2>/dev/null
|
||||
|
||||
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
|
||||
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` 2>/dev/null || echo No)"
|
||||
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
|
||||
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
|
||||
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
|
||||
# Prefer zero-byte open-for-write checks here so special files are validated more accurately without trying to change their contents.
|
||||
core_pattern_breakout="$(can_open_for_write /proc/sys/kernel/core_pattern)"
|
||||
modprobe_binary="$(ls -l "$(cat /proc/sys/kernel/modprobe 2>/dev/null)" 2>/dev/null || echo No)"
|
||||
modprobe_config_writable="$(can_open_for_write /proc/sys/kernel/modprobe)"
|
||||
panic_on_oom_dos="$(can_open_for_write /proc/sys/vm/panic_on_oom)"
|
||||
panic_sys_fs_dos="$(can_open_for_write /proc/sys/fs/suid_dumpable)"
|
||||
binfmt_misc_breakout="$(can_open_for_write /proc/sys/fs/binfmt_misc/register)"
|
||||
proc_configgz_readable="$([ -r '/proc/config.gz' ] 2>/dev/null && echo Yes || echo No)"
|
||||
sysreq_trigger_dos="$( (echo -n '' > /proc/sysrq-trigger && echo Yes) 2>/dev/null || echo No)"
|
||||
sysreq_trigger_dos="$(can_open_for_write /proc/sysrq-trigger)"
|
||||
kmsg_readable="$( (dmesg > /dev/null 2>&1 && echo Yes) 2>/dev/null || echo No)" # Kernel Exploit Dev
|
||||
kallsyms_readable="$( (head -n 1 /proc/kallsyms > /dev/null && echo Yes )2>/dev/null || echo No)" # Kernel Exploit Dev
|
||||
self_mem_readable="$( (head -n 1 /proc/self/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
if [ "$(head -n 1 /tmp/kcore 2>/dev/null)" ]; then kcore_readable="Yes"; else kcore_readable="No"; fi
|
||||
if [ "$(head -n 1 /proc/kcore 2>/dev/null)" ]; then kcore_readable="Yes"; else kcore_readable="No"; fi
|
||||
kmem_readable="$( (head -n 1 /proc/kmem > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
kmem_writable="$( (echo -n '' > /proc/kmem > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
kmem_writable="$(can_open_for_write /proc/kmem)"
|
||||
mem_readable="$( (head -n 1 /proc/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
mem_writable="$( (echo -n '' > /proc/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
mem_writable="$(can_open_for_write /proc/mem)"
|
||||
sched_debug_readable="$( (head -n 1 /proc/sched_debug > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
mountinfo_readable="$( (head -n 1 /proc/*/mountinfo > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
uevent_helper_breakout="$( (echo -n '' > /sys/kernel/uevent_helper && echo Yes) 2>/dev/null || echo No)"
|
||||
mountinfo_readable="No"
|
||||
for mountinfo_file in /proc/[0-9]*/mountinfo; do
|
||||
if [ -r "$mountinfo_file" ]; then
|
||||
mountinfo_readable="Yes"
|
||||
break
|
||||
fi
|
||||
done
|
||||
uevent_helper_breakout="$(can_open_for_write /sys/kernel/uevent_helper)"
|
||||
vmcoreinfo_readable="$( (head -n 1 /sys/kernel/vmcoreinfo > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
security_present="$( (ls -l /sys/kernel/security > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
security_writable="$( (echo -n '' > /sys/kernel/security/a && echo Yes) 2>/dev/null || echo No)"
|
||||
efi_vars_writable="$( (echo -n '' > /sys/firmware/efi/vars && echo Yes) 2>/dev/null || echo No)"
|
||||
efi_efivars_writable="$( (echo -n '' > /sys/firmware/efi/efivars && echo Yes) 2>/dev/null || echo No)"
|
||||
security_writable="$([ -w /sys/kernel/security ] 2>/dev/null && echo Yes || echo No)"
|
||||
efi_vars_writable="$([ -w /sys/firmware/efi/vars ] 2>/dev/null && echo Yes || echo No)"
|
||||
efi_efivars_writable="$([ -w /sys/firmware/efi/efivars ] 2>/dev/null && echo Yes || echo No)"
|
||||
proc_keys_readable="$( (head -n 1 /proc/keys > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
proc_timer_list_readable="$( (head -n 1 /proc/timer_list > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
sys_firmware_readable="$([ -r /sys/firmware ] 2>/dev/null && echo Yes || echo No)"
|
||||
debugfs_present="$([ -d /sys/kernel/debug ] 2>/dev/null && echo Yes || echo No)"
|
||||
debugfs_readable="$( (ls -la /sys/kernel/debug > /dev/null && echo Yes) 2>/dev/null || echo No)"
|
||||
thermal_present="$([ -d /sys/class/thermal ] 2>/dev/null && echo Yes || echo No)"
|
||||
thermal_readable="No"
|
||||
for thermal_file in /sys/class/thermal/*/*; do
|
||||
if [ -f "$thermal_file" ] && [ -r "$thermal_file" ]; then
|
||||
thermal_readable="Yes"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Title: Container - containerCheck
|
||||
# ID: containerCheck
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 22-08-2023
|
||||
# Description: Check if we are inside a container
|
||||
# Last Update: 21-03-2026
|
||||
# Description: Check whether the current process appears to be running inside a Linux container and identify common runtime hints.
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Functions Used: echo_no
|
||||
@@ -21,7 +21,7 @@ containerCheck() {
|
||||
if [ -f "/.dockerenv" ] ||
|
||||
grep "/docker/" /proc/1/cgroup -qa 2>/dev/null ||
|
||||
grep -qai docker /proc/self/cgroup 2>/dev/null ||
|
||||
[ "$(find / -maxdepth 3 -name '*dockerenv*' -exec ls -la {} \; 2>/dev/null)" ] ; then
|
||||
[ -f "/run/.dockerenv" ] ; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="docker\n"
|
||||
@@ -50,22 +50,31 @@ containerCheck() {
|
||||
grep "/lxc/" /proc/1/cgroup -qa 2>/dev/null; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="lxc\n"
|
||||
if echo "$containerType" | grep -qv "lxc"; then
|
||||
if [ "$containerType" ] && [ "$containerType" != "$(echo_no)" ]; then containerType="$containerType (lxc)\n"
|
||||
else containerType="lxc\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Are we inside podman?
|
||||
if env | grep -qa "container=podman" 2>/dev/null ||
|
||||
if [ -f "/run/.containerenv" ] ||
|
||||
env | grep -qa "container=podman" 2>/dev/null ||
|
||||
grep -qa "container=podman" /proc/1/environ 2>/dev/null; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="podman\n"
|
||||
if echo "$containerType" | grep -qv "podman"; then
|
||||
if [ "$containerType" ] && [ "$containerType" != "$(echo_no)" ]; then containerType="$containerType (podman)\n"
|
||||
else containerType="podman\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for other container platforms that report themselves in PID 1 env
|
||||
if [ -z "$inContainer" ]; then
|
||||
if grep -a 'container=' /proc/1/environ 2>/dev/null; then
|
||||
if grep -qa 'container=' /proc/1/environ 2>/dev/null; then
|
||||
inContainer="1"
|
||||
containerType="$(grep -a 'container=' /proc/1/environ | cut -d= -f2)\n"
|
||||
containerType="$(tr '\000' '\n' < /proc/1/environ 2>/dev/null | awk -F= '/^container=/{print $2; exit}')\n"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# Title: Container - enumerateDockerSockets
|
||||
# ID: enumerateDockerSockets
|
||||
# Author: Carlos Polop
|
||||
# Last Update: 22-08-2023
|
||||
# Description: Search Docker Sockets
|
||||
# Last Update: 21-03-2026
|
||||
# Description: Search interesting container runtime, orchestration, and build sockets that could expose high-impact APIs from inside a container.
|
||||
# License: GNU GPL
|
||||
# Version: 1.0
|
||||
# Functions Used: echo_not_found
|
||||
# Global Variables: $GREP_DOCKER_SOCK_INFOS, $GREP_DOCKER_SOCK_INFOS_IGNORE
|
||||
# Initial Functions:
|
||||
# Generated Global Variables: $SEARCHED_DOCKER_SOCKETS, $docker_enumerated, $dockerVersion, $int_sock, $sockInfoResponse
|
||||
# Generated Global Variables: $SEARCHED_DOCKER_SOCKETS, $docker_enumerated, $dockerVersion, $int_sock, $sockInfoResponse, $IFS, $OLDIFS
|
||||
# Fat linpeas: 0
|
||||
# Small linpeas: 1
|
||||
|
||||
@@ -17,6 +17,9 @@ enumerateDockerSockets() {
|
||||
dockerVersion="$(echo_not_found)"
|
||||
if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then
|
||||
SEARCHED_DOCKER_SOCKETS="1"
|
||||
OLDIFS="$IFS"
|
||||
IFS='
|
||||
'
|
||||
# NOTE: This is intentionally "lightweight" (checks common runtime socket names) and avoids
|
||||
# pseudo filesystems (/sys, /proc) to reduce noise and latency.
|
||||
for int_sock in $(find / \
|
||||
@@ -25,9 +28,16 @@ enumerateDockerSockets() {
|
||||
-type s \( \
|
||||
-name "docker.sock" -o \
|
||||
-name "docker.socket" -o \
|
||||
-name "cri-dockerd.sock" -o \
|
||||
-name "dockershim.sock" -o \
|
||||
-name "containerd.sock" -o \
|
||||
-name "containerd.sock.ttrpc" -o \
|
||||
-name "crio.sock" -o \
|
||||
-name "podman.sock" -o \
|
||||
-name "kubelet.sock" -o \
|
||||
-name "buildkitd.sock" -o \
|
||||
-name "buildkit.sock" -o \
|
||||
-name "firecracker-containerd.sock" -o \
|
||||
-name "frakti.sock" -o \
|
||||
-name "rktlet.sock" \
|
||||
\) -print 2>/dev/null); do
|
||||
@@ -43,7 +53,7 @@ enumerateDockerSockets() {
|
||||
echo "You don't have write permissions over interesting socket $int_sock" | sed -${E} "s,$int_sock,${SED_GREEN},g"
|
||||
fi
|
||||
|
||||
# Validate whether this looks like a Docker Engine API socket (amicontained-style) when curl exists.
|
||||
# Validate whether this looks like a Docker-compatible API socket (amicontained-style) when curl exists.
|
||||
docker_enumerated=""
|
||||
if [ "$(command -v curl 2>/dev/null || echo -n '')" ]; then
|
||||
sockInfoResponse="$(curl -s --max-time 2 --unix-socket "$int_sock" http://localhost/info 2>/dev/null)"
|
||||
@@ -67,5 +77,6 @@ enumerateDockerSockets() {
|
||||
fi
|
||||
fi
|
||||
done
|
||||
IFS="$OLDIFS"
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user