[BJDCTF 2020]encode

最后更新于 2024-07-13 461 字 预计阅读时间: 2 分钟


将程序·放进DIE,存在upx壳,脱壳分析后得到

在v6[50]后输入flag,比较flag的长度是否为21后进行base64的换表编码,再将编码后的结果放在v5[18]后进行异或加密后以v5作为key对v5[18]后的字符串进行rc4加密,再与v6对比。

逆向过程:先用v6进行rc4解密-->对其进行异或操作-->base64换表解码得出flag

进行rc4解密的过程出现了一些问题,查看别人的wp才发现密文长度不对,正常来说输入的flag为21位,base64后应该为28位,在进行str2hex变成56位,而密文v6却只有49位,少了7位,原因是ida将0x01-0x0f变成了1-f少了部分0使得bytes.fromhex()得到错误的十六进制导致解密出现错误,得到正确的密文

正确的密文E8D8BD91871A010E560F53F4889682F961420AF2AB08FED7ACFD5E00,rc4解密后得到


def rc4(key, ciphertext):
    sbox = list(range(256))
    j = 0
    for i in range(256):
        j = (j + sbox[i] + key[i % len(key)]) % 256
        sbox[i], sbox[j] = sbox[j], sbox[i]
    i = 0
    j = 0
    keystream = []
    for _ in range(len(ciphertext)):
        i = (i + 1) % 256
        j = (j + sbox[i]) % 256
        sbox[i], sbox[j] = sbox[j], sbox[i]
        k = sbox[(sbox[i] + sbox[j]) % 256]
        keystream.append(k)

    # 解密密文
    plaintext = []
    for i in range(len(ciphertext)):
        m = ciphertext[i] ^ keystream[i]
        plaintext.append(m)
    print(plaintext)

    return ''.join([chr(p) for p in plaintext])


data = [0xE8, 0xD8, 0xBD, 0x91, 0x87, 0x1A, 0x01, 0x0E, 0x56, 0x0F
    , 0x53, 0xF4, 0x88, 0x96, 0x82, 0xF9, 0x61, 0x42, 0x0A, 0xF2, 0xAB
    , 0x08, 0xFE, 0xD7, 0xAC, 0xFD, 0x5E, 0x00]
key = b"Flag{This_a_Flag}"

plaintext = rc4(key, data)

a=[35, 21, 37, 83, 8, 26, 89, 56, 18, 106, 57, 49, 39, 91, 11, 19, 19, 8, 92, 51, 11, 53, 97, 1, 81, 31, 16, 92]
b="Flag{This_a_Flag}"
s=len(b)
for x in range(len(a)):
    print(chr(a[x]^ord(b[x%s])),end="")

得到eyD4sN1Qa5Xna7jtnN0RlN5i8lO=进行换表解码

此作者没有提供个人介绍。
最后更新于 2024-07-13