Một trong những cuộc tấn công mật mã gần đây nhất được công bố vào tháng 12/2017 được 3 nhà mật mã học Hanno Böck, Juraj Somorovsky, Craig Young tìm ra được biết với tên gọi Return Of Bleichenbacher's Oracle Threat, viết tắt là ROBOT attack. Tấn công này ảnh hưởng tới nhiều  sản phẩm của  các hãng công nghệ lớn như F5, Citrix, Cisco và cả Facebook.

Tấn công ROBOT là một biến thể của cuộc tấn công  Bleichenbacher trên giao thức sử dụng mã hoá RSA, cho phép kẻ tấn công có thể giải mã được thông điệp mà không cần khoá bí mật. Để có thể hiểu được cuộc tấn công này cần phải biết đến các khái niệm như RSA, PKCS#1 v1.5, TLS-RSA key exchange, cuộc tấn công Bleichenbacher, chosen cipher attack.

Đầu tiên, tôi sẽ nói về cuộc tấn công Bleichenbacher.

Năm 1998, Daniel Bleichenbacher công bố cuộc tấn công chọn bản mã trên mã hoá RSA PKCS #1 v1.5 được sử dụng trong SSL. Cuộc tấn công dựa trên lỗ hổng của server, cho phép kẻ tấn công có thể xác định được rằng các thông điệp sau khi được gỉải mã có được padding đúng định dạng hay không. Chính lỗ hổng này cho phép kẻ tấn công có thể thu hẹp khoảng giá trị của thông điệp đã được mã hoá dựa vào thuật toán của Bleichenbacher, và cuối cùng kẻ tấn công có tìm được bản rõ mà không cần khoá bí mật để giải mã. Cuộc tấn công này đã phá vỡ hoàn toàn bảo mật SSL khi sử dụng mã hoá RSA.Điều kiện để tấn công theo Bleichenbacher trên SSL, một là với bất kỳ ai đều có khoá công khai đều có thể mã hoá được. Hai là trước khi mã hoá, bản rõ phải được padding theo chuẩn PKCS#1 v1.5. Đến đây xuất hiện một khái niệm mới PKCS#1 v1.5.

Giả sử (N, e)  là khoá công khai, chiều dài N tính theo byte là l, khoá bí mật là d. Trước khi 1 thông điệp k được mã hoá theo RSA, cần phải padding 1 chuỗi ngẫu nhiên PS theo chuẩn PKCS#1 v1.5 trong SSL, các bước tiến hành như sau:

  • Bước 1:  Tạo 1 chuỗi  padding ngẫu nhiên PS, |PS| > 8, |PS| = l-3-|k|  
  • Bước 2: Tính toán khối thông điệp theo khối có dạng: m = 00||02||PS||00||k
  • Bước 3: Mã hoá thông điệp theo RSA: c = m^e mod N (c được gọi là bản mã)

Tuy nhiên PKCS#1 v1.5  trong  TLS khác một chút, thêm 1 trường nữa là version của TLS, có dạng như sau :

00 || 02 || PS || 00 || 03 || 03 || k

Theo tiêu chuẩn của TLS 1.2 thì trường version được quy định là 0303.

Để giải mã, người giải mã cần phải biết khoá bí mật,bản rõ được tính như sau theo mã hoá RSA:

m = c^d (mod n) với d là khoá bí mật

sau đó kiểm tra padding có đúng định dạng PKCS#1 v1.5 hay không, và sẽ được chính xác thông điêp k.

Để thực hiện cuộc tấn công, kẻ tấn công gửi mã bản mã c lên server, server sẽ thực hiện giải mã, và kiểm tra xem khối được giải mã có đúng theo chuẩn định dạng PKCS# 1.5 hay không, nếu như bản rõ bắt đầu bằng 0002 thì sẽ trả về 1, nếu không sẽ trả về 0.

Thuật toán Bleichenbacher dựa trên tính mềm dẻo mã hoá theo RSA. Kẻ tấn công có thể sử dụng 1 giá trị s và thực hiện:

