[CryptoHack] SYMMETRIC CIPHERS(Flipping Cookie)
- -
Flipping Cookie
문제
내 웹사이트에서 쿠키를 구할 수는 있지만, 플래그값을 읽는 데는 도움이 되지 않을 거라고...생각합니다. |
https://aes.cryptohack.org/flipping_cookie/
풀이
from Crypto.Cipher import AES
import os
from Crypto.Util.Padding import pad, unpad
from datetime import datetime, timedelta
KEY = ?
FLAG = ?
@chal.route('/flipping_cookie/check_admin/<cookie>/<iv>/')
def check_admin(cookie, iv):
cookie = bytes.fromhex(cookie)
iv = bytes.fromhex(iv)
try:
cipher = AES.new(KEY, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(cookie)
unpadded = unpad(decrypted, 16)
except ValueError as e:
return {"error": str(e)}
if b"admin=True" in unpadded.split(b";"):
return {"flag": FLAG}
else:
return {"error": "Only admin can read the flag"}
@chal.route('/flipping_cookie/get_cookie/')
def get_cookie():
expires_at = (datetime.today() + timedelta(days=1)).strftime("%s")
cookie = f"admin=False;expiry={expires_at}".encode()
iv = os.urandom(16)
padded = pad(cookie, 16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(padded)
ciphertext = iv.hex() + encrypted.hex()
return {"cookie": ciphertext}
먼저 코드를 보면
check_admin의 iv값과 cookie 값을 가져오고 진수화를 시키고,
cookie 값을 복호화를 시키고, 패딩을 풀어준 후, unpadded에 다.
그리고 unpadded변수에서 ";"로 나눠준 후, "admin=true"인지 확인 후
플래그값을 준다.
get_cookie에선
expires_at변수에 현재 날짜와 시간에 대한 정보를 저장한다.
cookie변수에는 함수를 호출할 수 있는 문자열에 "admin=false"과 expired_at변수를 넣고, 암호화를 한다.
iv변수는 16바이트의 임의값을 넣고
cookie변수에 16바이트의 패딩을 하고,
CBC암호화를 통해
encypted변수에 padded변수를 암호화시켜
ciphertext에 iv값과 암호화한 값을 붙여
반환한다.
이 문제는 바이트 플리핑 공격을 사용하게 되는데
바이트 플리핑 공격은 암호문의 바이트를 손상시켜 일반 텍스트의 바이트를 변경한다.
위 그림을 보면 두 번째 블록의 복호화를 할때
두 번째 암호블록과 키와 함께 복호화를 시키고, 두 번째 암호문과 xor연산을 하여 평문을 보여준다.
첫번째 암호문의 중간의 비트를 바꿔주어 평문에 다른 값을 바꿀 수 있다.
.
p0 =iv ^ d(c0) d(c0) =p0 ^ iv p`0 = iv` ^ d(c0) iv` = p`0 ^ p0 ^ iv |
첫번째 암호문의 경우 iv중 일부를 바꾸거나 변형시켜 이를 원하는 평문을 나타낼 수 있고
이에 대한 식을 보여준다면
p0는 평문, d는 복호화, c0는 암호문,
p`0는 원하는 평문으로 가정하면
p0 = iv ^ d(c0) 인데,
p`0= iv' ^ d(c0)인데,
이때 iv`값은,
iv`= p`0 ^ d(c0)이다.
이때 d(c0)값은
d(c0)은 p0 ^ iv값이기 때문에
iv` = p`0 ^ p0 ^ iv
즉 평문인p0를"admin=False"
우리가 원하는 평문인p'0를 "admin=True"라고 한다면
즉 iv`값은 "admin=True" ^ "admin=False" ^ iv 이므로
get_cookie를 실행해
쿠키값인 "3cb187419c45c338adaa5f0019c398511020494c6588460121765cab4cf83950c7d09992dba4200a5d708807dd439399"
을 얻고
이때 앞 16바이트 부분이 iv 값이기에
3cb187419c45c338adaa5f0019c39851는 iv값이다.
그래서 iv값과 "admin=False", "admin=True" 를 xor연산을 하면 변형된 iv값이 나올 것이다.
from Crypto.Util.number import *
from pwn import xor
c = '3cb187419c45c338adaa5f0019c398511020494c6588460121765cab4cf83950c7d09992dba4200a5d708807dd439399'
iv = bytes.fromhex((c[:32]))
c_some = c[32:]
other_iv = xor(iv,b'admin=False;',b'admin=True;').hex() #check_admin()함수에서 ;로 나누기 때문에 넣음
print("cookie : "+c_some)
print("other_iv : "+other_iv)
쿠키값과
변형 시킨 iv값은 3cb187419c45d12bb4bc015a1cca9c56이다.
그래서 쿠키값과 변형 시킨 iv값을 대입하였더니
플래그값이 나왔다.
플래그값은 crypto{4u7h3n71c4710n_15_3553n714l}이다.
'워게임 > CryptoHack' 카테고리의 다른 글
[CryptoHack] GENERAL(XOR Starter, XOR Properties, Favourite byte, 'You either know, XOR you don't', Lemur XOR) (0) | 2023.05.10 |
---|---|
[CryptoHack] SYMMETRIC CIPHERS(PASSWORDS AS KEYS) (0) | 2023.05.09 |
[CryptoHack] SYMMETRIC CIPHERS(ECB ORACLE) (0) | 2023.05.07 |
[CryptoHack] SYMMETRIC CIPHERS(Triple DES) (0) | 2023.05.06 |
[CryptoHack] SYMMETRIC CIPHERS(ECB CBC WTF) (0) | 2023.05.05 |