Cấp bậc tác giả:

NETWORKING

BEAST: Một phương pháp tấn công HTTPS mới

Được viết bởi webmaster ngày 25/10/2013 lúc 10:05 PM
Bây giờ nhắc đến Netscape chắc ít người còn nhớ, nhưng trong giai đoạn đầu của cuộc cách mạng World Wide Web hồi giữa những năm 1990, Netscape có vị thế như Google hay Facebook bây giờ.
  • 0
  • 1778

BEAST: Một phương pháp tấn công HTTPS mới


1. Giới thiệu

Bây giờ nhắc đến Netscape chắc ít người còn nhớ, nhưng trong giai đoạn đầu của cuộc cách mạng World Wide Web hồi giữa những năm 1990, Netscape có vị thế như Google hay Facebook bây giờ. Rồi cuộc chiến trình duyệt lần thứ nhất nổ ra và Netscape là kẻ bại trận dưới tay gã khổng lồ Microsoft. Từ chỗ chiếm hơn 90% thị phần trình duyệt với sản phẩm chủ lực Netscape Navigator, Netscape giờ đây không còn được mấy ai biết đến. Dẫu vậy di sản mà họ để lại vẫn rất vĩ đại.

Netscape tạo nên Mozilla và đóng góp mã nguồn vào các phiên bản trình duyệt đầu tiên của tổ chức này. Javascript, ngôn ngữ lập trình được sử dụng phổ biến nhất trên WWW, cũng là một sản phẩm của Netscape. Vậy thì Netscape có liên quan gì đến tiêu đề của bài viết này? Secure Socket Layer (SSL), bộ giao thức giữ vai trò quyết định cho sự hình thành và phát triển của thương mại điện tử, nói không ngoa cũng là niềm hi vọng của cả thế giới về sự an toàn và riêng tư trên Internet, cũng được tạo ra ở Netscape.

Netscape làm xong SSL 1.0 từ năm 1994, nhưng phiên bản này chưa bao giờ được công bố. SSL 2.0 được công bố rộng rãi vào tháng Hai năm 1995. Không lâu sau đó người ta phát hiện ra nhiều vấn đề nghiêm trọng với bộ giao thức này nên vào năm 1996, Netscape phát hành SSL 3.0 với nhiều cải tiến nhằm sửa các lỗ hổng ở SSL 2.0. IETF, tổ chức quy định các tiêu chuẩn trên Internet, chuẩn hóa SSL và tạo ra Transportation Layer Security (TLS) và phát hành TLS 1.0 vào năm 1999.


Năm 2002, trong một email với nhan đề “An attack against SSH2 protocol” gửi đến nhóm phát triển OpenSSH, Wei Dai mô tả một tấn công chọn bản rõ (chosen-plaintext attack) vào cơ chế hoạt động CBC (cipher-block chaining) của các mã khối (block cipher). Tấn công của Wei Dai dựa trên một ý kiến của Phillip Rogaway đưa ra từ năm 1995, khi ông bàn về các điểm yếu trong việc sử dụng mật mã của giao thức IPSEC.

Không lâu sau đó, Bodo Möller, lập trình viên của dự án OpenSSL, nhận thấy tấn công của Rogaway-Dai có thể áp dụng được cho giao thức SSL 3.0 và TLS 1.0. Ông đề xuất một giải pháp khá thông minh, tạm gọi là giải pháp OpenSSL (chi tiết tôi sẽ nói sau) và tích hợp giải pháp đó vào phiên bản OpenSSL 0.9.6d phát hành giữa năm 2002. Tuy vậy, do gặp vấn đề về tương thích với trình duyệt Internet Explorer 6 của Microsoft (ai mà không gặp vấn đề này?), nên giải pháp OpenSSL thường bị gỡ bỏ trong các cài đặt của OpenSSL.