c’ = (c*s^e) mod N = (c*s) mod N

sau đó tăng dần giá trị s, tính c’, sau đó gửi lên server để giải mã , cho đến khi nhận được phản hồi là 1, khi đó kẻ tấn công có thể biết được :

2B <= m*s - r*N <3B

trong đó B = pow(2,8*(l-2)), điều này cho phép kẻ tấn công có thể giảm các trường hợp xuống. Bằng cách chọn giá trị s, tính toán r , kẻ tấn công có thể giảm phạm vi của m, cho đến khi chỉ còn lại m hoặc thời gian đủ nhỏ có thể brute force tìm m.

Thuật toán Bleichenbacher có dạng như sau

Các bạn có thể code lại và test thử.  Bleichenbacher’s attack không chỉ giải mã mà còn có thể ký bất kỳ thông điệp nào với khoá bí mật của server. Để tạo chữ ký với khoá bí mật của server, kẻ tấn công cần phải sử dụng 1 hàm băm thích hợp và mã hoá để xử lí thông điệp. Để tạo chữ ký theo chuẩn định dạng PKCS#1.5 với thông điệp M , cần phải mã hoá theo đinh dạng sau:

EM = 0001 || FF … FF || 00 || ASN.1(hash(M))

Đầu ra của hàm băm sẽ được ma hoá theo ASN.1. Kẻ tấn công thiết lập EM là đầu vào của thuật toán Bleichenbacher.

ROBOT attack tấn công thẳng vào quá trình trao đổi khoá trong TLS để lấy khoá bí mật,đặc biệt là trao đổi khoá sử dụng mã hoá RSA,  khoá bí mật này có thể giải mã toàn bộ các thông điệp được trao đổi sau này. Vì vậy ta cũng phải biết được quá trình trao đổi khoá trong TLS-RSA diễn ra nó như nào? Để cho các bạn dễ hình dung, tôi sẽ mô tả quá trình trao đổi khoá bằng hình sau:

CyStack cũng đã có một bài phân tích về cách hoạt động của HTTPS ở đây. Nên tôi sẽ chỉ giải thích ngắn gọn quá trình này.

  • Quá trình bắt tay TLS bắt đầu TLS client với thông điệp ClientHello. Thông điệp này bao gồm version TLS, và  danh sách các bộ mã hỗ trợ.
  • Nếu như server có bản mã, giao thức được hỗ trợ với client, nó sẽ phản hồi thông điệp ServerHello, thông điệp này chỉ ra bộ mã được lựa chọn và các tham số kết nối khác.
  • Server tiếp tục gửi chứng  chỉ trong thông điệp Certificate và tín hiệu kết thúc với thông điệp ServerHelloDone.
  • Sau đó client sẽ gửi thông điệp ClientKeyExchange bao gồm các tham số bí mật được mã hoá RSA với khoá trong chứng chỉ của server. Tất cả các khoá kết nối khác bắt nguồn từ tham số bí mật này.
  • Cuộc bắt tay sẽ kết thúc, khi cả 2 bên gửi thông điệp ChangeCipherSpec và Finished. Thông điệp ChangeCipherSpec chỉ ra các thông điệp tiếp theo được mã hoá theo session key, còn Finished chỉ ra kết thúc giai đoạn bắt tay. Sau đó client và Server sẽ trao đổi thông điệp sẽ được mã với khoá bí mật được trao đổi bên trên.

Vì tấn công ROBOT  là một biết thể của cuộc tấn công  Bleichenbacher trên giao thức sử dụng mã hoá RSA. Vì vậy tôi đã gỉai thích tấn công Bleichenbacher’s bên trên để các bạn có thể hình dung dễ hơn. Bây giờ mới đến cái chính mà chúng ta muốn tìm hiểu ROBOT attack.

