密码学实战 - HTB The Last Dance

2,175 阅读3分钟

概述

The Last Dance是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点包括ChaCha20算法以及XOR运算。

题目分析

相关的任务文件包括Python源代码文件source.py以及文本文件out.txt

source.py内容节选如下

from Crypto.Cipher import ChaCha20
from secret import FLAG
import os

def encryptMessage(message, key, nonce):
    cipher = ChaCha20.new(key=key, nonce=iv)
    ciphertext = cipher.encrypt(message)
    return ciphertext


def writeData(data):
    with open("out.txt", "w") as f:
        f.write(data)


if __name__ == "__main__":
    message = b"Our counter agencies have intercepted your messages and a lot "
    message += b"of your agent's identities have been exposed. In a matter of "
    message += b"days all of them will be captured"

    key, iv = os.urandom(32), os.urandom(12)

    encrypted_message = encryptMessage(message, key, iv)
    encrypted_flag = encryptMessage(FLAG, key, iv)

    data = iv.hex() + "\n" + encrypted_message.hex() + "\n" + encrypted_flag.hex()
    writeData(data)

out.txt内容节选如下

c4a66edfe80227b4fa24d431
7aa34395a258f5893e3db1822139b8c1f04cfab9d757b9b9cca57e1df33d093f07c7f06e06bb6293676f9060a838ea138b6bc9f20b08afeb73120506e2ce7b9b9dcd9e4a421584cfaba2481132dfbdf4216e98e3facec9ba199ca3a97641e9ca9782868d0222a1d7c0d3119b867edaf2e72e2a6f7d344df39a14edc39cb6f960944ddac2aaef324827c36cba67dcb76b22119b43881a3f1262752990
7d8273ceb459e4d4386df4e32e1aecc1aa7aaafda50cb982f6c62623cf6b29693d86b15457aa76ac7e2eef6cf814ae3a8d39c7

解题思路

ChaCha20由加密学大佬Daniel J. Bernstein(djb)发明的一种传流加密法。其算法要求一个密钥(key)和一个不可重复使用的种子数据(nonce或initialization vector)。

以上的代码中,相同的iv被使用了两次,因此两次加密的明文和密文之间就存在如下的关系

plaintext1 xor plaintext2 = cipertext1 xor cipertext2  

out.txt提供了cipertext1cipertext2plaintext1则是源代码中的message, 由此我们可以通过如下的计算得到plaintext2,也就是FLAG

plaintext2 = cipertext1 xor cipertext2 xor plaintext1  

解题过程

以下代码使用了pwntools工具库·提供的xor方法来对不同长度和类型的变量进行XOR计算。

import pwn

cipertext1 = '7aa34395a258f5893e3db1822139b8c1f04cfab9d757b9b9cca57e1df33d093f07c7f06e06bb6293676f9060a838ea138b6bc9f20b08afeb73120506e2ce7b9b9dcd9e4a421584cfaba2481132dfbdf4216e98e3facec9ba199ca3a97641e9ca9782868d0222a1d7c0d3119b867edaf2e72e2a6f7d344df39a14edc39cb6f960944ddac2aaef324827c36cba67dcb76b22119b43881a3f1262752990'
cipertext2 = '7d8273ceb459e4d4386df4e32e1aecc1aa7aaafda50cb982f6c62623cf6b29693d86b15457aa76ac7e2eef6cf814ae3a8d39c7'

message = b"Our counter agencies have intercepted your messages and a lot "
message += b"of your agent's identities have been exposed. In a matter of "
message += b"days all of them will be captured"

cipertext1 = bytes.fromhex(cipertext1)
cipertext2 = bytes.fromhex(cipertext2)
plaintext1 = message

plaintext2 = pwn.xor(cipertext1, cipertext2, plaintext1)

print("FLAG:", plaintext2)