shell / container-escape-check.sh
juppytt's picture
x
e0c04c2
raw
history blame
No virus
15.3 kB
#!/bin/bash
echo -e ""
echo -e "\033[34m=============================================================\033[0m"
echo -e "\033[34m Containers Escape Check v0.3 \033[0m"
echo -e "\033[34m-------------------------------------------------------------\033[0m"
echo -e "\033[34m Author: TeamsSix \033[0m"
echo -e "\033[34m Twitter: TeamsSix \033[0m"
echo -e "\033[34m Blog: teamssix.com \033[0m"
echo -e "\033[34m WeChat Official Accounts: TeamsSix \033[0m"
echo -e "\033[34m Project Address: github.com/teamssix/container-escape-check \033[0m"
echo -e "\033[34m=============================================================\033[0m"
echo -e ""
# Supported detection methods:
#
# 1. Privileged Mode
# 2. Mount Docker Socket
# 3. Mount Procfs
# 4. Mount Root Directory
# 5. Open Docker Remote API
# 6. CVE-2016-5195 DirtyCow
# 7. CVE-2020-14386
# 8. CVE-2022-0847 DirtyPipe
# 9. CVE-2017-1000112
# 10. CVE-2021-22555
# 11. Mount Host Var Log
# 12. CAP_DAC_READ_SEARCH
# 13. CAP_SYS_ADMIN
# 14. CAP_SYS_PTRACE
# 15. CVE-2022-0492
CheckCommandExists(){
$1 >/dev/null 2>&1
ret=$?
if [ "$ret" -eq 0 ]; then
return 1
fi
return 0
}
# Install command
InstallCommand(){
# install command if not present
CheckCommandExists $1
if [ $? -eq 0 ]; then
# Check network
timeout 3 bash -c "echo -e >/dev/tcp/baidu.com/80" > /dev/null 2>&1 && IsNetWork=1 || IsNetWork=0
if [ $IsNetWork -eq 1 ];then
echo -e "\033[93m[!] It is detected that the $1 command does not exist in the current system, and the command is being installed.\033[0m"
CheckCommandExists sudo
if [ $? -eq 0 ]; then
CheckCommandExists apt-get
if [ $? -eq 0 ];then
if [ "$1" = "capsh" ];then
apt-get -y update >/dev/null 2>&1 && apt-get install -y libcap2-bin >/dev/null 2>&1
else
apt-get -y update >/dev/null 2>&1 && apt-get install -y $1 >/dev/null 2>&1
fi
fi
CheckCommandExists yum
if [ $? -eq 0 ];then
if [ "$1" = "capsh" ];then
yum -y update >/dev/null 2>&1 && yum install -y libcap >/dev/null 2>&1
else
yum -y update >/dev/null 2>&1 && yum install -y $1 >/dev/null 2>&1
fi
fi
else
CheckCommandExists apt-get
if [ $? -eq 0 ];then
if [ "$1" = "capsh" ];then
sudo apt-get -y update >/dev/null 2>&1 && apt-get install -y libcap2-bin >/dev/null 2>&1
else
sudo apt-get -y update >/dev/null 2>&1 && apt-get install -y $1 >/dev/null 2>&1
fi
fi
CheckCommandExists yum
if [ $? -eq 0 ];then
if [ "$1" = "capsh" ];then
sudo yum -y update >/dev/null 2>&1 && yum install -y libcap >/dev/null 2>&1
else
sudo yum -y update >/dev/null 2>&1 && yum install -y $1 >/dev/null 2>&1
fi
fi
fi
CheckCommandExists $1
if [ $? -eq 0 ]; then
echo -e "\033[93m[!] $1 command installation failed.\033[0m"
else
echo -e "\033[93m[!] $1 command installation completed.\033[0m"
fi
fi
fi
}
# 0. Check The Current Environment
CheckTheCurrentEnvironment(){
if [ ! -f "/proc/1/cgroup" ];then
IsContainer=0
else
cat /proc/1/cgroup | grep -qi docker && IsContainer=1 || IsContainer=0
fi
if [ $IsContainer -eq 0 ];then
echo -e "\033[31m[-] Not currently a container environment.\033[0m"
exit 1
else
echo -e "\033[33m[!] Currently in a container, checking ......\033[0m"
VulnerabilityExists=0
fi
}
# 1. Check Privileged Mode
CheckPrivilegedMode(){
if [ ! -f "/proc/self/status" ];then
IsPrivilegedMode=0
else
cat /proc/self/status | grep -qi "0000003fffffffff" && IsPrivilegedMode=1 || IsPrivilegedMode=0
cat /proc/self/status | grep -qi "0000001fffffffff" && IsPrivilegedMode=1 || IsPrivilegedMode=0
fi
if [ $IsPrivilegedMode -eq 1 ];then
echo -e "\033[92m[+] The current container is in privileged mode.\033[0m"
VulnerabilityExists=1
fi
}
# 2. Check Docker Socket Mount
CheckDockerSocketMount(){
if [ ! -f "/var/run/docker.sock" ];then
IsDockerSocketMount=0
else
ls /var/run/ | grep -qi docker.sock && IsDockerSocketMount=1 || IsDockerSocketMount=0
fi
if [ $IsDockerSocketMount -eq 1 ];then
echo -e "\033[92m[+] The current container has docker socket mounted.\033[0m"
VulnerabilityExists=1
fi
}
# 3. Check Procfs Mount
CheckProcfsMount(){
find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && IsProcfsMount=1 || IsProcfsMount=0
if [ $IsProcfsMount -eq 1 ];then
echo -e "\033[92m[+] The current container has procfs mounted.\033[0m"
VulnerabilityExists=1
fi
}
# 4. Check Root Directory Mount
CheckRootDirectoryMount(){
find / -name passwd 2>/dev/null | grep /etc/passwd | wc -l | grep -q 7 && IsRootDirectoryMount=1 || IsRootDirectoryMount=0
if [ $IsRootDirectoryMount -eq 1 ];then
echo -e "\033[92m[+] The current container has root directory mounted.\033[0m"
VulnerabilityExists=1
fi
}
# 5. Check Docker Remote API
CheckDockerRemoteAPI(){
InstallCommand hostname
for PORT in "2375" "2376"
do
IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && timeout 3 bash -c "echo -e >/dev/tcp/$IP/$PORT" > /dev/null 2>&1 && DockerRemoteAPIIsEnabled=1 || DockerRemoteAPIIsEnabled=0
if [ $DockerRemoteAPIIsEnabled -eq 1 ];then
echo -e "\033[92m[+] The Docker Remote API for the current container is enabled.\033[0m"
VulnerabilityExists=1
fi
done
}
LinuxKernelVersion=`uname -r | awk -F '-' '{print $1}'`
KernelVersion=`echo -e $LinuxKernelVersion | awk -F '.' '{print $1}'`
MajorRevision=`echo -e $LinuxKernelVersion | awk -F '.' '{print $2}'`
MinorRevision=`echo -e $LinuxKernelVersion | awk -F '.' '{print $3}'`
# 6. Check CVE-2016-5195 DirtyCow
# 2.6.22 <= ver <= 4.8.3
CheckCVE_2016_5195DirtyCow(){
# 2.6.22 <= ver <= 2.6.xx
if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -eq 6 && "$MinorRevision" -ge 22 ]];then
echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 2.7 <= ver <= 2.x
if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -ge 7 ]];then
echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
VulnerabilityExists=1
fi
# ver = 3
if [[ "$KernelVersion" -eq 3 ]];then
echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 4.x <= ver <= 4.8
if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -lt 8 ]];then
echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 4.8.x <= ver <= 4.8.3
if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -eq 8 && "$MinorRevision" -le 3 ]];then
echo -e "\033[92m[+] The current container has the CVE-2016-5195 DirtyCow vulnerability.\033[0m"
VulnerabilityExists=1
fi
}
# 7. CVE-2020-14386
# 4.6 <= ver < 5.9
CheckCVE_2020_14386(){
# 4.6 <= ver < 4.x
if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -ge 6 ]];then
echo -e "\033[92m[+] The current container has the CVE-2020-14386 vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.x <= ver < 5.9
if [[ $KernelVersion -eq 5 && $MajorRevision -lt 9 ]];then
echo -e "\033[92m[+] The current container has the CVE-2020-14386 vulnerability.\033[0m"
VulnerabilityExists=1
fi
}
# 8. CVE-2022-0847 DirtyPipe
# 5.8 <= ver < 5.10.102 < ver < 5.15.25 < ver < 5.16.11
CheckCVE_2022_0847(){
if [ $KernelVersion -eq 5 ];then
# 5.8 <= ver < 5.10.x
if [[ "$MajorRevision" -ge 8 && "$MajorRevision" -lt 10 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.10.x <= ver < 5.10.102
if [[ "$MajorRevision" -eq 10 && "$MinorRevision" -lt 102 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.10.102 < ver <= 5.10.x
if [[ "$MajorRevision" -eq 10 && "$MinorRevision" -gt 102 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.10.x < ver < 5.15.x
if [[ "$MajorRevision" -gt 10 && "$MajorRevision" -lt 15 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.15.x <= ver < 5.15.25
if [[ "$MajorRevision" -eq 15 && "$MinorRevision" -lt 25 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.15.25 < ver <= 5.15.x
if [[ "$MajorRevision" -eq 15 && "$MinorRevision" -gt 25 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.16.x <= ver < 5.16.11
if [[ "$MajorRevision" -eq 16 && "$MinorRevision" -lt 11 ]];then
echo -e "\033[92m[+] The current container has the CVE-2022-0847 DirtyPipe vulnerability.\033[0m"
VulnerabilityExists=1
fi
fi
}
# 9. CVE-2017-1000112
# 4.4 <= ver<=4.13
CheckCVE_2017_1000112(){
# 4.4 <= ver <= 4.13
if [[ "$KernelVersion" -eq 4 && "$MajorRevision" -ge 4 && "$MajorRevision" -le 13 ]];then
echo -e "\033[92m[+] The current container has the CVE-2017-1000112 vulnerability.\033[0m"
VulnerabilityExists=1
fi
}
# 10. CVE-2021-22555
# 2.6.19 <= ver <= 5.12
CheckCVE_2021_22555(){
# 2.6.19 <= ver <= 2.6.xx
if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -eq 6 && "$MinorRevision" -ge 19 ]];then
echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 2.7 <= ver <= 2.x
if [[ "$KernelVersion" -eq 2 && "$MajorRevision" -ge 7 ]];then
echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
VulnerabilityExists=1
fi
# ver = 3 or ver = 4
if [[ "$KernelVersion" -eq 3 || "$KernelVersion" -eq 4 ]];then
echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
VulnerabilityExists=1
fi
# 5.x <= ver <= 5.12
if [[ $KernelVersion -eq 5 && $MajorRevision -le 12 ]];then
echo -e "\033[92m[+] The current container has the CVE-2021-22555 vulnerability.\033[0m"
VulnerabilityExists=1
fi
}
# 11. Mount Host Var Log
CheckVarLogMount(){
if [ ! -f "/var/run/secrets/kubernetes.io/serviceaccount/token" ];then
IsPodEnv=0
else
IsPodEnv=1
fi
if [ $IsPodEnv -eq 1 ];then
find / -name lastlog 2>/dev/null | wc -l | grep -q 3 && IsVarLogMount=1 || IsVarLogMount=0
if [ $IsVarLogMount -eq 1 ];then
echo -e "\033[92m[+] The current container has /var/log mounted.\033[0m"
VulnerabilityExists=1
fi
fi
}
# 12. Check CAP_DAC_READ_SEARCH
ChekckCAP_DAC_READ_SEARCH(){
if command -v capsh >/dev/null 2>&1; then
cap_dac_read_searchNum=`capsh --print | grep cap_dac_read_search | wc -l`
if [ $cap_dac_read_searchNum -gt 0 ];then
echo -e "\033[92m[+] The current container has the CAP_DAC_READ_SEARCH permission.\033[0m"
VulnerabilityExists=1
fi
fi
}
# 13. Check CAP_SYS_ADMIN
CheckCAP_SYS_ADMIN(){
if command -v capsh >/dev/null 2>&1; then
cap_sys_adminNum=`capsh --print | grep cap_sys_admin | wc -l`
if [ $cap_sys_adminNum -gt 0 ];then
echo -e "\033[92m[+] The current container has the CAP_SYS_ADMIN permission.\033[0m"
VulnerabilityExists=1
fi
fi
}
# 14. Check CAP_SYS_PTRACE
CheckCAP_SYS_PTRACE(){
if command -v capsh >/dev/null 2>&1; then
cap_sys_ptraceNum=`capsh --print | grep cap_sys_ptrace | wc -l`
if [ $cap_sys_ptraceNum -gt 0 ];then
echo -e "\033[92m[+] The current container has the CAP_SYS_PTRACE permission.\033[0m"
VulnerabilityExists=1
fi
fi
}
# 15. Check CVE-2022-0492, Code By https://github.com/PaloAltoNetworks/can-ctr-escape-cve-2022-0492/blob/main/can-ctr-escape-cve-2022-0492.sh
CheckCVE_2022_0492(){
# Setup test dir
test_dir=/tmp/.cve-2022-0492-test
if mkdir -p $test_dir ; then
# Test whether escape via user namespaces is possible
while read -r subsys
do
if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $subsys cgroup $test_dir 2>&1 >/dev/null && test -w $test_dir/release_agent" >/dev/null 2>&1 ; then
echo -e "\033[92m[+] The current container has the CVE-2022-0492 vulnerability.\033[0m"
fi
done <<< $(cat /proc/$$/cgroup | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$')
umount $test_dir >/dev/null 2>&1 && rm -rf $test_dir >/dev/null 2>&1
fi
}
main()
{
# 0. Check the current environment
CheckTheCurrentEnvironment
# 1. Check Privileged Mode
CheckPrivilegedMode
# 2. Check Docker Socket Mount
CheckDockerSocketMount
# 3. Check Procfs Mount
CheckProcfsMount
# 4. Check Root Directory Mount
CheckRootDirectoryMount
# 5. Check Docker Remote API
CheckDockerRemoteAPI
# 6. Check CVE-2016-5195 DirtyCow
CheckCVE_2016_5195DirtyCow
# 7. CVE-2020-14386
CheckCVE_2020_14386
# 8. CVE-2022-0847 DirtyPipe
CheckCVE_2022_0847
# 9. CVE-2017-1000112
CheckCVE_2017_1000112
# 10. CVE-2021-22555
CheckCVE_2021_22555
# 11. Mount Host Var Log
CheckVarLogMount
InstallCommand capsh
# 12. Check CAP_DAC_READ_SEARCH
ChekckCAP_DAC_READ_SEARCH
# 13. Check CAP_SYS_ADMIN
CheckCAP_SYS_ADMIN
# 14. Check CAP_SYS_PTRACE
CheckCAP_SYS_PTRACE
# 15. Check CVE-2022-0492
CheckCVE_2022_0492
if [ $VulnerabilityExists -eq 0 ];then
echo -e "\033[33m[!] Check completed, no vulnerability found. \033[0m"
else
echo -e "\033[33m[!] Check completed.\033[0m"
fi
}
main