bvdelft / PyOpaque

Create opaque Python objects via encapsulation
3 stars 0 forks source link

Three ways to access the deck (Challenge) #11

Open alejolp opened 12 years ago

alejolp commented 12 years ago

1) The ctypes module can be used to access memory locations directly. While the "import ctypes" sentence fails, the "ctypes" module is a tiny wrapper around the builtin "_ctypes" module. Importing that module is successful:

>>> import ctypes
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/ctypes/__init__.py", line 6, in <module>
    import os as _os, sys as _sys
RuntimeError: Illegal import (sys)
>>> import _ctypes
>>> 

2) The sys module can be accessed from the '_abcoll' module:

>>> import _abcoll
>>> _abcoll.sys
<module 'sys' (built-in)>
>>> import sys
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Illegal import (sys)

3) The sys module can be accessed from the 'site' module:

>>> import site
>>> site.sys
<module 'sys' (built-in)>
bvdelft commented 12 years ago

Thanks for filing the issue! It seems that all ways can be prevented by adding the three modules to the blacklist of imports, but I am unsure if that causes great limitations on the programmer?

alejolp commented 12 years ago

IMHO, a private variable is more like an "expression of good will" rather than a security policy to be enforced. Even Java and C++ allow some kind of trickery and black magic to access private variables.

Yes, I agree that blocking the importing of such modules harms the initial goal of enhancing the interpreter with private variables. I do like compiler automatic warnings and errors messages.

An interesting exception is Java Sandboxing, which is quite good, but Python crew decided not to take that path long time ago. In Py3k all traces of the rexec module are totally gone. http://wiki.python.org/moin/SandboxedPython

Another option would be to create a new operating system process for each object instance, and every interaction being done via RPC. From a security point of view it would be great, but overkill in performance.

There is one more way to bypass the importing limitation, importing any module without even using "import". Python allows importing modules inside a .zip package. That specific functionality is on another class, subclass of object.

Knowing the target machine, operating system and architecture, it could be possible to write a custom C extension, put it inside a .zip file, and import it using the zipimport module.

>>> ZI = [x for x in (1).__class__.__bases__[0].__subclasses__() if 'zipimp' in str(x)][0]
>>> f = open("/tmp/challenge.zip", "wb")
>>> f.write("EVIL_ZIP_PAYLOAD".decode("base64"))
>>> f.close()
>>> zz = ZI("/tmp/challenge.zip")
>>> m = zz.load_module("my_module")
>>> sys = m.bypass_import("sys")
>>> sys
<module 'sys' (built-in)>
1ucian0 commented 12 years ago

Blocking import is not the main goal of PyOpaque. In fact, that's not the goal at all.

But clearly, this kind of sandboxing is a requirement.

alejolp commented 12 years ago

By no means I'm trying to disrespect your work, folks. This is a cool project, I'm glad you made it open source, and it was in fact fun trying to break the challenge. I'm just here for the T-Shirt (XL size should be fine).