diff --git a/services/sheesh/dist/chall.py b/services/sheesh/dist/chall.py index b183fe8..2f8673f 100644 --- a/services/sheesh/dist/chall.py +++ b/services/sheesh/dist/chall.py @@ -1,77 +1,80 @@ #!/usr/bin/env python3 -import os, sys, binascii, random +import os, sys, signal, binascii, random from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Util.number import bytes_to_long, long_to_bytes random.seed(os.urandom(16)) -k0 = os.urandom(16) -k1 = os.urandom(16) -s0 = os.urandom(16); S1 = os.urandom(16) -m0 = os.urandom(16); M1 = os.urandom(16) +K0 = os.urandom(16) +K1 = os.urandom(16) +S0 = os.urandom(16) +S1 = os.urandom(16) +M0 = os.urandom(16) +M1 = os.urandom(16) -with open("/flag.txt","rb") as f: +with open("./flag.txt","rb") as f: flag = f.read() def hex_input(q): s = input(q).strip() - try: return binascii.unhexlify(s) + try: return binascii.unhexlify(s) except: print("err"); return None -def xex(b16): - x = AES.new(k1, AES.MODE_ECB).encrypt(b16) - return bytes(a ^ b for a,b in zip(x, b16)) +def enc1(b16: bytes) -> bytes: + x = AES.new(K1, AES.MODE_ECB).encrypt(b16) + return bytes(a ^ b for a, b in zip(x, b16)) -def enc1(iv, msg): - return AES.new(k0, AES.MODE_CBC, iv=iv).encrypt(pad(msg,16)) +def enc2(iv: bytes, m: bytes) -> bytes: + return AES.new(K0, AES.MODE_CBC, iv=iv).encrypt(pad(m, 16)) -def dec1(iv, c): - return unpad(AES.new(k0, AES.MODE_CBC, iv=iv).decrypt(c), 16) +def enc3(m: bytes) -> bytes: + return AES.new(K1, AES.MODE_CBC, iv=b"\x00"*16).encrypt(pad(m, 16))[-16:] -def enc2(msg): - return AES.new(k1, AES.MODE_CBC, iv=b"\x00"*16).encrypt(pad(msg,16))[-16:] - -def F(iv, ct): +def T(iv: bytes, ct: bytes): n = len(ct) - if n < 96 or (n & 15): return None - W = [ct[i:i+16] for i in range(0, n, 16)] + if n < 96 or (n & 15): + return None + v = memoryview(ct) + W = [bytes(v[i:i+16]) for i in range(0, n, 16)] m = len(W) - digest = enc2(iv) - r = ((iv[0]^iv[-1]) & 7) + 2 - r %= m - if r: W = W[r:] + W[:r] + r = ((iv[0] & 7) + 2) % m + if r: + W = W[r:] + W[:r] - if len(W) < 3: return None - A0 = long_to_bytes(bytes_to_long(W[0]) ^ bytes_to_long(m0)) - A1 = long_to_bytes(bytes_to_long(W[1]) ^ bytes_to_long(M1)) - j = 1 + (digest[0] & 1) - del W[j] - if len(W) < 2: return None + j = 1 + (W[0][0] & 1) + if len(W) <= j: + return None + del W[j] + if len(W) < 2: + return None - return b"".join((s0, A0, S1, A1, *W[2:])) + a0 = long_to_bytes(bytes_to_long(W[0]) ^ bytes_to_long(M0)) + a1 = long_to_bytes(bytes_to_long(W[1]) ^ bytes_to_long(M1)) + return b"".join((S0, a0, S1, a1, *W[2:])) -def O(iv, ct): - z = F(iv, ct) +def C(iv: bytes, ct: bytes) -> bool: + z = T(iv, ct) if z is None: ok = False else: try: - dec1(iv, z) + x = AES.new(K0, AES.MODE_CBC, iv=iv).decrypt(z) + unpad(x, 16) ok = True except: ok = False - if random.random() < 0.10: + if random.random() < 0.08: ok = not ok return ok iv = os.urandom(16) -MK = enc2(iv + iv) -h0 = (flag + b"\x00"*16)[:16] -h1 = bytes(a ^ b for a,b in zip(h0, MK)) -pt = h1 + flag[16:] -ct = enc1(iv, pt) +MK = enc3(iv + iv) +H0 = (flag + b"\x00"*16)[:16] +H1 = bytes(a ^ b for a, b in zip(H0, MK)) +pt = H1 + flag[16:] +ct = enc2(iv, pt) print("iv:", iv.hex()) print("ct:", ct.hex()) @@ -79,21 +82,17 @@ print() while True: try: - inp = hex_input("inp: ") - if inp is None: - print("hmmm\n"); continue - L = len(inp) - - if L == 16: - y = xex(inp) + blob = hex_input("blob: ") + if blob is None: + print("err\n"); continue + L = len(blob) + if L == 16: + y = enc1(blob) print("blk:", y.hex()); print() - elif L >= 32 and (L % 16) == 0: - ivq, ctq = inp[:16], inp[16:] - print("ok\n" if O(ivq, ctq) else "zzz\n") - + iv, ct = blob[:16], blob[16:] + print("ok\n" if C(iv, ct) else "no\n") else: - print("hmmm\n") - + print("err\n") except EOFError: - break + break \ No newline at end of file diff --git a/services/sheesh/src/chall.py b/services/sheesh/src/chall.py index a69ed3e..6f18cfe 100644 --- a/services/sheesh/src/chall.py +++ b/services/sheesh/src/chall.py @@ -1,77 +1,80 @@ #!/usr/bin/env python3 -import os, sys, binascii, random +import os, sys, signal, binascii, random from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Util.number import bytes_to_long, long_to_bytes random.seed(os.urandom(16)) -k0 = os.urandom(16) -k1 = os.urandom(16) -s0 = os.urandom(16); S1 = os.urandom(16) -m0 = os.urandom(16); M1 = os.urandom(16) +K0 = os.urandom(16) +K1 = os.urandom(16) +S0 = os.urandom(16) +S1 = os.urandom(16) +M0 = os.urandom(16) +M1 = os.urandom(16) -with open("/flag.txt","rb") as f: +with open("./flag.txt","rb") as f: flag = f.read() def hex_input(q): s = input(q).strip() - try: return binascii.unhexlify(s) + try: return binascii.unhexlify(s) except: print("err"); return None -def xex(b16): - x = AES.new(k1, AES.MODE_ECB).encrypt(b16) - return bytes(a ^ b for a,b in zip(x, b16)) +def enc1(b16: bytes) -> bytes: + x = AES.new(K1, AES.MODE_ECB).encrypt(b16) + return bytes(a ^ b for a, b in zip(x, b16)) -def enc1(iv, msg): - return AES.new(k0, AES.MODE_CBC, iv=iv).encrypt(pad(msg,16)) +def enc2(iv: bytes, m: bytes) -> bytes: + return AES.new(K0, AES.MODE_CBC, iv=iv).encrypt(pad(m, 16)) -def dec1(iv, c): - return unpad(AES.new(k0, AES.MODE_CBC, iv=iv).decrypt(c), 16) +def enc3(m: bytes) -> bytes: + return AES.new(K1, AES.MODE_CBC, iv=b"\x00"*16).encrypt(pad(m, 16))[-16:] -def enc2(msg): - return AES.new(k1, AES.MODE_CBC, iv=b"\x00"*16).encrypt(pad(msg,16))[-16:] - -def F(iv, ct): +def T(iv: bytes, ct: bytes): n = len(ct) - if n < 96 or (n & 15): return None - W = [ct[i:i+16] for i in range(0, n, 16)] + if n < 96 or (n & 15): + return None + v = memoryview(ct) + W = [bytes(v[i:i+16]) for i in range(0, n, 16)] m = len(W) - digest = enc2(iv) - r = ((iv[0]^iv[-1]) & 7) + 2 - r %= m - if r: W = W[r:] + W[:r] + r = ((iv[0] & 7) + 2) % m + if r: + W = W[r:] + W[:r] - if len(W) < 3: return None - A0 = long_to_bytes(bytes_to_long(W[0]) ^ bytes_to_long(m0)) - A1 = long_to_bytes(bytes_to_long(W[1]) ^ bytes_to_long(M1)) - j = 1 + (digest[0] & 1) - del W[j] - if len(W) < 2: return None + j = 1 + (W[0][0] & 1) + if len(W) <= j: + return None + del W[j] + if len(W) < 2: + return None - return b"".join((s0, A0, S1, A1, *W[2:])) + a0 = long_to_bytes(bytes_to_long(W[0]) ^ bytes_to_long(M0)) + a1 = long_to_bytes(bytes_to_long(W[1]) ^ bytes_to_long(M1)) + return b"".join((S0, a0, S1, a1, *W[2:])) -def O(iv, ct): - z = F(iv, ct) +def C(iv: bytes, ct: bytes) -> bool: + z = T(iv, ct) if z is None: ok = False else: try: - dec1(iv, z) + x = AES.new(K0, AES.MODE_CBC, iv=iv).decrypt(z) + unpad(x, 16) ok = True except: ok = False - if random.random() < 0.10: + if random.random() < 0.08: ok = not ok return ok iv = os.urandom(16) -MK = enc2(iv + iv) -h0 = (flag + b"\x00"*16)[:16] -h1 = bytes(a ^ b for a,b in zip(h0, MK)) -pt = h1 + flag[16:] -ct = enc1(iv, pt) +MK = enc3(iv + iv) +H0 = (flag + b"\x00"*16)[:16] +H1 = bytes(a ^ b for a, b in zip(H0, MK)) +pt = H1 + flag[16:] +ct = enc2(iv, pt) print("iv:", iv.hex()) print("ct:", ct.hex()) @@ -79,21 +82,17 @@ print() while True: try: - inp = hex_input("inp: ") - if inp is None: - print("hmmm\n"); continue - L = len(inp) - - if L == 16: - y = xex(inp) + blob = hex_input("blob: ") + if blob is None: + print("err\n"); continue + L = len(blob) + if L == 16: + y = enc1(blob) print("blk:", y.hex()); print() - elif L >= 32 and (L % 16) == 0: - ivq, ctq = inp[:16], inp[16:] - print("ok\n" if O(ivq, ctq) else "zzz\n") - + iv, ct = blob[:16], blob[16:] + print("ok\n" if C(iv, ct) else "no\n") else: - print("hmmm\n") - + print("err\n") except EOFError: - break + break \ No newline at end of file