nc 103.69.194.137 6000
Source code
chall.py
Đọc qua source code có thể thấy Flag chỉ gồm kí tự chữ cái hoa,thường + kí tự số và !_{}
Flag được pad cho đủ khối rồi đem đi mã hóa bằng AES mode CBC
Vì IV và key đều random ,nên chúng ta không thể biết cũng không thể vét cạn .Brute forcing key của AES-128 là một nhiệm vụ rất khó khăn và tốn nhiều thời gian. Vì AES-128 sử dụng một khóa độ dài 128 bit, có tổng cộng 2^128 khóa khả dĩ. Điều này có nghĩa là số lượng khóa có thể có của AES-128 là rất lớn và khó có thể tìm ra khóa đúng bằng cách thử và sai một cách ngẫu nhiên.
Thời gian cần thiết để brute force một khóa AES-128 tùy thuộc vào số lượng khóa mà bạn muốn thử trong một giây, còn được gọi là "tốc độ thử". Nếu bạn có một tốc độ thử khóa rất nhanh, ví dụ như một triệu khóa mỗi giây, thì thời gian brute force để tìm ra khóa đúng có thể chỉ mất khoảng vài triệu năm.
Tuy nhiên, trong thực tế, việc brute force khóa AES-128 rất khó và thường được coi là không khả thi bởi vì một tốc độ thử khóa nhanh như vậy không thể đạt được bằng các phương pháp hiện tại của máy tính.
Vì không thể tìm được key nên không thể khái thác theo hướng này.Trong hàm decrypt có phần sử dụng để xác thực phần padding.Phần padding sẽ có dạng:
Sau một thời gian tìm kiếm,mình tìm được một kiểu tấn công có tên là Padding oracle attack
Trong mật mã đối xứng, cuộc tấn công oracle đệm có thể được áp dụng cho chế độ hoạt động CBC, trong đó "oracle" (thường là máy chủ) rò rỉ dữ liệu về việc liệu phần đệm của tin nhắn được mã hóa có chính xác hay không. Dữ liệu như vậy có thể cho phép những kẻ tấn công giải mã (và đôi khi mã hóa) tin nhắn thông qua oracle bằng cách sử dụng khóa của oracle mà không cần biết khóa mã hóa.
Việc triển khai tiêu chuẩn của giải mã CBC trong mật mã khối là giải mã tất cả các khối bản mã, xác thực phần đệm, xóa phần đệm PKCS7 và trả về văn bản thuần túy của tin nhắn. Nếu máy chủ trả về lỗi "đệm không hợp lệ" thay vì lỗi chung "giải mã không thành công", kẻ tấn công có thể sử dụng máy chủ như một oracle đệm để giải mã (và đôi khi mã hóa) message.
Công thức toán học để giải mã CBC là
= ,
=
Sau 7749 lần search tung gg để tìm code tấn công ,mình tìm được kha khá code Padding Oracle attack ,nhưng khi chạy thì nó lạ lắm :))
Bản chất của Padding Oracle attack là sửa đổi byte cuối cùng của khối bản mã trước đó, chúng ta có thể thay đổi byte cuối cùng của khối bản rõ cuối cùng.
Liệt kê 256 byte, chúng ta có thể tìm thấy thời điểm khi last_plain_text = 1. Oracle sẽ không báo lỗi trong trường hợp này, vì đó sẽ là phần đệm hợp lệ. Bằng cách quan sát thực tế đó, chúng ta có thể kết luận rằng X XOR last_byte_from_encryption_function = 1. Hoặc, last_byte_from_encryption_function = X XOR 1. Và điều này không cần biết khóa! Đây là một thực tế rất quan trọng vì bây giờ chúng ta có thể giải mã last plaintext byte, đó là: last_byte_from_encryption_function XOR original_last_byte_from_previous_ciphertext_block. Một lần nữa, sử dụng thông tin này, chúng ta có thể thay đổi byte cuối cùng từ khối bản mã trước đó sao cho byte cuối cùng của bản rõ của khối cuối cùng sẽ là 2. Và liệt kê tất cả các byte cuối cùng có thể có. Sử dụng phương pháp này, tất cả 16 byte plaintext có thể được khôi phục bằng cách sử dụng tối đa 256*16=4096 lệnh gọi tới 'oracle' .
Sau 1 khi chạy thử khác nhiều đoạn code khác nhau bug và fix bug cả tỉ lần vẫn không được,nhưng vẫn kiên trì không bỏ cuộc mình đã tìm được 1 trang cung cấp mã Padding Oracle attack chạy được và mình đã modify để solve challenge này ,rất may là đã chạy thành công :))
Trong qua trình giải mã plaintext chúng ta sẽ bắt đầu từ khối cuối cùng ,ở challenge này khi gửi option encrypt
chúng ta sẽ nhận được 1 dãy hex dài 96 kí tự (48 byte),trong đó 16 byte đầu là IV,còn lại là ciphertext .
Chia ra thành 2 block(16 byte mỗi cái),sau đó sẽ tiến hành giải mã từ khối cuối cùng đầu tiên ,các khối sau đó tiếp tục ,nhưng ở đây chỉ có 2 block thôi.
Ta sẽ thay thế từng byte cuối trong khối lần lượt từ 0 đến 255 (tương đương 00 đến ff).Sau đó gửi khối mã đã sửa lại cho oracle .Hàm check_padding sẽ dùng hàm decrypt để xác thực xem phần pad có đúng không và sẽ khôi phục plaintext theo từng byte một,từ cuối trở về đầu.
Dưới đây là script ,vì đoạn mã tương đối phức tạp ,tên biến khá dài rối mắt nên mình sẽ giữ nguyên comment của tác giả cho dễ hiểu.
Sau khi chạy vài phút thu được kết quả:
Để thu được bản gốc 32 bytes oracle được gọi 3754 lần.
Flag: KCSC{Pudd1n9_M1r4cl3_5naCk}