NahamCon CTF 2024
NAHAMCON CTF 2024
CRYPTOGRAPHY WRITEUP
Author:
Pham Quoc Trung
Used Language:
Python3
Problem Solving:
MagicRSA
Description:
Here's an RSA challenge using the most magical number of all.
Attachment:
rsa_with_a_magic_number.py
output.txt
Solution:
Đây là một bài liên quan tới RSA. Với e = 3 và việc mã hóa từng kí tự một của flag (m rất nhỏ) thì đây là đặc điểm của lỗ hổng small e, small n điển hình. Để giải thì ta chỉ cần lấy căn bậc 3 của từng c để ra được flag.
Flag: flag{87b9eb9a4894bcf8a1a95a20e33f11f7}
Encryption Server
Description:
I read online it's bad to re-use the prime numbers in RSA. So, I made this server that randomly generates them for me.
Attachment:
RSA_Encryption_Server.py
Recon:
Ở bài này, trước tiên, một số e sẽ được lấy random từ 500-1000 thông qua dòng này:
Hàm encrypt thực hiện mã hóa RSA từng kí tự của input truyền vào giống bài trước:
Đến với hàm main, ta sẽ có các chức năng như sau:
Chức năng 1: Tiến hành mã hóa input người dùng, in ra
ciphertextvàNsử dụng để mã hóa.Chức năng 2: Tiến hành mã hóa flag, in ra
ciphertextvàNsử dụng để mã hóa.Chức năng 3: Thoát chương trình.
Solution:
Ban đầu thì mình cũng chưa nghĩ ra cách giải, chỉ là mình thấy từ chức năng 1, mình có thể khôi phục được e nên mình đã tiến hành tìm luôn.
Cụ thể, mình sẽ truyền input là \x02. Khi đó, c = pow(2, e, n) và do e chỉ nằm trong khoảng 500-1000, mình có thể dễ dàng factor c để ra được lũy thừa của 2. Và số mũ đó chính là e.
Giờ thì đã có e. Sau khi nghĩ mất một khoảng thời gian, mình nhận ra từ chức năng số 2 mình có thể lấy ra nhiều cặp c, n tùy ý, và đặc điểm của chúng là đều có chung số mũ e. Từ đó, mình nghĩ ra việc sử dụng Hastad Broadcast Attack. Về kĩ thuật thì các bạn có thể xem ở đây: link.
Nôm na là ở đây mình sẽ lấy ra 3 cặp c, n. Khi đó, mình sẽ có 3 phương trình như sau:
Sử dụng Định lý thặng dư Trung Hoa, mình sẽ tìm ra được giá trị m^e mod(n1*n2*n3). Nếu m đủ nhỏ và tích của n1, n2, n3 đủ lớn (do m chỉ là một kí tự nên mình đã test và khi e < 800 thì vẫn vô tư), ta có thể tìm được m bằng cách lấy căn bậc e của m.
Vậy ta sẽ kết nối tới server, tìm e, nếu e < 800 thì sẽ tiến hành tấn công Hastad Broadcast Attack trên từng kí tự để tìm được flag
Flag: flag{29070b0688f398587d41041f4b25d8a3}
Another way:
Cả 2 bước là lấy e và tìm ra m đều có thể được thực hiện bằng cách brute-force.
Đối với e , chỉ cần brute pow(m, e, n) với m là các kí tự đã biết "f, l, a, g, {", so sánh với ciphertext lấy được từ 2 để tìm được e đúng.
Tương tự với flag, chỉ cần brute pow(m, e, n) nhưng lần này là brute m. Nếu kết quả giống với trong ciphertext thì đó là kí tự đúng.
Rigged Lottery
Description:
I found out that somebody has been able to guarantee to win a prize everytime in this lottery. I can't figure it out how they were able to do that. Can you?
Attachment:
server.py
Solution:
Bài này..., thôi bỏ đi :v. All you need is here: link
Flag: <ditme tat me server roi>
Blackjack
Description:
Can you make a killing by playing blackjack?
Attachment:
server.py
Recon:
Bài này thì nó chính là một code game Blackjack luôn. Mục tiêu là ta phải thắng đủ 1.000.000 chips để có thể lấy đươc flag. Có một số điểm cần lưu ý:
Nếu nhà cái có số điểm >= 17 thì sẽ auto STAND.
Mỗi lần thắng, nếu all in ta sẽ lãi 50% vốn.
Bộ bài được shuffle sẽ là thứ tự bốc, mình sẽ được phát 2 con đầu và nhà cái là 2 con sau (cái này cứ print ra là thấy chứ đọc code chết)
=> Chỉ cần biết trước được bộ bài đã shuffle, ta có thể HIT or STAND một cách thuận lợi để lời nhiều nhất và lỗ ít nhất. Đơn giản là nếu không thắng được, ta sẽ biết trước và cược 1 chips only.
Solution:
Ý tưởng giải bài này: link
Nôm na thì state thực sự chỉ dựa vào 15 bit cuối của seed nên mình có thể bruteforce seed trong khoảng 2**15. Sau đó mình hoàn toàn có thể lấy được shuffled desk của từng ván, từ đó quyết định HIT or STAND.
Bằng cách đầu hàng ván đầu (dùng 1 chips), mình hoàn toàn có thể lấy được tối thiểu 4 lá bài đầu của bộ shuffled (sẽ cho vào file input.txt). Nếu seed nào cho ra outputs có 4 lá đó liền nhau, đó chính là seed đúng. Đây là code để lấy ra seed và hiển thị bộ bài (mình không hiển thị các bài đã trên tay để cho mục đích cá nhân: chơi cho dễ).
Dựa trên việc số chips sau khi all in sẽ bằng 1.5 lần số chips gốc, chỉ cần mình thắng all in khoảng 18 lần là sẽ thừa tiền lấy flag.
Do đếu viết được code solve bằng pwntools vì output mỗi lần đều khác và logic hơi phức tạp với mình để code, nên mình sẽ chơi bằng tay (18 lần bọ)

Flag: flag{49bfe61dce46fc826814208e020f58f3}
© 2024,Pham Quoc Trung. All rights reserved.
Last updated