BCACTF2.0 | FNES 2

#bcactf2

#!/usr/bin/env python3
import random
import math
import time
import binascii
import secrets
from Crypto.Cipher import AES 
from Crypto.Hash import SHA
from Crypto.Util.Padding import pad, unpad


with open("flag.txt", "r") as f:
    flag = f.read().strip().encode("ascii")

with open("key.txt", "r") as f:
    key = int(f.read().strip())

target_query = "Open sesame... Flag please!"

print("""
Welcome to your new and improved FNES... FNES 2!
As before, if you and a friend both run this service at the same time,
you should be able to send messages to each other!
Here are the steps:
1. Friends A and B connect to the server at the same time (you have about a five second margin)
2. Friend A encodes a message and sends it to Friend B
3. Friend B decodes the message, encodes their reply, and sends it to Friend A
4. Friend A decodes the reply, rinse and repeat
PS: For security reasons, there are still some characters you aren't allowed to encrypt. Sorry!
""", flush=True)

tempkey = SHA.new(int(key + int(time.time() / 10)).to_bytes(64, 'big')).digest()[0:16]

while True:
    print("Would you like to encrypt (E), decrypt (D), or quit (Q)?", flush=True)
    l = input(">>> ").strip().upper()
    if (len(l) > 1):
        print("You inputted more than one character...", flush=True)
    elif (l == "Q"):
        print("We hope you enjoyed!", flush=True)
        exit()
    elif (l == "E"):
        print("What would you like to encrypt?", flush=True)
        I = input(">>> ").strip()
        if (set(I.lower()) & set("flg!nsm")): # Disallowed characters changed to make the target query more difficult
            print("You're never getting my flag!", flush=True)
            exit()
        else:
            iv = secrets.token_bytes(16)
            cipher = AES.new(tempkey, AES.MODE_CBC, iv)
            c = str(binascii.hexlify(iv + cipher.encrypt(pad(str.encode(I), 16))))[2:-1]
            print("Here's your message:", flush=True)
            print(c, flush=True)
    elif (l == "D"):
        print("What was the message?", flush=True)
        I = input(">>> ").strip()
        iv = I[:32]
        I = I[32:]
        try:
            cipher = AES.new(tempkey, AES.MODE_CBC, binascii.unhexlify(iv))
            m = str(unpad(cipher.decrypt(binascii.unhexlify(I)), 16))[2:-1]
            if (m == target_query):
                print("\nPassphrase accepted. Here's your flag:\n", flush=True)
                print(str(flag)[2:-1], flush=True)
                try:
                    with open("advertisement.txt", "r") as ff:
                        print(ff.read(), flush=True)
                except:
                    pass
                exit()
            else:
                print("Here's the decoded message:", flush=True)
                print(m, flush=True)
        except ValueError:
            print("I can't read that!", flush=True)

こんなのだれが読もうと思うんだろうか。Padding Oracle Encryption Attackやるだけ

from ptrlib import Socket, padding_oracle_encrypt
from Crypto.Util.Padding import pad


sock = Socket("nc crypto.bcactf.com 49154")

def oracle(c):
    sock.sendlineafter(">>> ", "D")
    sock.sendlineafter(">>> ", c.hex())

    if b"I can't" in sock.recvline():
        return False
    return True


iv, c = padding_oracle_encrypt(oracle, pad(b"Open sesame... Flag please!", 16), bs=16, unknown=b"?") 

sock.sendlineafter(">>> ", "D")
sock.sendlineafter(">>> ", (iv + c).hex())
sock.interactive()

カテゴリ一覧