admin管理员组

文章数量:1597897

题目如下:

import binascii
import hashlib
from flag import flag
from Crypto.Cipher import AES
from Crypto.Util import *
import os

key1 = os.urandom(32)
key2 = b'tn*-ix6L*tCa*}i*'
key_len = len(key2)
assert flag.startswith(b'flag{')
assert (flag[13] == 45 and flag[18] == 45 and flag[23] == 45 and flag[28] == 45)
flag1 = b"2023: " + flag[:13] + flag[14:18] + flag[19:23]
flag2 = 

h = binascii.unhexlify(hashlib.sha256(key2).hexdigest())[:11]
gift1 = b'***********************************************************************************************'
gift2 = b'I tell you this, for when my days have come to an end , you, shall be King.' + h


def encrypt1(message, key):
    cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(128))
    ciphertext = cipher.encrypt(message)
    return ciphertext.hex()


def encrypt2(message, key, iv):
    padding = bytes((key_len - len(message) % key_len) * '&', encoding='utf-8')
    message += padding
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(message)
    return ciphertext.hex()


print("enc_gift1 = " + encrypt1(gift1, key1))
print("enc_flag = " + encrypt1(flag1, key1))
print("enc_gift2 = " + encrypt2(gift2, key2, flag2))

# enc_gift1 = bad7dbcff968d7cdbf51da011fe94e176fc8e7528e4dd85d2d5fc20ba69cefb7bfd03152a2874705bd2d857ea75b3216a830215db74772d9b9e9c218271d562694d3642d2917972fdb8c7363d8125730a50824cd8dc7e34cd4fa54be427cca
# enc_flag = c1c78891e30cd4c0aa5ed65c17e8550429c4e640881f9f1d6a56df
# enc_gift2 = ********c********b**************4***5********3****6a*****a**2********c*8******7***********3***5***2********e*5*************a******5**c***74***********fee046b4d2918096cfa3b76d6622914395c7e28eef

题目使用AES-CTR工作模式对gift1和flag1进行加密,使用的是相同的密钥key1

根据CTR工作原理

gift1 ⊕ key1 = enc_gift1

flag1 ⊕ key1 = enc_flag1

我们计算enc_gift1 ⊕ enc_flag1 得到 gift1 ⊕ flag1 这个结果再 与 flag1异或计算,即可得到gift1

def xor(a,b):
    temp = ""
    for x, y in zip(a, b):
        temp += chr(x ^ y)
    return temp.encode('latin1')

enc_gift1 = 'bad7dbcff968d7cdbf51da011fe94e176fc8e7528e4dd85d2d5fc20ba69cefb7bfd03152a2874705bd2d857ea75b3216a830215db74772d9b9e9c218271d562694d3642d2917972fdb8c7363d8125730a50824cd8dc7e34cd4fa54be427cca'
enc_flag = 'c1c78891e30cd4c0aa5ed65c17e8550429c4e640881f9f1d6a56df'
enc_flag = bytes.fromhex(enc_flag)
enc_gift1 = bytes.fromhex(enc_gift1)[:len(enc_flag)]
gift1 = xor(xor(enc_flag,enc_gift1),b"2023: flag{")

# print(gift1)
#gift1: b'I am Deathw'

通过计算,得到gift1的值为 I am Deathw 根据题目名Neltharion_and_Arthas搜索一下,发现《魔兽》系列游戏及其衍生作品中的角色,角色台词语录内容如下: 

I am Deathwing, the destroyer, the end of all things,inevitable,indomitable,I am the cataclysm

因此,gift1的内容就是I am Deathwing, the destroyer, the end of all things,inevitable,indomitable,I am the cataclysm

第二部分题目使用AES-CBC模式对gift2进行加密,key2作为对称密钥,flag2作为初始向量iv

由于key2有4个字符不确定,所以需要对key2进行暴力破解,但是我们需要寻找猜解时的验证条件。

AES分组长为16字节,enc_gift2给出的信息就是最后一个密文分组918096cfa3b76d6622914395c7e28eef以及倒数第二个密文分组的后5个字节fee046b4d2

h = binascii.unhexlify(hashlib.sha256(key2).hexdigest())[:11]
gift2 = b'I tell you this, for when my days have come to an end , you, shall be King.'+h

这两行可知,gift2的明文长度不满足其分组长,最后一个分组只有6个字符,还需要填充10个字符

padding = bytes((key_len - len(message) % key_len) * '&', encoding='utf-8')

这一行代码可知,这里填充的字符是 & ,也就是说倒数第二个明文分组的最后十个字符是 &

根据填充字符是&这一条件,再结合CBC模式的加密过程,可以用最后一个密文分组AES用key2解密再与其前一个分组的密文分组进行异或计算,最后十个字符若都是 & 则证明该key2是正确的。通过这个条件,可以得到key2。解密代码如下:

charlist = printable[:95]
pad_10chars = "fee046b4d2"
LastBlock = bytes.fromhex("918096cfa3b76d6622914395c7e28eef")
pad_c = bytes.fromhex(pad_10chars)
def brute_forcing():
    for x in tqdm(charlist):
        for y in charlist:
            for z in charlist:
                for w in charlist:
                    key2 = 'tn%s-ix6L%stCa%s}i%s' % (x, y, z, w)
                    cipher = AES.new(key2.encode(), AES.MODE_ECB)
                    message = cipher.decrypt(LastBlock)
                    pad_m = xor(message[-5:], pad_c)
                    if pad_m == b"&" * 5:
                        return key2
key2 = brute_forcing()
#key2:tn5-ix6L#tCaG}i6

得到key2之后需要求初始向量flag2,再回想CBC模式的加密流程图,我们现在知道明文gift2以及最后一个密文分组enc_gift2,那么就将最后一个密文分组解密,再与最后一个明文分组异或,得到前一个密文分组,再将其与对应的明文分组异或,得到前前一个密文分组......以此类推,我们就能得到初始向量flag2的值,解密代码如下:

key2 = b'tn5-ix6L#tCaG}i6'
h = binascii.unhexlify(hashlib.sha256(key2).hexdigest())[:11]
gift2 = b'I tell you this, for when my days have come to an end , you, shall be King.' + h + b'&'*10
Last_Cipher_Block = "918096cfa3b76d6622914395c7e28eef"
now_cipher = bytes.fromhex(Last_Cipher_Block)
for temp in range(6):
    mBlock = gift2[80-temp*16:96-temp*16]
    # print(mBlock)
    dec_ = AES.new(key2,AES.MODE_ECB)
    dec_m = dec_.decrypt(now_cipher)
    pre_cipher = xor(dec_m,mBlock)
    now_cipher = pre_cipher
print(now_cipher.decode())
#flag2:a3eae82b4c491e0e


合起来就就是正确答案了

本文标签: 线上鹏城NeltharionandArthas