FPTU SecAthon 2023
FPTU SecAthon 2023
CRYPTOGRAPHY WRITEUP
Author:
Pham Quoc Trung
Used Language:
Python3
Problem Solving:
Combine
The symmetric crypto algorithm is much more secure, but the problem of key distribution is annoying. Why don't we combine both symmetric and asymmetric algorithm in a crypto system. What a brilliant idea!
Attachment: combine.py
#!/usr/bin/env python3
from Crypto.Util.number import getStrongPrime, bytes_to_long
from Crypto.Cipher import AES
from secret import flag, key
def encrypt_message(key, msg):
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
msg = pad(msg).encode()
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(msg).hex()
return ciphertext
def encrypt_key(key):
nbit = 2048
p = getStrongPrime(nbit // 2)
q = getStrongPrime(nbit // 2)
n = p * q
e = 3
m = bytes_to_long(key)
cipherkey = pow(m, e, n)
return n, e, cipherkey
ciphertext = encrypt_message(key, flag)
n, e, c = encrypt_key(key)
print('n =', n)
print('e =', e)
print('cipherkey =', c)
print('ciphertext =', ciphertext)
output.txt
Ở đây, flag được mã hóa thông qua AES_ECB với block size là 16-bits, cùng với đó là key được mã hóa dựa trên RSA.
Nhìn vào output được cung cấp, mình nhận thấy e = 3, dấu hiệu cho lỗ hổng small e trong RSA. Giải thích dễ hiểu thì khi e quá nhỏ, m^e sẽ nhỏ hơn n. Khi đó m^e % n sẽ bằng m^e. Vậy thì đơn giản để tìm lại được key, ta chỉ cần lấy căn bậc e của cipherkey.
Với key tìm được, mình thực hiện giải mã AES_ECB và ra được flag.
Flag: FUSEC{The_combine_crypto_system_is_really_secure!!!}
Secret Agent
The secret agents share private information through a secret services. We take it from a napped agent, but cannot get its private information without knowing secret id. Wrong trials will punch me!
Attachment: chal_server.py
Ở challenge này thì mình có thể tạo tài khoản và được cung cấp token cho tài khoản đó. Sau đó thì có thể thực hiện đăng nhập. Nếu mình có quyền "privileged_granted" thì có thể truy cập được vào mục show flag và lấy được flag.
Trước hết thì mình để ý hàm tạo user:
Có thể thấy, token là JSON dạng {"client_id": client_id, "privileged_granted": True} được mã hóa thông qua hàm encrypt và base64. Cũng từ đoạn code, mình thấy rằng có thể dễ dàng lấy được đoạn token của secret_client bằng cách để trống client_id khi tạo tài khoản.
Tuy nhiên thì token này cũng chưa ra ngay được flag vì muốn đăng nhập chúng ta cần phải điền cả client_id. Vì vậy mình tiến tới xem xét các hàm liên quan tới mã hóa:
Ở đây, hàm encrypt sử dụng 2 lần mã hóa AES_CBC với key, iv1, iv2 được gen ra từ hàm os.random(16) ở đầu chương trình. Quá trình mã hóa có thể được minh họa như sau:
Quá trình thám mã:
Vì là CBC nên ở đây, mình sẽ thực hiện tấn công Padding Oracle Attack. Lý thuyết sẽ được dựa trên bài viết này.
Với bài này, phần token trong login chính là nơi chúng ta thực hiện tấn công. Message "Failed! Check your token again\n" sẽ là cơ sở để phát hiện unpadding thành công hay không.
Code:
Output sau khoảng 10p:
Đến đây thì mình đã biết được client_id là fAiryTypeAn. Thử login với token đã lấy được từ trước, mình ra được flag.
Flag: FUSEC{rewire_for_basic_padding_orarcle_attack_is_fresh_didnt_it???}
Special
I'm experimenting a new attack techniques but it takes too much time to attack. How long do I have to wait?
Attachment: special.py
output.txt
Bài này thì cũng là một dạng về RSA. Từ code, ta thấy được hai số p,q được tạo ra từ hàm sau:
Chúng ta đã biết n, e, c nhưng chúng đều ở trong điều kiện đủ để không khai thác được các cách thông dụng. Nhận thấy ngoài ra mình còn được cung cấp cả r,s là 2 giá trị trả về cùng với p,q dựa trên hàm gen số nguyên tố, mình đoán có thể khôi phục p,q bằng cách nào đó. Xem xét kĩ hàm genSpecialPrime, mình nhận thấy số nguyên tố trả về có dạng a**m + r. Dựa trên số liệu bài cho, mình có thể viết lại p,q như sau:
Do đã biết n, và n = p * q, mình có:
Đến đây thì mình cũng khá là bế tắc. Sau khi bú chút hint thì mình nhận ra r,s là 2 số khá nhỏ. Khi đó, n sẽ xấp xỉ bằng (a*b)^6. Để gần hơn thì mình sẽ lấy a*b = căn bậc 6 của n-r*s
Phương trình trên là phương trình bậc 2 1 ẩn, hoàn toàn có thể giải ra được a. Từ đó ta sẽ có được b và tính được p,q. Lúc đó, bài toán RSA sẽ không còn gì khó nữa.
Flag: FUSEC(Simplifier_LSB_Attack_On_Special_Small_Cases_for_RSA)
© 2023,Pham Quoc Trung. All rights reserved.
Last updated