Cuộc tấn công này chỉ có thể áp dụng với các trang web HTTPS, sử dụng các giao thức TLS/SSL đảm bảo truyền thông an toàn. Tấn công Robot chỉ ảnh hưởng đến các bộ mã RSA được sử dụng trong TLS. Cuộc tấn công có thể mô tả bằng hình sau:

Ở hình trên xuất hiện 2 khái niệm chosen cipher attack và oracle. Chosen cipher attack là cuộc tấn công chọn bản mã, tức là kẻ tấn công có bản mã sau đó chỉnh sửa gửi lên server, nếu như attacker nhận được bất kì thông tin nào của bản rõ từ phản hồi của server thì attacker giành chiến thắng. Oracle là các máy chủ có sử dụng mã hoá để mã hoá, giải mã thông điệp.

Trong giao thức TLS, trước khi hai bên trao đổi thông điệp cần phải thực hiện quá trình bắt tay (TLS handshake) để trao đổi khoá bí mật dùng để mã hoá các thông điệp được trao đổi sau này. Toàn bộ bảo mật của quá trình nằm trên thông điệp ClientKeyExchange được gửi từ client đến server, thông điệp này chứa giá trị pre-master-secret được mã hoá với khoá công khai RSA của server. Giá trị pre-master-secret trước khi được mã hoá sẽ được padding theo chuẩn định dạng PKCS#1 v1.5, sau đó sẽ dùng khoá công khai trong chứng chỉ nhận được của server để mã hoá. Khi server nhận được thông điệp ClientKeyExchange, bước đầu tiên sẽ giải mã và kiểm tra xem có đúng định dạng PKSC#1 V1.5, nếu như 2 byte đầu không phải là 0x0002 thì kết nối sẽ không được thiết lập. Trong 1 số trườmg hợp SSL/TLS sẽ gửi cảnh báo đến client và đóng kết nối. Một kẻ tấn công có thể cố gắng thành lập 1 kết nối bằng cách gửi 1 giá trị ngẫu nhiên trong thông điệp ClientKeyExchange thay vì giá trị pre-master-secret đã được mã hoá. Nếu như server tiếp tục bắt tay, thì có nghĩa là 2 byte đầu tiên của dữ liệu đã được giải mã là 0x0002, nếu như server gửi cảnh báo , có nghĩa là bị lỗi. Server có thể kiểm tra thêm các điều kiện khác và giá trị có thể bị từ chối mặc dù khi giải mã bắt đầu bằng 2 byte 0x0002. Ví dụ server sẽ kiểm tra thêm giá tri pad có khác 0 hay không. Tuỳ thuộc vào hành vi của server mà cuộc tấn công dễ hay khó hơn. Sau đó attacker sử dụng thuật toán Bleichenbacher’s  để attack, giảm phạm vi của bản rõ m xuống cho đến khi chỉ còn lại m hoặc  thời gian đủ nhỏ có thể brute force tìm m. Nếu như kẻ tấn công tìm được giả trị pre-master-secret có thể giải mã được toàn bộ các thông điệp được sau đổi sau này.

