All Projects → DavidBuchanan314 → unsafe-python

DavidBuchanan314 / unsafe-python

Licence: MIT License
A library to assist writing memory-unsafe code in "pure" python, without any imports (i.e. no ctypes etc.)

Programming Languages

python
139335 projects - #7 most used programming language

unsafe-python

A library to assist writing memory-unsafe code in "pure" python, without any imports (i.e. no ctypes etc.)

Note: This is a toy. You probably shouldn't use it for anything serious (or anything at all, really).

Core features:

  • addrof(obj) - A trivial alias of the id() builtin.
  • fakeobj(addr) - Allows for crafting fake heap objects.
  • getmem() - Returns a bytearray view of the current process's virtual memory.
  • setrip(addr) - Sets the RIP register. Argument passing etc. coming soon™.
  • do_rop(payload) - Execute a ROP payload.

A trivial example, showing how to dereference a null pointer in pure python. The future is now!

>>> import unsafe  # (If "no imports" is a requirement, then you can just copy-paste the code)
>>> mem = unsafe.getmem()
>>> mem[0]
Segmentation fault (core dumped)

For a less trivial example, check out shellcode_example_nocheats.py, which uses ROP to mprotect a shellcode buffer, and then jump into it.

Why?

I don't know.

How?

The CPython bytecode interpreter has documented memory-unsafety bug/features. Notably, the LOAD_CONST opcode (used to load a constant from the co_consts tuple) does not have any bounds checks, presumably for performance reasons. This has been used in the past to execute arbitrary code and escape sandboxes. Until now, these exploits have relied on custom bytecode generation, which is inherently fragile because the bytecode specification changes between different versions and/or implementations of python.

This project uses CPython's code object introspection APIs, along with a heap grooming technique, in order to craft "vulnerable" code objects using CPython's own bytecode compiler. This technique allows us to craft fake python objects on the heap, similar to the "fakeobj()" primitive you might see in exploits for JavaScript engines. For example, we can craft a bytearray with a base addresss of 0 and a length of SSIZE_MAX, giving us read and write access to raw memory.

TODO:

  • Perform ROP gadget search without "cheating" by reading /proc/self/maps. i.e. find a reliable way to leak libc base.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].