Ngoài OpenSSL ra, không một nhà phát triển SSL nào quan tâm đến tấn công Rogaway-Dai, vì ý tưởng này được xem là chỉ có ý nghĩa về mặt lý thuyết. Không ai nghĩ rằng có thể xây dựng được một tấn công thực thụ vào các ứng dụng SSL từ ý tưởng này, ngoại trừ Gregory Bard. Lần lượt trong hai năm, 2004 và 2006, Bard thử áp dụng tấn công Rogaway-Dai vào SSL trong trình duyệt và SSL trong VPN. Mặc dù Bard đã cho thấy được “diện mạo” của tấn công Rogaway-Dai khi áp dụng vào SSL sẽ ra sao, nhưng các tấn công của Bard vẫn không thể áp dụng được trong thực tế (tôi sẽ quay lại điểm này sau).

Trong khi đó, để ngăn chặn triệt để tấn công Rogaway-Dai, IETF quyết định chỉnh sửa TLS 1.0 và phát hành TLS 1.1 vào năm 2006. Đây là một điều chỉnh lớn, bởi vì TLS 1.1 (và TLS 1.2) không tương thích với TLS 1.0 và SSL 3.0. Đối với IETF, tấn công Rogaway-Dai, tồn tại trong hơn 11 năm từ những phiên bản đầu tiên của SSL, xem như là đã được giải quyết rốt ráo. Cho đến khi B.E.A.S.T được giới thiệu trong thời gian gần đây.

BEAST áp dụng Rogaway-Dai để tấn công vào giao thức HTTPS. Nếu như trước đây các tấn công vào HTTPS vốn chỉ tập trung vào việc khai thác điểm yếu của hạ tầng khóa công khai/chứng chỉ số thì BEAST thực sự giải mã các yêu cầu mà trình duyệt gửi đến máy chủ xuyên qua HTTPS, rồi lấy trộm các bánh quy HTTP (HTTP cookie). Trong số các ý kiến bình luận về BEAST, tôi thích nhất ý kiến của Karsten Nohl:

The TLS exploit is a neat fusion of two streams in vulnerability research: Cryptanalysis and client-side attacks. In this case, a known client-side problem–namely (that) Web sites are not shielded from one another–is used to break an assumption in cryptography–that a user’s computer will not attack the user.

Users already need to trust all the Web sites they are visiting due to vulnerabilities in their browsers (“drive-by exploits”) and in trusted Web sites (“tab-nabbing”). The new exploit strongly reminds us of this rule.

BEAST chỉ ra rằng: do tính chất liên kết của Web, rất dễ để thực hiện tấn công chọn bản rõ vào HTTPS. Một website bất kỳ có thể khiến trình duyệt của bạn mở một kết nối HTTPS đến một website khác và trong các kết nối đó, kẻ tấn công kiểm soát được phần lớn nội dung. Nói cách khác, BEAST có thể dễ dàng biến trình duyệt thành một encryption oracle, rồi cứ lần lượt gửi bản rõ vào, quan sát bản mã và lập lại (adaptive chosen-plaintext attack). Trong video trình diễn dưới đây, BEAST sẽ giải mã các yêu cầu HTTPS để lấy các bánh quy HTTP và từ đó truy cập vào tài khoản PayPal của nạn nhân.


2. CBC – Tấn công Rogaway-Dai

2.1 CBC

Trong định nghĩa của mỗi mã khối (block cipher) đều có một thuật toán mã hóa nhận vào một khối bản rõ (plaintext block) có chiều dài b bit (gọi là chiều dài khối – block size) và một khóa có chiều dài n bit, rồi “nhào trộn” bản rõ và khóa lại với nhau để xuất ra một khối bản mã (ciphertext block) có b bit. Ví dụ như thuật toán mã hóa của mã khối nổi tiếng DES nhận vào một khối bản rõ có chiều dài 64 bit và một khóa có chiều dài 56 bit, rồi xuất ra một khối bản mã có chiều dài 64 bit. Vì lý do an toàn, các mã khối hiện đại thường có b = 128 và n >= 128, ví dụ như AES-128, AES-192, AES-256 (con số phía sau là chiều dài khóa; tất cả đều có chiều dài khối là 128 bit). Câu hỏi tự nhiên là mã hóa thế nào nếu bản rõ dài hơn b? Chẳng hạn như tôi cần phải làm sao nếu muốn dùng AES-128 để mã hóa bài viết này, vốn chắc chắn dài hơn 128 bit?

