做多了RSA的密码学,偶尔遇到AES还挺新颖的,写个wp记录一下。
下载下来之后得到两个python文件和两个没有扩展名的文件,随机打开一个:
from Cryptodome.Cipher import AES
import os
import gmpy2
from flag import FLAG
from Cryptodome.Util.number import *
def main():
key = os.urandom(2) * 16
iv = os.urandom(16)
print(bytes_to_long(key) ^ bytes_to_long(iv))
aes = AES.new(key, AES.MODE_CBC, iv)
enc_flag = aes.encrypt(FLAG)
print(enc_flag)
if __name__ == "__main__":
main()
简单分析一下,这个题用的是CBC模式的AES加密,AES是256bit密钥,iv是16位,然后将256bit的key和128bit的iv进行异或运算得到第一次输出,然后AES加密之后得到第二次输出。
值得注意的是,生成key的方法是先生成两个字节,然后再乘以16得到的,这样得到的密钥后面的每个字节都和前两个相同。
用记事本打开给到的另外一个文件:
91144196586662942563895769614300232343026691029427747065707381728622849079757
b'\x8c-\xcd\xde\xa7\xe9\x7f.b\x8aKs\xf1\xba\xc75\xc4d\x13\x07\xac\xa4&\xd6\x91\xfe\xf3\x14\x10|\xf8p'
根据加密过程中的逻辑,key为32byte,iv为16byte,两者进行了异或运算,那么key的高128bit不会改变,那么通过将高128bit与输出后的后半部分进行异或运算就能还原iv 和 key了。
直接写出exp:
from Crypto.Util.number import *
from Crypto.Cipher import AES
flag = b'\x8c-\xcd\xde\xa7\xe9\x7f.b\x8aKs\xf1\xba\xc75\xc4d\x13\x07\xac\xa4&\xd6\x91\xfe\xf3\x14\x10|\xf8p'
s = '91144196586662942563895769614300232343026691029427747065707381728622849079757'
s1 = long_to_bytes(int(s))
iv = long_to_bytes(int(bytes_to_long(s1[0:16])) ^ int(bytes_to_long(s1[16:])))
key = s1[0:16] * 2
aes = AES.new(key, AES.MODE_CBC, iv)
print(aes.decrypt(flag))
输出:b'actf{W0W_y0u_can_so1v3_AES_now!}'