MrQuậy
Well-Known Member
-
24/09/2013
-
178
-
2.221 bài viết
Tấn công CRIME lên các giao dịch web sử dụng bộ giao thức SSL/TLS
CRIME (Compression Ratio Info-Leak Made Easy hay Compression Ratio Info-Leak Mass Exploitation) tấn công lên bộ giao thức SSL/TLS được phát triển và công bố bởi hai nhà nghiên cứu Julliano Rizzo và Dương Ngọc Thái. CRIME là kiểu tấn công kênh kề sử dụng để khôi phục khóa phiên (token) của một phiên liên lạc hoặc thông tin bí mật khác dựa trên kích thước nén của các yêu cầu HTTP (HTTP request). Đây là kỹ thuật khai thác các phiên liên lạc web được bảo vệ bởi bộ giao thức SSL/TLS sử dụng một trong hai phương pháp nén dữ liệu (DEFLATE và gzip) nhằm làm giảm hiện tượng tắc nghẽn mạng hoặc thời gian tải của trang web.
Hai nhà nghiên cứu đã trình bày hình thức tấn công này tại hội nghị bảo mật Ekoparty vào tháng 9 năm 2012 sau khi thông báo cho các công ty phần mềm lớn bị ảnh hưởng là Mozilla và Google (CVE-2012-4929). CRIME được biết đến như hình thức tấn công chống lại hàm nén trong SSL/TLS và SPDY.
Hình 1: Sơ đồ tấn công CRIME
Hai nhà nghiên cứu đã trình bày hình thức tấn công này tại hội nghị bảo mật Ekoparty vào tháng 9 năm 2012 sau khi thông báo cho các công ty phần mềm lớn bị ảnh hưởng là Mozilla và Google (CVE-2012-4929). CRIME được biết đến như hình thức tấn công chống lại hàm nén trong SSL/TLS và SPDY.
Hình 1: Sơ đồ tấn công CRIME
1. Phương pháp tấn công và khai thác lỗ hổng
Phương pháp nén là cơ chế truyền và lưu trữ cùng một lượng dữ liệu trong một số bit, phương pháp nén chính được sử dụng trong TLS để nén dữ liệu là DEFLATE. DEFLATE chứa hai thuật toán con là mã Lempel-Ziv (LZ77) và mã Huffman. LZ77 được sử dụng để loại bỏ các chuỗi lặp đi lặp lại, trong khi đó mã Huffman được sử dụng để loại bỏ các ký tự lặp lại nhiều lần. Hàm nén này quét các giá trị đầu vào, tìm kiếm các chuỗi lặp đi lặp lại và thay thế bằng các thông số xuất hiện trước đó như khoảng cách, độ dài rồi nén nội dung trong một chuỗi có định dạng là zlib. Một trong các thông số quan trọng trong kỹ thuật nén này là kích thước cửa sổ (window size), nhận giá trị trong khoảng từ 1 đến 15, được biểu diễn dưới dạng bit. Kích thước cửa sổ càng cao thì tỷ lệ nén càng cao. Giới hạn của khoảng cách là 32Kb và độ dài chuỗi được giới hạn trong 258 byte.
Trong quá trình làm việc với giao thức TLS, cụ thể là trong thông báo ClientHello, phía người dùng (client) liệt kê danh sách các thuật toán nén được hỗ trợ (ở đây chỉ thảo luận hàm nén TLS và SPDY, không xem xét hàm nén HTTP). Trong thông báo ServerHello, máy chủ (server) trả lời thuật toán nén sẽ được sử dụng. Các thuật toán nén được mô tả bởi các định dạnh một byte (one-byte identifier). Khi sử dụng hàm nén TLS, nó được áp dụng đối với tất cả các dữ liệu được truyền tải như một chuỗi dài. Cụ thể, khi sử dụng với HTTP, hàm nén được áp dụng với tất cả các HTTP yêu cầu liên tục trong chuỗi bao gồm cả phần thông tin đầu tiên của gói tin (header). CRIME là một hình thức tấn công vét cạn bằng cách tận dụng một đặc tính của hàm nén và dựa vào đó để thay đổi độ dài của dữ liệu được nén. Các thành phần bên trong hàm nén phức tạp hơn nhiều nhưng ví dụ đơn giản sau có thể chỉ ra cách khai thác thông tin bị rò rỉ.
Giả sử một HTTP yêu cầu từ client có cấu trúc như sau:
Hình 2: HTTP request của client
Phương pháp nén là cơ chế truyền và lưu trữ cùng một lượng dữ liệu trong một số bit, phương pháp nén chính được sử dụng trong TLS để nén dữ liệu là DEFLATE. DEFLATE chứa hai thuật toán con là mã Lempel-Ziv (LZ77) và mã Huffman. LZ77 được sử dụng để loại bỏ các chuỗi lặp đi lặp lại, trong khi đó mã Huffman được sử dụng để loại bỏ các ký tự lặp lại nhiều lần. Hàm nén này quét các giá trị đầu vào, tìm kiếm các chuỗi lặp đi lặp lại và thay thế bằng các thông số xuất hiện trước đó như khoảng cách, độ dài rồi nén nội dung trong một chuỗi có định dạng là zlib. Một trong các thông số quan trọng trong kỹ thuật nén này là kích thước cửa sổ (window size), nhận giá trị trong khoảng từ 1 đến 15, được biểu diễn dưới dạng bit. Kích thước cửa sổ càng cao thì tỷ lệ nén càng cao. Giới hạn của khoảng cách là 32Kb và độ dài chuỗi được giới hạn trong 258 byte.
Trong quá trình làm việc với giao thức TLS, cụ thể là trong thông báo ClientHello, phía người dùng (client) liệt kê danh sách các thuật toán nén được hỗ trợ (ở đây chỉ thảo luận hàm nén TLS và SPDY, không xem xét hàm nén HTTP). Trong thông báo ServerHello, máy chủ (server) trả lời thuật toán nén sẽ được sử dụng. Các thuật toán nén được mô tả bởi các định dạnh một byte (one-byte identifier). Khi sử dụng hàm nén TLS, nó được áp dụng đối với tất cả các dữ liệu được truyền tải như một chuỗi dài. Cụ thể, khi sử dụng với HTTP, hàm nén được áp dụng với tất cả các HTTP yêu cầu liên tục trong chuỗi bao gồm cả phần thông tin đầu tiên của gói tin (header). CRIME là một hình thức tấn công vét cạn bằng cách tận dụng một đặc tính của hàm nén và dựa vào đó để thay đổi độ dài của dữ liệu được nén. Các thành phần bên trong hàm nén phức tạp hơn nhiều nhưng ví dụ đơn giản sau có thể chỉ ra cách khai thác thông tin bị rò rỉ.
Giả sử một HTTP yêu cầu từ client có cấu trúc như sau:
Hình 2: HTTP request của client
Độ lớn của nội dung yêu cầu được tính bằng . Mặc dù nội dung đã được mã hóa, nhưng độ dài nội dung được nén có thể bị nghe trộm.
Hình 3: SSL/TLS không ẩn độ dài request/response
Kẻ tấn công biết được rằng client sẽ gửi đi giá trị “Cookie: secrectcookie=” và hy vọng sẽ thu được giá trị bí mật đó. Vì vậy, bằng cách thay đổi đoạn mã JavaScript, kẻ tấn công gửi một yêu cầu có chứa nội dung “Cookie: secrectcookie=0” trong chuỗi truy vấn. Do đó, HTTP yêu cầu từ kẻ tấn công sẽ có cấu trúc như sau:
Hình 4: HTTP request của client đã bị kẻ tấn công thay đổi
Trong yêu cầu bị thay đổi, đầu vào có chứa dữ liệu bị kẻ tấn công kiểm soát, tức là “secretcookie=0” và là một phần của yêu cầu. Do thừa giá trị secretcookie, nên độ dài sau khi nén sẽ nhỏ hơn, nếu dữ liệu bị kẻ tấn công kiểm soát không phù hợp với bất cứ chuỗi ký tự nào tồn tại trong yêu cầu, (ý tưởng tấn công ở đây là thay đổi đầu vào, đo và so sánh các giá trị độ dài để đoán giá trị bí mật).
Khi hàm nén xử lý yêu cầu, sẽ nhận ra các chuỗi “secretcookie=” lặp lại, hàm nén phải phát thêm một dấu hiệu có giá trị bằng “0”. Kẻ tấn công thử lại lần nữa với “secretcookie=1” trong tiêu đề yêu cầu, sau đó là “secretcookie=2” và cứ tiếp tục như thế. Tất cả các yêu cầu này sẽ được nén với cùng một kích cỡ, ngoại trừ yêu cầu chứa “secretcookie=7” với khả năng nén tốt hơn (16 byte của chuỗi lặp lại được thay thế bởi 15 byte), do đó độ dài nội dung yêu cầu sẽ ngắn hơn một byte. Yêu cầu với giá trị cookie bắt đầu bằng “7” được nén tốt hơn là một dấu hiệu cho thấy rằng “7” là ký tự đầu tiên của giá trị secretcookie. Do đó sau một vài yêu cầu, kẻ tấn công có thể đoán được byte thứ nhất của giá trị bí mật. Lặp lại quá trình này (secretcookie=70,secretcookie=71,…), kẻ tấn công có thể thu được từng byte của giá trị cookie bí mật hoàn chỉnh.
Hình 5: Tấn công CRIME thực hiện tại một bên liên lạc
Kích cỡ lớn nhất của một bản ghi TLS là 16 Kb. Khi một bản ghi có kích cỡ lớn hơn 16 Kb, TLS sẽ chia bản ghi đó thành những bản ghi riêng rẽ và nén chúng riêng biệt. Nếu kẻ tấn công biết được vị trí của giá trị cookie bí mật, thì bằng cách chèn thêm phần đệm thích hợp vào đường dẫn của yêu cầu, kẻ tấn công sẽ bắt TLS chia yêu cầu sao cho bản ghi thứ nhất chứa duy nhất 1 byte chưa biết. Trong mỗi lần kẻ tấn công có thể tìm thấy một kết quả phù hợp, sau đó loại bỏ 1 byte của phần đệm thêm vào, và khi đó TLS tiếp tục chia bản ghi sao cho nó chỉ chứa 1 byte chưa biết trong bản ghi thứ nhất và cứ lặp lại như vậy sẽ tìm được trọn vẹn giá trị cookie bí mật.
Hình 6: Chia tách bản ghi sử dụng giá trị biên đã lựa chọn
Cách tấn công trên có thể được tối ưu hóa. Nếu giá trị cookie bí mật dựa trên hệ cơ số 64, tức là có 64 giá trị phù hợp ứng với mỗi kí tự chưa biết, kẻ tấn công có thể làm một yêu cầu chứa 32 bản sao chép của “Cookie:secretcookie=X” (có 32 phương án dành cho 1 ký tự X). Nếu một trong số kết quả là giá trị thực của cookie thì tổng độ dài bản ghi sẽ nhỏ hơn. Mỗi lần kẻ tấn công có thể biết được một nửa số ký tự alphabet là thành phần của những byte chưa biết, kẻ tấn công thử lại lần nữa với 16/16 tách ra và tiếp diễn như thế… Trong sáu yêu cầu, sẽ tìm được giá trị của những byte chưa biết (bởi vì ).
2. Giải pháp khắc phục và ngăn chặn tấn công
Do tấn công CRIME khai thác thuật toán nén, nên cách dễ dàng nhất để ngăn chặn CRIME là vô hiệu hóa hàm nén TLS. Giải pháp này dễ dàng thực hiện bằng cách áp dụng một bản vá SPDY ở cả máy chủ và máy khách. Trình duyệt cần phải thực hiện nâng cấp phiên bản mới nhất giúp giảm thiểu thiệt hại cho người sử dụng giải pháp này.
Từ phía máy chủ, cần thay đổi tập tin php.ini như sau:
zlib.output_compression = Off
echo “exportOPENSSL_NO_DEFAULT_ZLIB=1” >>/etc/apache2/httpd.conf
Để phát hiện tấn công CRIME hướng đến máy chủ, ta sẽ thực hiện câu lệnh openssl:
$ echo GET | openssl s_client -connect mobivi.vn:443 -state-showcerts
Hình 7: Phát hiện tấn công CRIME trong máy chủ
Như vậy, cả hai trình duyệt Chrome và Firefox đều đã vô hiệu hóa hàm nén TLS (và hàm nén SPDY nếu sử dụng) trong trình duyệt của mình cũng như các gói phần mềm máy chủ khác sau tấn công CRIME, được thực hiện bởi Rizzo và Dương Ngọc Thái.
Tài liệu tham khảo
1. Pratik Guha Sarkar, Shawn Fitzgerald, Attacks on SSL – A comprehensive study of BEAST, CRIME, TIME, BREACH, LUCKY 13 & RC4 BIASES, https://www.isecpartners.com, 2013.
2. C. Meyer, 20 Years of SSL/TLS Research An Analysis of the Internet’s Security Foundation, 2014.
3. G. V. Bard, The Vulnerability of SSL to Chosen Plaintext Attack, IACR Cryptology ePrint Archive, 2004.
4 P. Deutsch, DEFLATE Compressed Data Format Specification version 1.3, RFC 1951, IETF, 1996.
Hình 3: SSL/TLS không ẩn độ dài request/response
Kẻ tấn công biết được rằng client sẽ gửi đi giá trị “Cookie: secrectcookie=” và hy vọng sẽ thu được giá trị bí mật đó. Vì vậy, bằng cách thay đổi đoạn mã JavaScript, kẻ tấn công gửi một yêu cầu có chứa nội dung “Cookie: secrectcookie=0” trong chuỗi truy vấn. Do đó, HTTP yêu cầu từ kẻ tấn công sẽ có cấu trúc như sau:
Hình 4: HTTP request của client đã bị kẻ tấn công thay đổi
Trong yêu cầu bị thay đổi, đầu vào có chứa dữ liệu bị kẻ tấn công kiểm soát, tức là “secretcookie=0” và là một phần của yêu cầu. Do thừa giá trị secretcookie, nên độ dài sau khi nén sẽ nhỏ hơn, nếu dữ liệu bị kẻ tấn công kiểm soát không phù hợp với bất cứ chuỗi ký tự nào tồn tại trong yêu cầu, (ý tưởng tấn công ở đây là thay đổi đầu vào, đo và so sánh các giá trị độ dài để đoán giá trị bí mật).
Khi hàm nén xử lý yêu cầu, sẽ nhận ra các chuỗi “secretcookie=” lặp lại, hàm nén phải phát thêm một dấu hiệu có giá trị bằng “0”. Kẻ tấn công thử lại lần nữa với “secretcookie=1” trong tiêu đề yêu cầu, sau đó là “secretcookie=2” và cứ tiếp tục như thế. Tất cả các yêu cầu này sẽ được nén với cùng một kích cỡ, ngoại trừ yêu cầu chứa “secretcookie=7” với khả năng nén tốt hơn (16 byte của chuỗi lặp lại được thay thế bởi 15 byte), do đó độ dài nội dung yêu cầu sẽ ngắn hơn một byte. Yêu cầu với giá trị cookie bắt đầu bằng “7” được nén tốt hơn là một dấu hiệu cho thấy rằng “7” là ký tự đầu tiên của giá trị secretcookie. Do đó sau một vài yêu cầu, kẻ tấn công có thể đoán được byte thứ nhất của giá trị bí mật. Lặp lại quá trình này (secretcookie=70,secretcookie=71,…), kẻ tấn công có thể thu được từng byte của giá trị cookie bí mật hoàn chỉnh.
Hình 5: Tấn công CRIME thực hiện tại một bên liên lạc
Kích cỡ lớn nhất của một bản ghi TLS là 16 Kb. Khi một bản ghi có kích cỡ lớn hơn 16 Kb, TLS sẽ chia bản ghi đó thành những bản ghi riêng rẽ và nén chúng riêng biệt. Nếu kẻ tấn công biết được vị trí của giá trị cookie bí mật, thì bằng cách chèn thêm phần đệm thích hợp vào đường dẫn của yêu cầu, kẻ tấn công sẽ bắt TLS chia yêu cầu sao cho bản ghi thứ nhất chứa duy nhất 1 byte chưa biết. Trong mỗi lần kẻ tấn công có thể tìm thấy một kết quả phù hợp, sau đó loại bỏ 1 byte của phần đệm thêm vào, và khi đó TLS tiếp tục chia bản ghi sao cho nó chỉ chứa 1 byte chưa biết trong bản ghi thứ nhất và cứ lặp lại như vậy sẽ tìm được trọn vẹn giá trị cookie bí mật.
Hình 6: Chia tách bản ghi sử dụng giá trị biên đã lựa chọn
Cách tấn công trên có thể được tối ưu hóa. Nếu giá trị cookie bí mật dựa trên hệ cơ số 64, tức là có 64 giá trị phù hợp ứng với mỗi kí tự chưa biết, kẻ tấn công có thể làm một yêu cầu chứa 32 bản sao chép của “Cookie:secretcookie=X” (có 32 phương án dành cho 1 ký tự X). Nếu một trong số kết quả là giá trị thực của cookie thì tổng độ dài bản ghi sẽ nhỏ hơn. Mỗi lần kẻ tấn công có thể biết được một nửa số ký tự alphabet là thành phần của những byte chưa biết, kẻ tấn công thử lại lần nữa với 16/16 tách ra và tiếp diễn như thế… Trong sáu yêu cầu, sẽ tìm được giá trị của những byte chưa biết (bởi vì ).
2. Giải pháp khắc phục và ngăn chặn tấn công
Do tấn công CRIME khai thác thuật toán nén, nên cách dễ dàng nhất để ngăn chặn CRIME là vô hiệu hóa hàm nén TLS. Giải pháp này dễ dàng thực hiện bằng cách áp dụng một bản vá SPDY ở cả máy chủ và máy khách. Trình duyệt cần phải thực hiện nâng cấp phiên bản mới nhất giúp giảm thiểu thiệt hại cho người sử dụng giải pháp này.
Từ phía máy chủ, cần thay đổi tập tin php.ini như sau:
zlib.output_compression = Off
echo “exportOPENSSL_NO_DEFAULT_ZLIB=1” >>/etc/apache2/httpd.conf
Để phát hiện tấn công CRIME hướng đến máy chủ, ta sẽ thực hiện câu lệnh openssl:
$ echo GET | openssl s_client -connect mobivi.vn:443 -state-showcerts
Hình 7: Phát hiện tấn công CRIME trong máy chủ
Như vậy, cả hai trình duyệt Chrome và Firefox đều đã vô hiệu hóa hàm nén TLS (và hàm nén SPDY nếu sử dụng) trong trình duyệt của mình cũng như các gói phần mềm máy chủ khác sau tấn công CRIME, được thực hiện bởi Rizzo và Dương Ngọc Thái.
Tài liệu tham khảo
1. Pratik Guha Sarkar, Shawn Fitzgerald, Attacks on SSL – A comprehensive study of BEAST, CRIME, TIME, BREACH, LUCKY 13 & RC4 BIASES, https://www.isecpartners.com, 2013.
2. C. Meyer, 20 Years of SSL/TLS Research An Analysis of the Internet’s Security Foundation, 2014.
3. G. V. Bard, The Vulnerability of SSL to Chosen Plaintext Attack, IACR Cryptology ePrint Archive, 2004.
4 P. Deutsch, DEFLATE Compressed Data Format Specification version 1.3, RFC 1951, IETF, 1996.
ThS. Nguyễn Thanh Sơn CN. Nguyễn Thị Tuyết Trinh Học viện kỹ thuật Mật mã, Ban CYCP