Để giải quyết vấn đề này, người ta dùng một phương thức hoạt động (mode of operation) của mã khối. Lưu ý rằng cùng một phương thức hoạt động có thể sử dụng cho nhiều mã khối khác nhau và ngược lại. Mỗi phương thức hoạt động sẽ định nghĩa hai thuật toán: mã hóa và giải mã. Các thuật toán này sẽ sử dụng mã khối và một khóa duy nhất để mã hóa/giải mã các khối dữ liệu có chiều dài lớn hơn b.  Có nhiều phương thức hoạt động, phổ biến nhất là Electronic Code Book (ECB) và Cipher Block Chaining (CBC). Để mã hóa bằng ECB hay CBC, chúng ta cần phải thực hiện hai bước:


Nếu chiều dài bản rõ không chia hết cho chiều dài khối thì đệm thêm (pad) một số byte vào bản rõ (padding bytes) để tổng chiều dài chia hết cho b. Có nhiều cách đệm, phổ biến nhất là đệm theo chuẩn PKCS #5.
Chia bản rõ ra thành từng khối và mã hóa theo thuật toán quy định trong phương thức hoạt động. Tôi sẽ đi vào chi tiết bước này trong cả hai phương thức ECB và CBC ngay bên dưới.
Điều thú vị là cả hai thao tác này đều đã tạo ra những tấn công rất nghiêm trọng vào các ứng dụng của mã khối trong thực tế. Ví dụ như đối với bước thứ nhất, ở Eurocrypt 2002 Serge Vaudenay đã trình bày tấn công padding oracle, một tấn công chọn bản mã (chosen-ciphertext attack) cho phép kẻ tấn công có thể giải mã bất kỳ bản mã nào, chỉ với một điều kiện là nạn nhân tiết lộ kết quả gỡ đệm trong quá trình giải mã. Sau Vaudenay, đã có rất nhiều nghiên cứu khác về tấn công padding oracle. Tôi và một đồng nghiệp cũng có hai nghiên cứu về đề tài này. Tuy vậy, BEAST không phải là một tấn công padding oracle, nên từ đây về sau chúng ta xem như các bản rõ đều đã được thêm đệm cho phù hợp.

Tôi dùng một số ký hiệu sau đây cho phần còn lại của loạt bài này:

Bản rõ được ký hiệu là M, bản mã là C. Bản rõ được chia ra thành m khối P_1, P_2,…,P_m. Các khối này sẽ được mã hóa thành C_1, C_2,…,C_m.
Hàm mã hóa của mã khối là E_k, trong đó k là khóa. Tương ứng, hàm giải mã là D_k.
Viết X = {X_1}|{X_2}|\cdots|{X_m} nghĩa là kết nối các khối X_i lại với nhau để tạo ra khối X.
Vector khởi tạo (initialization vector) được ký hiệu là IV.
Phương thức hoạt động đơn giản nhất là ECB. ECB mã hóa các khối bản rõ độc lập với nhau, cụ thể như sau:

Mã hóa

\displaystyle \begin{array}{rcl} C_i &=& E_k(P_i), i=1,..,m\\ C &=& C_1|C_2|\cdots|C_m \end{array} 

Giải mã

\displaystyle \begin{array}{rcl} P_i &=& D_k(C_i), i=1,..,m\\ M &=& P_1|P_2|\cdots|P_m \end{array} 

Phương thức mã hóa độc lập này có một tính chất: các khối bản rõ giống nhau sẽ cho kết quả là các khối bản mã giống nhau. Nói cách khác, so sánh giá trị của C_i và C_j với i, j bất kỳ chúng ta có thể biết được một chút “thông tin” về P_i và P_j. Đây là một tính chất không mong muốn của bất kỳ phương thức hoạt động hay hệ mã nào (bởi vì nó làm cho hệ mã không còn an toàn theo định nghĩa semantic security). Điều thú vị là ECB được chọn là phương thức mặc định trong nhiều thư viện lập trình phổ biến.

Bài tập 1: Quân ta đang ở chiến trường. Mỗi ngày bộ chỉ huy sẽ gửi ra một lệnh cho biết hôm đó quân ta sẽ làm gì. Chỉ có hai lệnh: “TAN CONG” hoặc “PHONG THU”. Do quân địch cũng có thể nghe lén sóng radio, nên để cho an toàn, bộ chỉ huy sử dụng ECB để mã hóa các lệnh trước khi gửi. Tất cả các lệnh đều được mã hóa bằng cùng một khóa duy nhất. Chứng minh rằng ngay trong ngày thứ hai, quân địch đã có thể đoán trước chiến thuật của quân ta.

Bài tập 2: Tìm và liệt kê các thư viện lập trình sử dụng ECB là phương thức hoạt động mặc định. Điểm thưởng: tìm trên Google Code Search các chương trình sử dụng các thư viện này và xem thử có cách nào khai thác điểm yếu của ECB trong các chương trình này hay không.

Vậy làm thế nào để phá vỡ sự độc lập giữa các khối? Làm cho chúng phụ thuộc nhau :-) . Đó cũng là ý tưởng của phương thức CBC. Tên gọi của CBC gợi ý rằng các khối bản mã sẽ được “móc nối” lại với nhau, cụ thể như sau:

Mã hóa

\displaystyle \begin{array}{rcl} C_0 &=& IV\\ C_i &=& E_k(P_i \oplus C_{i-1}), i=1,..,m\\ C &=& C_0|C_1|C_2|\cdots|C_m \end{array} 

Giải mã

\displaystyle \begin{array}{rcl} P_i &=& D_k(C_i) \oplus C_{i-1}, i=1,..,m\\ M &=& P_1|P_2|\cdots|P_m \end{array} 

Lưu ý rằng khi mã hóa bằng CBC, chiều dài bản mã tăng thêm một khối. Khối tăng thêm này là IV, dùng để mã hóa khối bản rõ đầu tiên. Trong CBC, IV không cần được giữ bí mật, nhưng với cùng một khóa thì IV phải độc nhất và không dự đoán được.

Bài tập 3: Giả sử bộ chỉ huy ở bài tập 1 chuyển sang sử dụng CBC. Vì thiếu thiết bị tạo số ngẫu nhiên, bộ chỉ huy quyết định chọn một IV cố định và dùng IV này trong tất cả các lần gửi lệnh. Chứng minh rằng quân địch vẫn có thể đoán trước chiến thuật của quân ta ngay trong ngày thứ hai.

CBC được sử dụng ở rất nhiều ứng dụng của mã khối, trong đó có SSL/TLS. Điểm mấu chốt trong việc sử dụng CBC chính là chọn lựa IV đảm bảo hai tiêu chí ở trên. Rất tiếc người thiết kế SSL/TLS làm sai chỗ này. Bài tập 3 gợi ý rằng, để có IV độc nhất thì nên dùng một bộ tạo số ngẫu nhiên (random number generator). Lưu ý là không phải bộ tạo số nào cũng có thể dùng trong mật mã và hầu hết các bộ tạo số ngẫu nhiên đi kèm theo các ngôn ngữ lập trình đều không an toàn. Có lẽ tôi sẽ viết một bài về đề tài này sau. Quay trở lại giá trị IV. Như vậy trong CBC, mỗi lần mã hóa, chúng ta nên chọn một IV ngẫu nhiên. Câu hỏi là: ngẫu nhiên có bao hàm không dự đoán được? Chắc chắn rồi, bởi nếu đã là ngẫu nhiên thì làm sao mà dự đoán được! Tôi nghĩ sự tồn tại của điểm yếu trong SSL/TLS, tấn công Rogaway-Dai và bây giờ là BEAST đều xuất phát từ chỗ này. Cách mà SSL/TLS chọn các IV để mã hóa các bản ghi (record) khiến các IV này ngẫu nhiên, nhưng lại dự đoán được!

Trong SSL/TLS, dữ liệu từ tầng ứng dụng được chia ra thành từng bản ghi dài không quá 2^{14} byte, rồi các bản ghi này sẽ được mã hóa dùng CBC. Với bản ghi đầu tiên, SSL/TLS sẽ chọn một IV hoàn toàn ngẫu nhiên từ bộ tạo số ngẫu nhiên. Từ bản ghi thứ hai trở đi, SSL/TLS sẽ chọn khối bản mã cuối cùng của bản ghi trước đó làm IV. Ví dụ như bản ghi thứ nhất có 3 khối P_1, P_2, P_3, mã hóa tạo thành 4 khối C_0, C_1, C_2, C_3, thì C_3 sẽ được chọn làm IV cho bản ghi thứ hai. Rồi khối bản mã cuối cùng của bản ghi thứ hai sẽ là IV cho bản ghi thứ ba, v.v. Lưu ý rằng C_3 là hoàn toàn ngẫu nhiên, nhưng nếu như chúng ta biết C_3 trước khi chọn bản ghi thứ hai thì xem như IV của bản ghi thứ hai là dự đoán được. Nói cách khác, IV không dự đoán được nghĩa là chúng ta không thể biết được giá trị của IV trước khi chọn bản rõ.

Vậy chuyện gì sẽ xảy ra nếu chúng ta dự đoán được IV trước khi chọn bản rõ?

2.2 Tấn công Rogaway-Dai

Wei Dai mô tả như sau tấn công này như sau:

Phil Rogaway observed that CBC mode is not secure against chosen-plaintext attack if the IV is known or can be predicted by the attacker before he chooses his plaintext [1]. Similarly, CBC mode is not secure if the attacker can observe the last ciphertext block before choosing the next block of plaintext, because the last block of ciphertext essentially serves as the IV for the rest of the message.

The attack itself is very simple. Remember that in CBC mode, each plaintext block is XOR’ed with the last ciphertext block and then encrypted to produce the next ciphertext block. Suppose the attacker suspects that plaintext block P_i might be x, and wants to test whether that’s the case, he would choose the next plaintext block P_j to the x \oplus C_{i-1} \oplus C_{j-1}. If his guess is correct, then C_j = E_k(P_j \oplus C_{j-1}) = E_k(P_i \oplus C_{i-1}) = C_i, and so he can confirm his guess by looking at whether C_j = C_i.[...]

[1] http://www.cs.ucdavis.edu/~rogaway/papers/draft-rogaway-ipsec-comments-00.txt

Như vậy Dai chỉ ra rằng chúng ta có thể dự đoán được (giải mã!) bản rõ đã quan sát nếu chúng ta biết được IV trước khi chọn bản rõ mới trong CBC. Nếu P_i chỉ nhận 100 giá trị, thì rõ ràng chúng ta có thể giải mã được P_i sau khi thực hiện trung bình 50 bước chọn và thử P_j. Giới hạn của Rogaway-Dai nằm ở chỗ trong thực tế miền giá trị của P_i thường rất lớn. Làm sao để giảm miền giá trị của P_i?

Nguồn bài viết: procul

BÌNH LUẬN BÀI VIẾT

Bài viết mới nhất

LIKE BOX

Bài viết được xem nhiều nhất

HỌC HTML