Skip to content

Instantly share code, notes, and snippets.

@jdabtieu
Last active October 14, 2024 18:16
Show Gist options
  • Select an option

  • Save jdabtieu/e169fd499d60c7e610e35ca862d81d02 to your computer and use it in GitHub Desktop.

Select an option

Save jdabtieu/e169fd499d60c7e610e35ca862d81d02 to your computer and use it in GitHub Desktop.
idekCTF 2024 misc/memoryfs

MemoryFS

Description

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

Commentary

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).

Solution

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}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment