DASCTF 2024最后一战RE题wp

tryme

很简单的base64编码,修改了码表,然后逐位异或2
在这里插入图片描述
在这里插入图片描述

黑客不许哭

CUDA的入门编程,只要装过CUDA库就可以跑。
在这里插入图片描述
这里是设置v4的张量数据
在这里插入图片描述
这里是设置v8的,但是第一个数据又被后面覆盖为flag输入的字符码*1.020123456789
在这里插入图片描述
总体的逻辑就是把输入的flag字符逐位×1.020123456789,然后加1,最后再和一个double数组相乘,判断是否等于另一个double数组

在这里插入图片描述
但是发现结果不准确,比如第一个flag字符应该是D,ascii码68,计算(68*1.020123456789+1)*60.51846366284686=4258.58715955144
但是比较结果是4358.58716,基本上差了100,我们就把比较结果减100来计算。
写出计算脚本如下:

a=[
(4358.58716  -100)/60.51846366284686,
(6122.2983   -100)/89.4737043286176 ,
(2158.74574  -100)/24.03104711352393,
(5973.017537 -100)/84.68873702464015,
(9173.840881 -100)/104.6695364464632,
(6164.67827  -100)/83.75627693648984,
(12293.528276-100)/96.41044018110416,
(4091.327439 -100)/75.27071882034213,
(3360.696562 -100)/60.33140727998576,
(2403.667017 -100)/46.10475987767577,
(3199.455077 -100)/56.28563000222285,
(4962.117508 -100)/86.68936481373537,
(8266.407604 -100)/80.87786332435297,
(2863.062918 -100)/55.29894355978243,
(1044.626306 -100)/9.261748448423328,
(1067.530873 -100)/20.6272127322797 ,
(3217.476319 -100)/31.1897419717479 ,
(6260.942959 -100)/116.1865600512257,
(3278.952568 -100)/30.85991826286804,
(160.724197  -100)/1.063344600421732,
(596.797742  -100)/10.59144776777723,
(3277.973032 -100)/55.64965261721374,
(6368.757598 -100)/122.950447694522 ,
(842.858109  -100)/7.140637105592679,
(5925.142209 -100)/55.44977106531295,
(3046.937162 -100)/62.82703886751251,
(12752.384458-100)/125.3057489450499,
(2442.54747  -100)/45.94487116254584,
(1827.164764 -100)/32.57185367060958,
(4903.961921 -100)/92.37291765689986,
(5619.869598 -100)/117.6805078353046,
(3851.247916 -100)/63.42241478603398,
(4472.987644 -100)/84.08593452538155,
(13135.636855-100)/125.3035418960081,
(1640.630636 -100)/26.50460072585211,
(975.429551  -100)/15.6085145259943 ,
(2174.379531 -100)/35.68707511621358,
(2289.845471 -100)/37.67352051379848,
(2605.707441 -100)/24.32434117146088,
(1488.586824 -100)/25.69248490815507,
(12216.019619-100)/116.4638282572803,
(4588.270425 -100)/86.30264794289376,
(4803.36317  -100)/79.51984419851664,
(13035.30263 -100)/100.6517460100543,
]
flag=''
for i in range(len(a)):
    a[i]=a[i]/1.020123456789
    flag+=chr(int(a[i]-0.5))
print(flag)
#DASCTF{34056b0c-a3d7-71ef-b132-92e8688d4e29}

得到flag

刻板印象re

咋一看很简单
在这里插入图片描述

加密逻辑在sub_401740,但是401795处有修改堆栈返回值的代码,IDA误以为后面没有代码了,nop掉这部分,就可以看到完整的伪C代码。
在这里插入图片描述
这里是典型的XTEA加密和异或加密,但是根据给定的key和算法,计算出来的是一个假flag:
fakeflag_plz_Try_more_hard_to_find_the_true_flag
再仔细检查exe文件,发现有tlscallback中有额外逻辑处理
在这里插入图片描述
修改了main函数里的sub_40126C函数jmp 地址,使其调用sub_41F000函数。
在这里插入图片描述
这里又有SMC的代码,动态调试下看比较简单:
在这里插入图片描述
这里有很多一段一段的汇编代码,popa和pusha中间的部分才是加密逻辑的代码,其余的代码都是用来控制代码块执行的。
由于实际代码不是很多,就用人肉的方式看了下,大致逻辑就是一个XXTEA加密,密钥是{What_is_this_?},delta是0x11451419
加密后还需要跟 8f6ca63f943df5d9366651d7662fb38fc0619ecee9d7e1bf13141614c2e7c33a7f94a1e7240ea75cd377fe4f11dc6923异或
最后再和结果字符串比较
根据这个逻辑写出解密脚本:

import struct
def XTEAdecrypt(rounds, v, k):
    v0 = v[0]
    v1 = v[1]
    delta = 0x9E3779B9
    x = delta * rounds
    for i in range(rounds):
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (x + k[(x >> 11) & 3])
        v1 = v1 & 0xFFFFFFFF
        x -= delta
        x = x & 0xFFFFFFFF
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (x + k[x & 3])
        v0 = v0 & 0xFFFFFFFF
#    v[0] = v0
#    v[1] = v1
    return [v0,v1]

def xor(a,b):
    return bytes([i^j for i,j in zip(a,b)])
def shift(z, y, x, k, p, e):
    return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))

def XXTEAdecrypt(v, k):
    delta = 0x11451419
    n = len(v)
    rounds = 6 + 52 // (n)
    x = (rounds * delta) & 0xFFFFFFFF
    y = v[0]
    for i in range(rounds):
        e = (x >> 2) & 3
        for p in range(n - 1, 0, -1):
            z = v[p - 1]
            v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
            y = v[p]
        p -= 1
        z = v[n - 1]
        v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
        y = v[0]
        x = (x - delta) & 0xFFFFFFFF
    return v
if __name__ == '__main__':
    key=[]
    keys=b'{What_is_this_?}'
    for i in range(4):
        key.append(struct.unpack('<I',keys[i*4:i*4+4])[0])
    enc=bytes.fromhex('18091C14371D162D3C05163E0203102C0E313915043A39030D132B3E06083700170B001D1C0016060717300330060A71')
    enc=xor(enc,bytes.fromhex('8f6ca63f943df5d9366651d7662fb38fc0619ecee9d7e1bf13141614c2e7c33a7f94a1e7240ea75cd377fe4f11dc6923'))
    encrypted=[]
    for i in range(len(enc)//4):
        encrypted.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
    decrypted = XXTEAdecrypt(encrypted, key)
    flag=b''
    for i in range(len(decrypted)):
        flag+=struct.pack('<I',decrypted[i])
    key = [0x756F797B,0x6E69665F,0x74695F64,0x7D3F215F]
    rounds = 32
    enc=flag
    enc=xor(enc,bytes.fromhex('DA3023E3DC398260A54468C2437ABBE450E102C28159EA1EC68B7138278394D8F48D1A2A568A4AD454DC243FB9ED7B9A'))
    encrypted=[]
    flag=b''
    for i in range(len(enc)//4):
        encrypted.append(struct.unpack('<I',enc[i*4:i*4+4])[0])
    for i in range(len(encrypted)//2):
        decrypted = XTEAdecrypt(rounds,encrypted[i*2:i*2+2], key)
        x=struct.pack('<2I',decrypted[0],decrypted[1])
        flag+=x
    print(xor(flag,b'Laughter_is_poison_to_fearLaughter_is_poison_to_fear'))
#DASCTF{You_come_to_me_better_than_all_the_good.}

secret_of_inkey

在这里插入图片描述
根据输入key的对话框字符串,找到对应的函数(sub_417240)
动态调试,找到加密处理函数sub_416D70
在这里插入图片描述
解密处理逻辑:逐位异或索引和key,然后进行AES_ECB解密,都是使用输入的key值。
然后把所有的加密的数据导出来,用脚本循环跑:

from Crypto.Cipher import AES
import re
a=bytes.fromhex('C9EFAB9D79AEA0435699970D9CBDF02989D26F51BCC425EEFCFFD46B7E86C2FCA1D7544BA64FBD757CE9206...太长省略...EACE0E6AFDCA5FA7B327BE42CEA6A6F9905AF097C2DC4C4A6DAFE94955B4368DF1E8AE87A5A5E47C6E9ACF6E092F9179719422')
keys={'565':'9fc82e15d9de6ef2'}
allenc=[]
for i in range(len(a)//32):
    allenc.append(a[i*32:i*32+32])
run=1
while(run):
    run=0
    for j in list(keys.keys()):
        cipher=AES.new(keys[j].encode(),AES.MODE_ECB)
        for i in allenc:
            encs=bytearray(i)
            for k in range(32):
                encs[k]^=k^ord(keys[j][k%16])
            dec=cipher.decrypt(bytes(encs))
            if dec[:6]==b'key_of':
                x=re.findall('key_of_(\d+)_is_"([0-9a-f]+)"',dec.decode())
                if len(x)>0:
                    if x[0][0] not in keys:
                        keys[x[0][0]]=x[0][1]
                        #print(len(keys))
                    allenc.remove(i)
                    run=1
            elif b'nothing_here' in dec:
                allenc.remove(i)
                run=1
        #oldkeys.append(keys.pop(j))
        
for j in list(keys.keys()):
    cipher=AES.new(keys[j].encode(),AES.MODE_ECB)
    for i in allenc:
        encs=bytearray(i)
        for k in range(32):
            encs[k]^=k^ord(keys[j][k%16])
        dec=cipher.decrypt(bytes(encs))
        for k in range(32):
            if dec[k]<0x20 or dec[k]>0x7e:
                break
        else:
            print(j,dec.decode())

输出结果:
599 Congratulations!
599 You_have_find_the_true_box
599 This_is_the_treasure
599 DASCTF{Do_y0u_l1ke_wh4t_you_s3e}
也可以点击编号599的格子,输入密码8760b9754d97849e看到flag
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值