Bleichenbacher’s oracle cũng được biết đến là cuộc tấn công “triệu  thông điệp” bởi vì nó phải gửi hàng triệu thông điệp ClientKeyExchange giả cho đến khi nhận được giá trị “pre-master-secret”. Trong 1 số trường hợp server phát hiện ra ClientKeyExchange không đúng định dạng (khi giải mã ra không đúng định dạng PKCS#1.5 ) nó tạo 1 giá trị ngẫu nhiên  như thể nó nhận được giá trị từ client và gửi thông điệp ChangeCipherSpec. Với cơ chế này kẻ tấn công không thể phân biệt được lỗi, và cuộc tấn công là không thể.

Một máy chủ bị lỗ hổng cho phép 1 kẻ tấn công thực hiện với khoá bí mật của server. Tuy nhiên cuộc tấn công này cần đến vài nghìn kết nối và thực hiện trong 1 khoảng thời gian.TLS hỗ trợ các kiểu trao đổi khoá khác nhau với RSA: trao đổi khoá RSA  nơi mà giá trị bí mật được mã hoá bởi client và chuyển tiếp bí mật cho phép trao đổi khoá sử dụng Diffie Hellman  hoặc curve Diffie Hellman nơi mà RSA chỉ được sử dụng để ký. Nếu như trao đổi khoá dùng RSA để mã hoá giá trị bí mật được sử dụng, kẻ tấn công có thể ghi lại các bản ghi và sau đó có thể gải mã nó với Bleichenbacher oracle. Nếu như server chỉ hỗ trợ trao đỏi khoá RSA tĩnh có đọ rủi ro rất cao.

Tấn công vào trao đổi khoá nơi mã RSA chỉ được sử dụng để làm chữ kí , kẻ tấn công phải đối mặt với  1 vấn đề: kẻ tấn công có thẻ giả mạo một server với client , để thực hiện được điều này kẻ tấn công phải thực hiên được với chữ kí trong suốt quá trình bắt tay. Một quá trình bẳt tay trong TLS thường nhỏ hơn 1 giây . Kẻ tấn công có thể trì hoãn lên đến vài giây, và không được nhiều hơn, cuôc tấn công cần phải diễn ra nhanh. Mà để taọ chữ kí với Bleichenbacher attack sẽ mất nhiều thời gian hơn so với việc giải mã, do vậy điểu này rất khó khăn trong thực tế.

Vậy tấn công Robot có gì khác so với tấn công  Bleichenbacher hay không?

Tấn công Bleichenbacher dựa trên các cảnh báo trả về từ server, thông điệp sau khi được gỉải mã kiểm tra nếu padding đúng thì trả về true, nếu không trả về false. Trong tấn công Robot, dựa vào phân biệt các loại lỗi timeouts, connection resets, duplicate TLS alerts. Theo các nhà nghiên cứu phát hiện ra lỗ hổng này, họ cũng phát hiện ra rằng, nếu như gửi các thông điệp được rút ngắn chỉ gửi thông điệp ClientKeyExchange mà không gửi các thông điệp ChangeCipherSpec và Finished , cho phép họ tìm ra nhiều máy chủ dễ bị tổn thương hơn.

Tại sao một cuộc tấn công hết sức nguy hiểm này vẫn còn tồn tại cho đến bây giờ mặc dù đã được tìm ra từ năm 1998?

Sau khi Daniel Bleichenbacher công bố cuộc tấn công, thay vì sử dụng RSA-OAEP để padding trong mã hoá RSA, các nhà thiết kết TLS vẫn quyết định sử dụng RSA PKCS #1 v1.5 trong các phiên bản TLS sau này và áp dụng thêm các biện pháp đối phó. Các biện pháp đổi phó này quy định rằng các các phản hồi của server luôn taọ ra các cảnh báo chung, tức là kẻ tấn công không thể phân biệt được loại lỗi trả về từ server. Mục đích là để ngăn chặn kể tấn công không thể phân biệt được đâu là bản mã hợp lệ hay không hợp lệ.

Tấn công Robot chỉ ảnh hưởng đến các chế độ mật mã sử dụng RSA. Tuy nhiên hầu hết các kết nối hiện nay TLS sử dụng  Elliptic Curve Diffie Hellman key exchange để trao đổi khoá bí mật và chỉ sử dụng RSA để ký số. Vì vậy để phòng chống cuộc tấn công chỉ cần vô hiệu hoá các mã hoá RSA.

Chúng ta cũng có thể kiểm tra trực tiếp xem các trang web có bị lỗ hổng hay không?, các nhà phát hiện ra các lỗ hổng này đã công bố tool để kiểm tra 1 trang web có bị lỗ hổng không. Chúng ta có thể tải tool  về theo đường dẫn https://github.com/robotattackorg/robot-detect, cài đặt và chạy thử.

Các bạn cũng có thể tham khảo thêm tại trang web: https://robotattack.org/#check