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:


浙公网安备 33010602011771号