LEAST COMMON GENOMINATOR?
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
- Tóm tắt đoạn code trên:
- Đoạn code trên tạo một object là LCG, trong đó có 3 số được giữ bí mật là m,n,c nhưng bù lại ta biết được giá trị seed. LCG có phương thức
next()
nhằm tạo ra các số có giá trị = (state*m + c) % n
và lưu nó vào state mới cho các lần tính tiếp theo.
- Đề bài đã tạo ra các số 512 bits bằng LCG, 6 giá trị đầu tiên tạo ra được lưu vào file
dump.txt
, nếu tạo được số nguyên tố thì lưu vào mảng primes_arr
, nó sẽ generate cho đến khi primes_arr
đủ 8 số.
- Dùng
primes_arr
làm private key để mã hóa RSA, ghi kết quả mã hóa vào file flag.txt
và export public key ra file public.pem
.
- Để làm bài trên, ta phải tìm được 3 số m,n,c trong LCG, từ 6 số trong file
dump.txt
- Tìm n: Giả sử 6 số trong
dump.txt
là x0 tới x5, ta có:
Tương tự:
Do đó n là ước của gcd 2 số trên.
Ở bài này ta may mắn tìm được luôn n là gcd 2 số đó.
- Tìm m: Vì nên
- Tìm c: Vì nên
- Tìm được m,c,n rồi, ta chỉ cần nạp chúng vào LCG và để nó tự generate private key.
- Source code:
- Flag: CTF{C0nGr@tz_RiV35t_5h4MiR_nD_Ad13MaN_W0ulD_b_h@pPy}
Primes
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
- Tóm tắt đề:
- Đầu tiên, chuỗi bytes m sẽ được đưa vào hàm
to_bits
để đưa về chuỗi nhị phân bằng cách mỗi ký tự trong plaintext được đổi ra chuỗi nhị phân 7 bits theo thứ tự little edian và nối lại.
- Số p chính là dãy gồm
7*len(flag) = 518
số nguyên tố đầu tiên, số bound trong hàm next_primes
là tích của 131 số nguyên tố cuối cùng trong p, còn q là số nguyên tố nhỏ nhất lớn hơn bound (từ đó ta thấy p,q cố định do không phụ thuộc vào flag).
- Tiếp theo hàm
prod_exp
sẽ tính x bằng cách lấy tích các p[i]^b[i]
rồi mod q với b = to_bits(m)
.
- Ở đây do có 1 phần plaintext đã biết nên mình sẽ làm các thao tác y như đề bài đã làm với plaintext, ta sẽ thu được số k (
k = prod_exp(p,q,to_bits(known_text))
)
- Tới đây mình nhận ra
k * prod_exp(p,q, to_bits(unknown_text)) = x mod q
, do đó mình sẽ tính để tính giá trị kia, nhưng thực ra nó không phải giá trị ta muốn tìm :') mà nó chỉ là đồng dư với giá trị cần tìm. Giả sử kết quả phép toán trên là tmp, ta cần tìm giá trị của ct = prod_exp(p,q, to_bits(unknown_text))
, ta có:
- (1)(như đã nói ở trên)
- ct là ước của maxx với maxx là tích của
7*len(unknow_text)
số nguyên tố cuối cùng trong p, điều này được suy ra bởi ct là một subset product của list các số nguyên tố trên. Do đó
- Nhân vào 2 vế của (1) với t, ta được . Sau khi tìm được t, mình dễ dàng tìm được
ct = maxx // t
- Việc tìm trên cũng có khả năng ra kết quả không như mong muốn (cũng vì tìm nghiệm trong phương trình đồng dư có thể cho nhiều đáp án), tuy nhiên khi tính được giá trị ct mình đã check lại 2 điều kiện trên và nó pass :)) do đó việc ta phải làm bây giờ là khôi phục lại chuỗi bits và tìm plaintext thôi.
- solve.sage
- Flag: CTF{w0W_c0Nt1nUed_fr4Ct10ns_suR3_Ar3_fUn_Huh}
Bài này mình làm ra nhờ vào may mắn là nhiều :D. Có lẽ tác giả ra bài này mong muốn người chơi sử dụng kiến thức của "continued fraction" (thông qua việc đề cập trong flag). Có thể trong tương lai gần, mình sẽ update thêm cách làm mới cho bài này :p
Official write-up: https://github.com/google/google-ctf/tree/master/2023/quals/crypto-primes/solution