Writeup WhiteHat Contest lần 2
Crypto 500:
Khi đọc source ta thấy bài này dùng cơ chế mã hóa CBC mode.
Trên đây là hình minh họa cơ chế decrypt của CBC mode,
Ta thấy khi giải mã thì ciphertext sau khi qua block decrypt sẽ phải xor với khối ciphertext nằm trước. Đó chính là điểm chúng ta có thể lợi dụng để thêm role trên chuỗi login bằng cách sửa 2 byte
vd tên login của mình nhập vào là:
Sau đó bằng cách sửa 2 byte trong block thứ 2 của ciphertext (ciphertext của đoạn số 111...), ta điều khiển được quá trình decrypt của block đứng sau vì phép xor có tính chất kết hợp và giao hoán A^(B^A) = A^B^A = A^A^B = (A^A)^B = B
trong chuỗi login của mình thì cần đổi X thành & và đổi Y thành =, nên sẽ là như vậy (xem như C=cipher (cái mình có), K=Key (mà mình không biết) cho đơn giản):
Bình thường:
Modified:
tương tự với '=', cuối cùng là code lấy flag
Khi đọc source ta thấy bài này dùng cơ chế mã hóa CBC mode.
Trên đây là hình minh họa cơ chế decrypt của CBC mode,
Ta thấy khi giải mã thì ciphertext sau khi qua block decrypt sẽ phải xor với khối ciphertext nằm trước. Đó chính là điểm chúng ta có thể lợi dụng để thêm role trên chuỗi login bằng cách sửa 2 byte
vd tên login của mình nhập vào là:
Mã:
00000000001111111111111111XroleYadministrator //tên này hoàn toàn hợp lệ đối với filter '^[\w]+$'
trong chuỗi login của mình thì cần đổi X thành & và đổi Y thành =, nên sẽ là như vậy (xem như C=cipher (cái mình có), K=Key (mà mình không biết) cho đơn giản):
Bình thường:
Mã:
Encrypt: C='X'^K
Decrypt: K^C='X'
Modified:
Mã:
Encrypt: C='X'^K
Decrypt: K^(C^'X'^'&')=(K^C)^'X'^'&'='X'^'X'^'&'='&' :D
tương tự với '=', cuối cùng là code lấy flag
Mã:
#!/usr/bin/env python2
import base64
import socket as sk
from time import sleep
def conn():
s = sk.socket(sk.AF_INET,sk.SOCK_STREAM)
s.connect(('ctf.whitehat.vn',1365))
return s
def rand(len=16):
return ''.join([chr(0x30+ord(i)%10) for i in open('/dev/urandom').read(16)])
def register(username):
s = conn()
s.recv(1024)
s.send('0\n')
s.recv(1024)
s.send(username)
return s.recv(1024).split('\n')[2]
def login(sig):
s = conn()
s.send('1\n')
sleep(0.01)
s.send(base64.b64encode(sig))
return s.recv(1024,sk.MSG_WAITALL)
sig = register('1234567890'+rand()+'XroleYadministrator').decode('base64')
payload = sig[:16] #login=1234567890
payload += chr(ord(sig[16])^ord('X')^ord('&')) #X -> &
payload += sig[17:21] #role
payload += chr(ord(sig[21])^ord('Y')^ord('=')) #Y -> =
payload += sig[22:] #the rest
print login(payload)
//đang viết tiếp những bài còn lại======================
[0] Register
[1] Login
======================
Provide your certificate:
Your login : ['1234567890\xc87n\x81a\xee%\x87\xe1\x1d8\x0f\x80\xea\x8ai']
Your role : ['administrator', 'anonymous ']
Well done!! A bit-flipping attack is an attack on a cryptographic cipher in which the attacker can change the ciphertext in such a way as to result in a predictable change of the plaintext, although the attacker is not able to learn the plaintext itself. Here your flag: Flag{CBC_M0D3_1S_N0T_EN0UGH}
Chỉnh sửa lần cuối bởi người điều hành: