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:
emojis = json.load(emoji_file)
for emoji in re.findall("(:[a-z_]*?:)", instance.body):
instance.body = instance.body.replace(emoji, "{{" + emojis[emoji.replace(":", "")] + ".png}}")
```
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.