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 ciphertextN sử dụng để mã hóa.

  • Chức năng 2: Tiến hành mã hóa flag, in ra ciphertextN sử 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:

c1memodn1c2memodn2c3memodn3c_1 \equiv m^e \mod n_1 \\ c_2 \equiv m^e \mod n_2 \\ c_3 \equiv m^e \mod n_3

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