사실 서버가 닫힌지 오래기 때문에 https://xerxes-break.tistory.com/371?category=679888 이 사이트에서 직접 파이썬으로 구현하셔서 그 스크립트대로 문제를 풀어보겠다.

#!/usr/bin/env python
from Crypto.Cipher import AES
import hashlib
import sys

flag = open("flag", "r").read().strip()

AES_KEY = hashlib.sha256(flag).hexdigest().decode("hex")[:16]
BLOCK_SIZE  = 16

pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)

def GetCookie(input):
    cipher = AES.new(AES_KEY, AES.MODE_ECB)
    input = pad(input + flag)
    print("Your Cookie is: " + cipher.encrypt(input).encode("hex"))

while(True):
    print("Enter you username (no whitespace) : "),
    sys.stdout.flush()
    input = raw_input()
    GetCookie(input)

사실 이 스크립트는 주어지지 않고

baby_crypt The cookie is input + flag AES ECB encrypted with the sha256 of the flag as the key. 라는 것만 주어진다.

먼저 대부분의 블록암호 문제는 암호모드와 Block Size를 알아내야 한다. 암호모드는 AES_ECB라는 것이 주어졌으니 Block Size를 알아내자.

A를 많이 입력하였을 때 988로 cookie가 시작되었고 A를 정확히 16개 보내주면 988로 시작한다. 따라서 Block Size는 16이다.

ECB는 같은 평문에 대해 같은 암호문을 출력하므로 code book을 작성하자.

from pwn import *
p=process(["python", "BabyCrypt.py"])

def GetCookie(payload):
    p.sendlineafter('(no whitespace) : ', payload)
    p.recvuntil('is: ')
    c = p.recv(32)
    return c

flag = GetCookie('A'*15)
for i in range(33, 128):
    comp = GetCookie('A'*15+p8(i))
    if flag == comp:
        print chr(i)
        break

처음 'F'를 이런식으로 알아낼 수 있다.

from pwn import *
p=process(["python", "BabyCrypt.py"])

def GetCookie(payload):
    p.sendlineafter('(no whitespace) : ', payload)
    p.recvuntil('is: ')
    c = p.recv(32)
    return c

payload = 'A'*15
for j in range(0, 16):
    flag = GetCookie('A'*(15-j))
    for i in range(33, 128):
        comp = GetCookie(payload+p8(i))
        if flag == comp:
            print chr(i)
            payload = payload[1:]+p8(i)
            break

16자리를 알아내었다.

Exploit Code

from pwn import *
p=process(["python", "BabyCrypt.py"])

def GetCookie(k, payload):
    p.sendlineafter('(no whitespace) : ', payload)
    p.recvuntil('is: ')
    c = p.recvline()[32*k:32*(k+1)]
    return c

answer = ''
payload = 'A'*15
for k in range(0, 5):
    for j in range(0, 16):
        flag = GetCookie(k, 'A'*(15-j))
        for i in range(33, 128):
            comp = GetCookie(0, payload+p8(i))
            if flag == comp:
                answer += chr(i)
                payload = payload[1:]+p8(i)
                break

print answer

Capture the Flag

image

'Writeup [crypto] > CTF 대회 기출' 카테고리의 다른 글

[PlaidCTF 2019] R u SAd?  (0) 2020.03.08
[OverTheWire Advent 2019] Santa's Signature  (0) 2020.03.08
[HITCON 2019] Lost Modulus Again  (0) 2020.03.08
[Codegate CTF 2018] rsababy  (0) 2020.03.08
[BambooFox CTF] oracle  (0) 2020.03.08

+ Recent posts