#!/usr/bin/env python3
import urllib.request
import json
import base64
import struct
import sys
BASE = sys.argv[1] if len(sys.argv) > 1 else "http://tasks.duckerz.ru:30030"
def post(path, payload):
req = urllib.request.Request(BASE + path, data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"}, method="POST")
with urllib.request.urlopen(req, timeout=15) as resp:
return json.loads(resp.read().decode())
def get(path):
with urllib.request.urlopen(BASE + path, timeout=15) as resp:
return json.loads(resp.read().decode())
def aes_ecb_victim(block16):
r = post("/aes_ecb_tenant", {
"who": "victim",
"block_b64": base64.b64encode(block16).decode()
})
return base64.b64decode(r["cipher_b64"])
def main():
# 1. FLAG_BLOB
r = get("/flag")
flag_blob = base64.b64decode(r["flag_blob"])
FLAG_IV = flag_blob[:12]
FLAG_CT = flag_blob[12:-16]
FLAG_TAG = flag_blob[-16:]
print(f"[+] FLAG_IV = {FLAG_IV.hex()}")
print(f"[+] FLAG_CT = {FLAG_CT.hex()} ({len(FLAG_CT)} bytes)")
# 2. Строим keystream для KEY_VICTIM с j0 = FLAG_IV || 00000001
# CTR: начиная с j0 + 1 = FLAG_IV || 00000002
# ks[0..15] = AES_ECB(VICTIM, FLAG_IV || 00000002)
# ks[16..31] = AES_ECB(VICTIM, FLAG_IV || 00000003)
# ks[32..] = AES_ECB(VICTIM, FLAG_IV || 00000004)[:...]
ks = bytearray()
counter = 2 # j0+1 = 00000002
while len(ks) < len(FLAG_CT):
block = FLAG_IV + counter.to_bytes(4, "big")
ks_block = aes_ecb_victim(block)
ks.extend(ks_block)
counter += 1
print(f" keystream block {counter-2}: {ks_block.hex()}")
ks = bytes(ks[:len(FLAG_CT)])
print(f"[+] ks = {ks.hex()}")
# 3. Расшифровываем
FLAG_PT = bytes(a ^ b for a, b in zip(FLAG_CT, ks))
print(f"[+] FLAG_PT = {FLAG_PT.hex()}")
try:
flag = FLAG_PT.decode()
print(f"\n[***] FLAG: {flag}")
return flag
except Exception as e:
print(f"[-] Не удалось декодировать: {e}")
return None
if __name__ == "__main__":
main()