概述
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提供了cipertext1和cipertext2, plaintext1则是源代码中的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)