Box
2 minutos de lectura
Se nos proporciona el siguiente código en Python que cifra la flag:
from Crypto.Util.number import bytes_to_long
flag = open("flag.txt", "rb").read().strip()
TABLE = [
lambda a, b: f"({a}+{b})",
lambda a, b: f"({a}-{b})",
lambda a, b: f"({a}*{b})",
]
def build_box(s: bytes):
e = "(x)"
for b in s:
e = TABLE[b % len(TABLE)](e, b)
return eval(f"lambda x: {e}")
box = build_box(flag)
ct = box(bytes_to_long(flag))
print(ct)
print(box(1337))
print(box(0x1337))
"""
Output:
5545457088879574964209613711409478327714366805681091501255101702161458272094830554232779120250
3011454617406654839679120250
10002638090931457241529120250
"""
Se trata de una forma extraña de cifrar un mensaje. Básicamente, box
es un conjunto de operaciones que contiene una sola x
, y al llamar a box
con un valor dado, se sustituye dicho valor en la x
para obtener el resultado final.
Podemos ver cómo funciona box
:
$ python3 -q
>>>
>>> TABLE = [
... lambda a, b: f"({a}+{b})",
... lambda a, b: f"({a}-{b})",
... lambda a, b: f"({a}*{b})",
... ]
>>>
>>>
>>> def build_box(s: bytes):
... e = "(x)"
... for b in s:
... e = TABLE[b % len(TABLE)](e, b)
... return f"lambda x: {e}"
...
>>> box = build_box(b'ictf{fake_flag}')
>>> box
'lambda x: ((((((((((((((((x)+105)+99)*116)+102)+123)+102)-97)*107)*101)*95)+102)+108)-97)-103)*125)'
Como todas las operaciones son sumas y multiplicaciones, podemos expresar box
como una función lineal
Nos dan
Por tanto,
Una vez que tenemos
Ahora vamos a realizar las operaciones con Python:
>>> c = 5545457088879574964209613711409478327714366805681091501255101702161458272094830554232779120250
>>> c1 = 3011454617406654839679120250
>>> c2 = 10002638090931457241529120250
>>> m = (c2 - c1) // (0x1337 - 1337)
>>> n = c1 - 1337 * m
>>> x = (c - n) // m
>>> hex(x)
'0x696374667b776f775f737563685f6c696e6561725f736f5f656173797d'
>>> bytes.fromhex(hex(x)[2:])
b'ictf{wow_such_linear_so_easy}'