n00bzCTF Write-up - Curl As A Service - Unintended
ShiSHcat 🐈Challenge: https://challs.n00bzunit3d.xyz:30533
We also have the redacted source code of the main file: https://ctf.n00bzunit3d.xyz/attachments/CaaS/challenge_redacted.py
The challenge description informs us that the flag is not inside flag.txt.
Going to the website and analyzing the code we can see that the webserver will fetch every URL we pass to it through urllib.request.urlopen(f'{inp}').
There seems to be a blacklist of characters for the URL, but looking carefully at the code we can notice that it's not actually in use.
Looking at the documentation of urllib, we can see that it supports, apart from http:// and https://, also file://, ftp:// and data:// protocols.
We can use file:/// to fetch files on the system. The problem is that file:/// urllib implementation provides no way to access relative files, I tried things like file://challenge.py without success, and I had no idea on where the files actually were stored on the server's filesystem. The goal was to get the contents of the non-stripped challenge.py that was running on the server, since it contains the URI location that would print the flag.

I tried using /proc/self/tools, /proc/self/ is a virtual directory where it's contents are relative to the process who accesses it, for example getting /proc/self/environ reveals environment variables of the process. I tried fetching file:///proc/self/cmdline, in hopes that it contained an absolute path, but unfortunately it printed only "python challenge.py", so the script was started from the work directory.
I tried looking into how getcwd worked, but I haven't found anything exploitable through a LFI.
I thought I was on the wrong way, so I searched a bit online and I found this writeup for a similiar CTF: https://ctftime.org/writeup/24948
Using the header injection in urllib to make requests to the Google Cloud metadata service.
I began trying to exploit it, trying to fetch http://metadata/computeMetadata/ worked, it returned v1 and beta, and I knew that this challenge was hosted on Google Cloud. However I haven't been able to get the header injection working. Maybe it was patched?
Then it struck me, there are many other tools apart from /proc/self/environ and /proc/self/cwdline inside /proc/self, maybe there is something interesting.
On my computer I ran:shishcat@pc~# ls /proc/self
arch_status limits root attr loginuid sched autogroup map_files schedstat auxv maps sessionid cgroup mem setgroups clear_refs mountinfo smaps cmdline mounts smaps_rollup comm mountstats stack coredump_filter net stat cpu_resctrl_groups ns statm cpuset numa_maps status cwd oom_adj syscall environ oom_score task exe oom_score_adj timens_offsets fd pagemap timers fdinfo patch_state timerslack_ns gid_map personality uid_map io proj
Interesting, what is cwd? I tried cd'ing into it and it returned the same files as the dir I was inside before. It seemed like a link to the chdir of the process using it.
So I tried getting file:///proc/self/cwd/challenge.py and it actually printed the contents of challenge.py! The challenge was solved. I just had to fetch /such_a_1337_flag_file_th4t_n0_one_c4n_defnitely_f1nd_hahahaha_lollll_nooob_xDDDDDDd.txt and it returned the flag.
Later in the CTF it was revealed as an hint that the flag was in /chall/templates/<flagfile>, so you just needed to get file:///chall/challenge.py

Other people people probably guessed that the file was in /chall.