Are you sick and tired of law enforcement busting down your door, stealing your hard drives, and then finding all your pirated movies? Well, fret no more, because with MemoryFS, once those goons unplug your computer, your files are wiped!
Attachments: main.py
I actually came up with the idea for this challenge while messing around in Bash trying to make a different challenge. It's a bit of a not well-known behavior, which is that if you enter a directory through a symlink and then the symlink gets deleted, Bash will try to resolve your path to the real path. In fact, the reference solution can be performed in Bash with the exact same results (replace ln with ln -s for symlink, rm <dir> with rmdir <dir>, and create_flag with echo idek{flag} > /flag.txt).
We are provided with a command to write the flag file, create_flag, as well as various other common shell commands like ls, cat, etc. The difficulty lies in how we can get to cat flag.txt. The cat command disallows flag.txt, so we can't execute it directly. Unlike in a normal shell, we also cannot cat a symlink to flag.txt as symlinks are only resolved for directory navigation.
Instead, we can try getting flag.txt through one of the special variables. $_ doesn't work because it only stores a command if the command is valid (and flag.txt is not a valid command). $0 doesn't work for the same reason. The numerical ones obviously don't work. This leaves us with $PWD, which we might be able to use if we can get our path to /flag.txt. However, we cannot cd flag.txt as that is also banned.
To achieve this, we can use the feature discussed in the Commentary section. If I have directories /flag.txt/b and a symlink /a --> /flag.txt, then I can cd /a/b to get to /a/b (real path /flag.txt/b). Then, if I delete the symlink and cd .., the shell will resolve my path to /flag.txt without us having to ever cd flag.txt. Competitors were expected to find this because the code responsible for this feature was a little sus, compared to the relative normal-ness of the other code.
The last piece of the puzzle is how to run the create_flag command, since /flag.txt exists already. We can simply just remove the directory, because the shell lets us remove the directory we are currently in.
user@memoryFS:/$ mkdir flag.txt
user@memoryFS:/$ mkdir flag.txt/b
user@memoryFS:/$ ln flag.txt a
user@memoryFS:/$ cd a/b
user@memoryFS:/a/b$ rm /a
user@memoryFS:/a/b$ cd ..
user@memoryFS:/flag.txt$ rm /flag.txt/b
user@memoryFS:/flag.txt$ rm /flag.txt
user@memoryFS:/flag.txt$ create_flag
user@memoryFS:/flag.txt$ cat $PWD
idek{fake_flag}
Bonus (running these commands with Bash):
/# mkdir flag.txt
/# mkdir flag.txt/b
/# ln -s flag.txt a
/# cd a/b
/a/b# rm /a
/a/b# cd ..
/flag.txt# rmdir /flag.txt/b
/flag.txt# rmdir /flag.txt
/flag.txt# echo 'idek{flag}' > /flag.txt
/flag.txt# cat $PWD
idek{flag}