They found a vulnerability in Python that allows commands to be run from sandboxed scripts

Few days ago disclosed a method to bypass Python's isolated code execution systems, based on the use of a long-known bug that appeared in Python 2.7, identified in 2012, and not yet fixed in Python 3.

It is mentioned that the bug allows to use specially bound python code to initiate a call to memory already freed (Use-After-Free) in Python. Initially, it was assumed that the error does not represent a security threat and only in very rare cases, usually artificially created, can it lead to an abnormal termination of the script.

A security researcher under the pseudonym kn32 became interested in the problem and managed to prepare a working exploit that makes it possible to call any system command without direct access to methods like os.system.

The exploit is implemented in pure Python and works without importing external libraries and without installing the "code.__new__" driver. Of the hooks, only "builtin.__id__" is used, which is generally not prohibited. On the practical side, the proposed code can be used to bypass isolation mechanisms in various services and environments (for example, in learning environments, online shells, built-in controllers, etc.) that allow execution of Python code, but limit the available calls and disallow access methods such as os.system.

The proposed code is an analogue of the os.system call, which works by exploiting a vulnerability in CPython. The exploit works with all versions of Python 3 on x86-64 systems and is stable on Ubuntu 22.04 even with PIE, RELRO and CET security modes enabled.

Work boils down to getting information about the address of one of the functions from the Python code in the CPython executable code.

Based on this address, the base address of CPython in memory and the address of the system() function in the loaded libc instance are calculated. At the end, a direct transition to a given address system is started by replacing the pointer of the first argument with the string "/bin/sh".

The easiest approach to exploitation is to create a list with a length equal to the length of the freed buffer, which will most likely have its item buffer (ob_item) allocated in the same place as the freed buffer.

This will mean that we will get two different "views" on the same piece of memory. One view, the memoryview, thinks that memory is just an array of bytes, which we can write to or read from arbitrarily. The second view is the list we created, which thinks memory is a list of PyObject pointers. This means that we can create fake PyObject emails somewhere in memory, write their addresses to the list by writing to the memoryview, and then access them by indexing the list.

In the case of the PoC, they write 0 to the buffer (line 16) and then access it with print(L[0]). L[0] gets the first PyObject* which is 0, and then print tries to access some fields in it, resulting in a null pointer dereference.

It is mentioned that this bug is present in all python versions since at least python 2.7 and although the exploit was designed to work on almost any version of Python 3, this does not mean that it is not reproducible in Python 2 (according to the author).

The purpose of the exploit is to call system("/bin/sh") whose steps are as follows:

  • CPython leak binary function pointer
  • Calculate CPython base address
  • Calculate the address of system or your PLT stub
  • Jump to this address with the first argument pointing to /bin/sh
  • Win

Lastly, it is mentioned that the exploit will not be useful in most configurations. However, it can be useful for Python interpreters trying to isolate code, restricting imports or the use of Audit Hooks.

Finally if you are interested in knowing more about it about the note, you can consult the original publication in the following link


Leave a Comment

Your email address will not be published. Required fields are marked with *

*

*

  1. Responsible for the data: AB Internet Networks 2008 SL
  2. Purpose of the data: Control SPAM, comment management.
  3. Legitimation: Your consent
  4. Communication of the data: The data will not be communicated to third parties except by legal obligation.
  5. Data storage: Database hosted by Occentus Networks (EU)
  6. Rights: At any time you can limit, recover and delete your information.