CTFshow-_菜狗杯-龙珠NFT
搜索有万分之六的概率拿到存在龙珠的地址,10次机会内拿到七个龙珠才能拿到Flag
查看生成龙珠地址的代码
class AESCipher(): def __init__(self,key): self.key = self.add_16(hashlib.md5(key.encode()).hexdigest()[:16]) self.model = AES.MODE_ECB self.aes = AES.new(self.key,self.model) def add_16(self,par): if type(par) == str: par = par.encode() while len(par) % 16 != 0: par += b'\x00' return par def aesencrypt(self,text): text = self.add_16(text) self.encrypt_text = self.aes.encrypt(text) return self.encrypt_text def aesdecrypt(self,text): self.decrypt_text = self.aes.decrypt(text) self.decrypt_text = self.decrypt_text.strip(b"\x00") return self.decrypt_text data['address']= base64.b64encode(AES_ECB.aesencrypt(json.dumps(data))).decode()
查看处理龙珠地址的代码
address=request.args.get('address') data=AES_ECB.aesdecrypt(base64.b64decode(address)) data=json.loads(data.decode()) if data['dragonball'] !="0": players[data['player_id']]['dragonballs'].append(data['dragonball']) return jsonify({'get_ball':data['dragonball']})
地址是对data进行加密的结果,AES的ECB模式的加密和解密都是16位为一组进行的
第二次data是这个{"player_id": "572d4e421e5e6b9bc11d815e8a027112", "dragonball": "0", "round_no": "2", "time":"2022-10-19 15:06:45"}
其中红色部分是其中一组,"dragonball":"0"表示没有龙珠,"round_no":"2"表示第二次搜索,如果直接使用这个地址将不会获得龙珠
但是如果去掉红色部分变成{"player_id": "572d4e421e5e6b9bc11d815e8a027112", "dragonball": "2", "time":"2022-10-19 15:06:45"}就会获得二星龙珠
简单写一个Python脚本,先对地址base64解密,然后去掉红色部分(根据位数),再进行base64加密,这样后端对地址处理的时候就会解密成功并且可以获得龙珠
import base64 while True: miwen=base64.b64decode(input('address:')) fake_address=miwen[:64]+miwen[80:] print(base64.b64encode(fake_address))