NewStarCTF flip-flop 复现(CBC字节翻转攻击)

NewStarCTF flip-flop 复现(CBC字节翻转攻击)

本来是一道nc题. 这里复现就把拿到admin权限为目标了.

题目

import os
from Crypto.Cipher import AES
auth_major_key = os.urandom(16)	# 密钥
from flag import secret
BANNER = """
Login as admin to get the flag ! 
"""
MENU = """
Enter your choice
[1] Create NewStarCTF Account
[2] Create Admin Account
[3] Login
[4] Exit
"""
print(BANNER)
def bxor(b1, b2): # 二进制内容异或
    result = b""
    for b1, b2 in zip(b1, b2):
        result += bytes([b1 ^ b2])
    return result
while True:
    print(MENU)
    option = int(input('> '))
    if option == 1:
        auth_pt = b'NewStarCTFer____'	# 明文
        user_key = os.urandom(16)		# iv
        cipher = AES.new(auth_major_key, AES.MODE_CBC, user_key)
        code = cipher.encrypt(auth_pt)	# 加密得到密文code
        print(f'here is your authcode: {user_key.hex() + code.hex()}')	# 给出iv和密文
    elif option == 2:
        print('GET OUT !!!!!!')
    elif option == 3:
        authcode = input('Enter your authcode > ')
        user_key = bytes.fromhex(authcode)[:16]	# 解密iv
        code = bytes.fromhex(authcode)[16:]		# 需解密的密文
        cipher = AES.new(auth_major_key, AES.MODE_CBC, user_key)
        auth_pt = cipher.decrypt(code)			# 解出的明文
        if auth_pt == b'AdminAdmin______':		# 目标明文
            a = user_key.hex() + code.hex()
            print(a)
        elif auth_pt == b'NewStarCTFer____':
            print('Have fun!!')
        else:
            print('Who are you?')
    elif option == 4:
        print('ByeBye')
        exit(0)
    else:
        print("WTF")

明文16字节, 故加解密时不考虑分割.

属于CBC字节翻转攻击.

CBC加密模式原理如下:

image

初始给定向量iv, 对明文加密,上一次的密文为下一次加密的iv.

解题思路

我们要得到admin权限,需要把解密得到的明文从'NewStarCTFer____'改成'AdminAdmin______'.

但是不能通过修改最后的密文来实现(因为密钥未知).

所以我们只能从iv下手了.

对于最后一次加密,设密文为m, iv(上一次加密得到的密文)为Cn-1, 加密得到密文为Cn, 我们需要明文从m改为m', 需要将Cn改为C'n.

把一次加解密过程抽象为函数Enc()Dec()则能推出:

\[Enc(m\oplus C_{n-1}) = C_n\\ \Rightarrow m = Dec(C_n)\oplus C_{n-1}...(1)\\ \]

同理得到:

\[m' = Dec(C_n)\oplus C'_{n-1}...(2) \]

将(1)式与(2)式异或:

\[m\oplus m' = C_{n-1}\oplus C'_{n-1}\\ C'_{n-1} = m\oplus m' \oplus C_{n-1} \]

我们将其前推到第一次加密, 可得:

\[iv' = m\oplus m' \oplus iv \]

由此可以写出攻击解密脚本.

Exp

def bxor(b1, b2):	# 对二进制数据进行异或
    result = b""
    for b_1, b_2 in zip(b1, b2):
        result += bytes([b_1 ^ b_2])
    return result

authcode = ""	# 这里是得到的数据
user_key = bytes.fromhex(authcode)[:16]	# 拿出iv
code = bytes.fromhex(authcode)[16:]		# 结果密文
user_key = bxor(user_key, b'AdminAdmin______')	# 异或目标明文
user_key = bxor(user_key, b'NewStarCTFer____')	# 异或原明文
authcode = user_key.hex() + code.hex()	# 最终结果:经过构造的authcode
print(authcode)

最后感谢猫神和黄gg的帮助.

posted @ 2023-01-03 12:49  络辰  阅读(158)  评论(0编辑  收藏  举报