CSA Capture The Flag 2019 | Flag Server

#CSACTF2019

https://ctftime.org/task/8470

import sys, time
from Crypto.Hash import SHA256
from Crypto.Cipher.AES import AESCipher

flag = "Flag goes here"

def encrypt(m):
    key = SHA256.new(flag).digest()
    try:
        text = 'rowdy123' + m.decode('base64') + flag
    except:
        return "Opps, bad input"
    pad = 16 - (len(text) % 16)
    text += (chr(pad) * pad)
    cipher = AESCipher(key).encrypt(text).encode("base64")

    return cipher

print "State your name (in base64): "
m = raw_input()
print "Here's the package:"
print encrypt(m)

AESの問題。

PyCryptoのAESCipherはデフォルトだとECBモードを使う。自分で好きな入力を選択できるときECBモードと来れば、Chosen Plaintext Attackがある。

これのためにptrlibにecb_chosenplaintextっていう関数を入れたけどこれだと微妙に解けない。pythonencode("base64") って微妙にちゃんと仕事しないんですよね。これをb64encodeにしたら解けていたのでうーん……。

from ptrlib.pwn.sock import Socket
from ptrlib.crypto.ecb import ecb_chosenplaintext
from logging import getLogger, WARN
from base64 import b64encode, b64decode
import string

getLogger("ptrlib.pwn").setLevel(WARN + 1)


def by_bytes(xs, n):
    for i in range(0, len(xs), n):
        yield xs[i : i + n]


def encrypt(m):
    sock = Socket("localhost", 8888)
    sock.recvuntil(": \n")
    sock.sendline(b64encode(m))
    sock.recvuntil(":\n")
    c = b64decode(sock.recvline())
    sock.close()
    return c


print(ecb_chosenplaintext(encrypt, b"rowdy123", 99))