NewStarCTF flip-flop题解(CBC字节翻转攻击)
下面先给出题目
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): # use xor for bytes 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) cipher = AES.new(auth_major_key, AES.MODE_CBC, user_key) code = cipher.encrypt(auth_pt) print(f'here is your authcode: {user_key.hex() + code.hex()}') elif option == 2: print('GET OUT !!!!!!') elif option == 3: authcode = input('Enter your authcode > ') user_key = bytes.fromhex(authcode)[:16] 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")
观察题目,可以发现这是一道nc交互的题目,加密方式是AES-CBC
仔细观察,这道题目的AES的密钥是随机生成的,所以进行解密是不可取的。但由于所有的加密密钥都是一样的,且通过此密钥加密的一组明文密文 iv已知,这时我们可以使用CBC字节翻转攻击。
下面先介绍一下CBC加密流程
首先是将明文分组(一般16个字节一组),然后第一块明文与iv进行异或,利用key加密,随后生成的密文作为iv与第二块明文进行相同操作,由此得出密文。
那我们可以知道,想要改变某一块明文则需要改变前面的密文,这也就是CBC字节翻转攻击的方法。
下面先插入异或知识:
C=A^B
A=C^B
回到题目,可以发现明文只有16个字节,所以不需要分组。
我们的目标是flag,也就是明文为b'AdminAdmin______'
而我们现在已知明文b'NewStarCTFer____'及其密文,iv
那我们可以通过改变iv来达到改变明文的目的
下面给出修改脚本
先给出异或代码
def bxor(b1, b2):
result = b""
for b1, b2 in zip(b1, b2):
result += bytes([b1 ^ b2])
return result
authcode = user_key = bytes.fromhex(authcode)[:16] 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() print(authcode)
修改完我们便可以进行nc交互
在此感谢猫神对我做题一些细节的指导。