CryptoHack Bean Counter

题目脚本

from Crypto.Cipher import AES
import os

KEY = ?

class StepUpCounter(object):
    def __init__(self, step_up=False):
        self.value = os.urandom(16).hex()
        self.step = 1
        self.stup = step_up

    def increment(self):
        if self.stup:
            self.newIV = hex(int(self.value, 16) + self.step)
        else:
            self.newIV = hex(int(self.value, 16) - self.stup)
        self.value = self.newIV[2:len(self.newIV)]
        return bytes.fromhex(self.value.zfill(32))

    def __repr__(self):
        self.increment()
        return self.value

@chal.route('/bean_counter/encrypt/')
def encrypt():
    cipher = AES.new(KEY, AES.MODE_ECB)
    ctr = StepUpCounter()

    out = []
    with open("challenge_files/bean_flag.png", 'rb') as f:
        block = f.read(16)
        while block:
            keystream = cipher.encrypt(ctr.increment())
            xored = [a^b for a, b in zip(block, keystream)]
            out.append(bytes(xored).hex())
            block = f.read(16)

    return {"encrypted": ''.join(out)}

由于 PNG 图像的前缀已知,因此我们可以得到密钥,通过密钥直接解密文件即可,根据加密规则,密钥会有轻微扰乱,但对于图像而言,轻微的扰乱人眼无法察觉,唯一需要注意的是文件后缀错误,部分图像编辑器无法打开,直接在 VScode 内查看即可。

脚本如下

import requests
from tqdm import *
from Crypto.Util.number import *
from pwn import *

# First 16 numbers of PNG: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452

requests.adapters.DEFAULT_RETRIES = 100000
s = requests.Session()
s.timeout = (1000.0, 1000.0)

encrypt_flag = requests.get(f'http://aes.cryptohack.org/bean_counter/encrypt')
result = encrypt_flag.json()['encrypted']
ciphertext = bytes.fromhex(result)
PNG_headers = bytes.fromhex('89504e470d0a1a0a0000000d49484452')
key = xor(ciphertext, PNG_headers)

png = b''
for i in range(len(ciphertext)):
    png += xor(key[i % len(key)], ciphertext[i])

with open('d:/Desktop/bean_counter.png', 'wb') as f:
    f.write(bytes(png))

FLAG:

image

posted @ 2025-02-27 11:16  YipChip  阅读(40)  评论(0)    收藏  举报