Tags: web

Rating:

[Link to original writeup](https://github.com/babaiserror/ctf/tree/main/%5B210813-16%5D%20ReallyAwesomeCTF%202021#emojibook-web-350-pts)

This was intended to be a django lfi challenge, but due to a mistake in the setting of the dockerfile, it became a challenge of exploiting the filter.

After registering and logging into the website, you can create notes, which has a title and a body.

From the source file given, in notes/views.py, there is this snippet:

py
def view_note(request: HttpRequest, pk: int) -> HttpResponse:
note = get_object_or_404(Note, pk=pk)
text = note.body
for include in re.findall("({{.*?}})", text):
print(include)
file_name = os.path.join("emoji", re.sub("[{}]", "", include))
with open(file_name, "rb") as file:
text = text.replace(include, f"")

return render(request, "note.html", {"note": note, "text": text})


This looks for notes with body that has something in the form of "{{" + "<some string> + "}}", then removes all the brackets, then uses that to construct a filename with os.path.join, in the form of "emoji" + "your path". It opens and reads this file, encodes the data with base64, and puts it in an image tag.

Also from the source, in notes/forms.py, there is this:

py
def save(self, commit=True):
instance = super(NoteCreateForm, self).save(commit=False)
instance.author = self.user
instance.body = instance.body.replace("{{", "").replace("}}", "").replace("..", "")

with open("emoji.json") as emoji_file:

When saving the note, this removes all "{{", "}}", and ".." in the body. We know from the description that the flag is in the path /flag.txt; also, os.path.join has a property where if an argument has an absolute path, it will discard all the previous arguments.
Using all these, putting {..{/flag.txt}..} in the body gives us the flag.