DASCTF NOV - re - babytea - writeup

初识别为正常tea算法,稍改了魔数delta。
考点主要集中在对异常的识别与调试。一共有三处异常:
第一处:必定为0,必定执行异常处理程序:
在这里插入图片描述
第二处:由给予值的最高位(第32位)决定,不一定执行异常:

在这里插入图片描述
第三处:必定为0,必定执行异常处理程序:
在这里插入图片描述
那么这里有两点:①为了方便代码阅读,可以先将必定执行的语句改为jmp,之后伪代码可以如下图:
在这里插入图片描述
②要在动调里捕获异常,我们可以在异常处理代码的入口下断。(mov esp ,xxx)
如几处标红断点所示。
那么本题最后加上细节,分析可得,其魔改了一共了三个点:①tea开始时使用变量a、b异或v0、v1②sum累加delta时若最高位为0(或许是溢出)则异或0x1234567③tea结束时v0、v1为新的a、b

from ctypes import *

sign = []
sum = c_uint32(0)
d1 = 0x1234567
d2 = 0x89ABCDEF
for i in range(32):
    delta = 0x9E3779B1
    
    if (sum.value + delta) & 0x80000000 == 0:
        sign.append(1)
        sum.value += delta
        sum.value ^= 0x1234567
    else:
        sign.append(0)
        sum.value += delta

def encrypt(v, k):
    v0, v1 = c_uint32(v[0]), c_uint32(v[1])
    delta = 0x9E3779B1
    k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
    v0.value ^= 0x1234567
    v1.value ^= 0x89ABCDEF
    total = c_uint32(0)
    
    for i in range(32):
        #print(hex(v0.value))
        total.value += delta
        if sign[i] == 1:
            total.value ^= 0x1234567
        v0.value += ((v1.value << 4) + k0) ^ (v1.value +
                                              total.value) ^ ((v1.value >> 5) + k1)
        v1.value += ((v0.value << 4) + k2) ^ (v0.value +
                                              total.value) ^ ((v0.value >> 5) + k3)


    return v0.value, v1.value


def decrypt(v, k):
    v0, v1 = c_uint32(v[0]), c_uint32(v[1])
    #print(hex(v[0]), hex(v[1]))
    delta = 0x9E3779B1
    k0, k1, k2, k3 = k[0], k[1], k[2], k[3]

    total = c_uint32(0xc78e4d05)
    for i in range(32):
        v1.value -= ((v0.value << 4) + k2) ^ (v0.value +
                                              total.value) ^ ((v0.value >> 5) + k3)
        v0.value -= ((v1.value << 4) + k0) ^ (v1.value +
                                              total.value) ^ ((v1.value >> 5) + k1)
        if sign[31-i] == 1:
            total.value ^= 0x1234567
        total.value -= delta
    v0.value ^= d1
    v1.value ^= d2
    return v0.value, v1.value


if __name__ == "__main__":

    context = [0x5E27B530, 0xBDBEF7F3, 0xE3516A8F, 0x5D836CFE,
               0xD83DFA09, 0x8EFC737A, 0x55A853A3, 0x7A564EC5]
    # 待加密的明文,两个32位整型,即64bit的明文数据
    # 四个key,每个是32bit,即密钥长度为128bit
    key = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476]
    # 202CB962AC59075B964B07152D234B70
    flag = b''
    for i in range(0, 4):
        res = decrypt(context[i*2:i*2+2], key)
        d1 = context[i*2]
        d2 = context[i*2+1]
        flag +=res[0].to_bytes(
            4, "little")+res[1].to_bytes(4, "little")
    print(flag)


flag{600d_y0u_r34lly_kn0w_734_4nd_53h}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值