Tags: misc jail pyjail 

Rating: 5.0

On connecting to the server it prompts and waits for input:

```
The flag is stored super secure in the function ALLES !
>>> a =
```

So at first my aim was to call `ALLES`, but :

```
>>> a = ALLES()
name 'alles' is not defined
```

> **Takeaway 1** : It converts our input to lowercase and then evaluates it and store back it into `a`.

So I tried :

```
>>> a = eval('alles'.upper()+'()')
u
Denied
```

> **Takeaway 2** : Some characters were blacklisted.

After some fuzzing I found the blacklisted and whitelisted characters :

```
blacklisted = ['!', '#', '$', '%', '&', '*', ',', '-', '/',
'4', '5', '6', '8',
':', ';', '<', '=', '>', '?', '@', '\\', '^', '`',
'b', 'f', 'h', 'j', 'k', 'm', 'q', 'u', 'w', 'x', 'y', 'z',
'{', '|', '}', '~']

whitelisted = ['"', "'", '(', ')', '+', '.',
'0', '1', '2', '3', '7', '9',
'[', ']', '_',
'a', 'c', 'd', 'e', 'g', 'i', 'l', 'n', 'o', 'p', 'r', 's', 't', 'v']
```

From those list I figured out few useful things:
1. Functions we can still use like : `str, print, eval etc.`
2. Common attributes we can use : `__class__, __str__ etc.`
3. Any number usning `+`.

Now I tried to find some inbuilt strings in the python itself to reuse them and I stumbled upon something very interesting:
```
>>> a = str(print.__class__)
>>> a = print(a)
<class 'builtin_function_or_method'>
```

It's a string and using indexing we can bypass blacklisted characters, similary I found bypass for few more characters:
```
bypass = {
'b' : 'str(print.__class__)[7+1]',
'f' : 'str(print.__class__)[9+7]',
'h' : 'str(print.__class__)[31]',
'm' : 'str(print.__class__)[27+1]',
'u' : 'str(print.__class__)[9]',
}
```

So for executing `print(ALLES())` bypass would be like: `print(eval(eval('"alles()".'+str(print.__class__)[9]+'ppe'+'r()')))` , but :
```
>>> a = print(eval(eval('"alles()".'+str(print.__class__)[9]+'ppe'+'r()')))
No flag for you!
```

So after some more playing with input I found something, which was equivalent of executing `print(ALLES.__code__.co_consts)`:
```
>>> a = print(eval(eval('"alles.__".'+str(print.__class__)[9]+'ppe'+'r()')+'code__.co_consts'))
(None, 'p\x7f\x7frbH\x00DR\x07CRUlJ\x07DlRe\x02N', 'No flag for you!')
```

The gibberish looking string was interresting, so I tried to make sense out of it:
```
>>> gib = b'p\x7f\x7frbH\x00DR\x07CRUlJ\x07DlRe\x02N'
>>> chr(gib[0]^ord('A'))
'1'
>>> chr(gib[1]^ord('L'))
'3'
>>> chr(gib[2]^ord('L'))
'3'
>>> chr(gib[3]^ord('E'))
'7'
>>> chr(gib[4]^ord('S'))
'1'
>>> chr(gib[5]^ord('{'))
'3'
```

It turned out that the string was indeed the `flag` xored with key `1337`, and with little python code we can get the flag :
```
enc_flag = b'p\x7f\x7frbH\x00DR\x07CRUlJ\x07DlRe\x02N'
key = b'1337'
flag = ''
for i in range(len(enc_flag)):
flag+=chr(enc_flag[i]^key[i%len(key)])
print(flag)
```

`FLAG : ALLES{3sc4ped_y0u_aR3}`