from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import json
import os
FLAG = ?
KEY = ?
def admin():
print("welcome admin")
print(f"Flag = {FLAG}")
def guest():
print("welcome guest")
def auth():
user = dict()
username = input("username : ")
password = input("password : ")
user["is_admin"] = int(username == "admin" and password == FLAG)
plaintext = json.dumps(user).encode()
padded = pad(plaintext, 16)
iv = os.urandom(16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
try:
encrypted = iv + cipher.encrypt(padded)
except ValueError as e:
return {"error": str(e)}
print(f"Here is your token : {encrypted.hex()}")
return user
def authToken():
token = input("Token : ")
token = bytes.fromhex(token)
iv = token[:16]
token = token[16:]
cipher = AES.new(KEY, AES.MODE_CBC, iv)
try:
plaintext = cipher.decrypt(token)
unpadded = unpad(plaintext, 16)
user = json.loads(unpadded)
except ValueError as e:
return {"error": str(e)}
return user
print("Welcome !")
print("Please login first.")
choice = input("How would you login ?\n1) Token\n2) Credentials\n\nChoice :")
if choice == "1":
user = authToken()
elif choice == "2":
user = auth()
else:
print("error... goodbye")
exit(0)
if "error" in user:
print(f"ERROR : {user['error']}")
exit(0)
elif user["is_admin"] == 1:
admin()
else:
guest()
The challenge objective is to authenticate as admin using an arbitrary token forged using bit flipping attack.
Exploitation
First, a legit token is needed.
$ python3 chall.py
Welcome !
Please login first.
How would you login ?
1) Token
2) Credentials
Choice :2
username : a
password : a
Here is your token : 9cdc43fb9d2fed9a0b5ccc837d4a5badf1b4b1731bcca9977bc862f3e2033970
welcome guest
The token contains two blocks, the IV and the ciphertext block.
The original plaintext is :
b'{"is_admin": 0}\x01'
The targeted data is :
b'{"is_admin": 1}\x01'
The IV can be replace with the value 9cdc43fb9d2fed9a0b5ccc837d4b5bad obtaned using the following operation :
As explain , plaintext is xored with the precedent cipherblock ( the IV for the first block ) before encryption. As we can control the ciphertext, we can control the plaintext.
The json data +
If you want to try this exploit by yourself, you can pull :