CSAW 2014 Writeup: pybabbies
At the recent CSAW14 I participated with the krebs team. Sadly, I had only little time for the CTF, but I managed to complete one task nonetheless. It was called pybabbies, belonged to the category Exploitation and yielded 200 points (on a scale from 100 to 500).
The Task
We were to connect to 54.165.210.171 12345
where we were greeted by a Python shell. Thankfully the code for this shell was included in the task:
As you can see, this is a Python2 script. What it does is essentially the following:
- It removes all builtin functions and variables except for
raw_input
andprint
. This means we can't use any implicitly or explicitly used builtins such aslen
(which is commonly implicitly used in existental statements). - It starts a REPL loop.
- It executes every (one-line) command we enter … except if it contains a banned word. Such as …
import
. Orsys
. Oros
. Oreval
orexec
orinput
. Basically everything we would want to escape the sandbox and find the keyfile.
The Solution
Now, what we really want to do, is getting access to a file without importing any module, sending executable input or using builtin functions. This means we need access to the file
type, which we can use to access and open files. Sooo, how do we access a file without any of this?
>>> subclasses = ().__class__.__base__.__subclasses__()
This might look like a bit of magic, but it's really not that bad. Basically it takes a normal (albeit empty) tuple, ()
, then gets its class, which is <type 'tuple'>
. __base__
gets the base class of tuple
which is object
. __subclasses__()
is closest to magic. It returns a list of weak references of the immediate subclasses of a class. Thankfully, in Python many classes subclass object
directly. If this hadn't succeeded, we'd just gone on level further down the __subclasses__()
output.
But we were lucky: at subclasses[40]
there was <type 'file'>
. The remainder was just finding the keyfile.
>>> file_type = subclasses[40] >>> key_file = file_type('./key','r') >>> key = key_file.read() >>> print(key) flag{definitely_not_intro_python}