[watevrCTF 2019]Crypto over the intrawebs

分析代码,可以知道关键部分:

def encrypt(plaintext):
	global USERNAME
	global key
	plaintext = USERNAME + ": " + plaintext
	out = [random.randint(0, 9999), random.randint(0, 999)]
	for i in range(len(plaintext)):
		out.append( ( out[i+1] + ( (out[i] * ord(plaintext[i])) ^ (key+out[i+1]) ) ) ^ (key*out[i]) )

因为每次发送的消息都有固定头部,所以可以利用这一特征求出 key。利用z3构造多个方程求解。由于^运算的参与,不能使用Int(‘x’),需使用比特流BitVec(‘x’,bit)。由key的生成过程可知 key 最多 76bits。

from z3 import *
from tqdm import tqdm

conv = open(r'conversation','rb').readlines()
text = []
for i in range(1,len(conv),2):
    out = conv[i][9:-1].split()
    out = [int(j) for j in out]
    text.append(out)

know = 'Houdini: '
out = text[0]
for bit in tqdm(range(1, 78)):
    x = BitVec('x', bit)
    S = Solver()
    for i in range(len(know)):
        S.add( (out[i+1] + ((out[i] * ord(know[i])) ^ (x+out[i+1]))) ^ (x*out[i]) == out[i+2] )
    S.check()
    result = S.model()
    key = result[x].as_long()

    message = ''
    for each in text:
        for k in range(len(each)-2):
            try:
                ch = (((each[k+2] ^ (key*each[k])) - each[k+1]) ^ (key + each[k+1]))//each[k]
                message += chr(ch)
            except:
                pass
    
    if 'flag' in message or 'watevr' in message:
        print(message)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值