III. 0X01.1 Phân tích CVE-2020-5243


Dưới đây là chức năng session history ở một số ứng dụng, chức năng này có nhiệm vụ lưu lại các phiên đăng nhập trên các thiết bị, địa điểm khác nhau.

image

Hình mô tả chức năng session history

Chức năng này đa phần sử dụng regular expression để lọc ra các thiết bị định danh cho người dùng. Đầu vào mà máy chủ thường dùng để xử lý cho chức năng này là trường User-Agent được đính kèm trong header gửi đến máy chủ.

image

Hình mô tả trường User-Agent

Và phần xử lý này của ứng dụng cũng thường dễ bị tấn công bởi ReDoS. Cụ thể có thể xem qua mã lỗi CVE-2020-5243 mô tả rằng chức năng phân tích trường User-Agent của thư viện ua-parser có thể bị khai thác ReDoS do bắt các nhóm chồng chéo nhau không chặt chẽ.

Đây mẫu regular expression gây lỗi: ; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)

Điểm gây lỗi chính là nơi bắt ra 2 nhóm \d+[^\);]+)[^\);]* trong cú pháp, như ví dụ 3 nói trên thì evil character từ kẻ tấn công truyền vào có thể trùng khớp với cả 2 nhóm trên.

8

Mô tả 2 nhóm bắt kí tự chồng chéo lên nhau

Vì truyền lên một chuỗi đầu vào không khớp mẫu, kèm theo là hữu hạn các evil character dẫn đến bộ máy này cần xử lí hữu hạn các đường đi trạng thái để kết thúc. Từ đó khiến cho các máy chủ trở nên quá tải và gây tắc nghẽn.

Sau khi nhận được báo cáo, thư viện đã cung cấp bản vá khắc phục như bên dưới.

13

Trong bản vá này loại đi nhóm [^\);]* khỏi cú pháp đã giải quyết được vấn đề các nhóm bắt kí tự chồng chéo lên nhau.


IV. 0X02 ReDoS trong Whitebox

Tìm kiếm nơi có thể xảy ra ReDoS phổ biến hơn trong Whitebox, vì cách thức phát hiện loại tấn công này chủ yếu phân tích các mẫu regular expression từ ứng dụng. Từ đó tìm ra các kí tự potential có thể dẫn đến backtracking.

Đã có nhiều nhà nghiên cứu đóng góp các công cụ phân tích mẫu regular expression độc hại có thể phát hiện ra hầu hết các mẫu có khả năng bị khai thác. Ví dụ như:

  • regexploit phát triển bở @doyensec hỗ trợ khá nhiều ngôn ngữ như java,javascript,python.c-sharp
  • saferegex phát triển bởi @jkutner
  • ...

Các công cụ này đã làm tốt công việc của nó là tìm được các mẫu có khả năng gây lỗi đến 80%. Tuy nhiên vẫn bỏ qua một số mẫu phức tạp.

V. 0x03 ReDoS trong Blackbox

Khai thác ReDoS trong Blackbox ít khả hơn so với WhiteBox, vì nó như một kiểu khai thác . Cách khai thác vẫn chỉ có thể suy đoán các tham số dễ bị tấn công như các trường email, phone number, session history.... Các trường mà ứng dụng yêu cầu sự phân biệt rõ ràng bởi kí tự thường, in hoa, số, kí tự đặc biệt.

Sau khi tìm được các điểm vào có thể khai thác thì lại có 2 cách tấn công có thể dùng:

  • Tự động 100%:
  • Bao gồm 2 bước chính sau khi tìm được đầu vào có khả năng khai thác là đưa ra tập n giả định mẫu regular expression từ server. Bước tiếp là đưa ra tập m chuỗi đầu độc hại để lần lượt khai thác các mẫu giả định kia. Có thể xem là mất n^m bước khai thác.
  • Semi(thủ công 50%, tự động 50%):
  • Bỏ qua bước đưa ra n giả định mẫu mà người khai thác sẽ tự gợi ý mẫu regular expression. Sau đó sẽ tự động thực hiện vét cạn m chuỗi vào độc hại.

Đối với cách tự động 100% kia mình sợ rằng chưa kịp tấn công máy chủ thì máy mình đã tự crash rồi. Vì vậy mà hiện tại vẫn chưa có công cụ nào khả quan để kiểm tra blackbox.

VI. 0x04 Ngăn chặn ReDoS

Làm thế nào để tạo ra mẫu regular expression vừa linh hoạtan toàn?

Với người một số bạn chưa có kiến thức bảo mật về phần này đang cố gắng tạo ra một mẫu regular expression dài ngoẵn. Nhằm mục đích bắt được nhiều nhóm, nhiều mục tiêu, bắt nó như một mẫu đa dụng. Nhưng đôi khi sẽ biến tính năng thành lỗ hỏng.

Vậy làm sao để giải quyết câu hỏi ở trên? Mình sẽ liệt kê một số cách để hạn chế khả năng bị khai thác thông qua mẫu như sau:

  • Sử dụng DFA -> An toàn nhưng sẽ không linh hoạt vì hạn chế các trạng thái kết thúc.

Trở thành một người viết mẫu chuẩn 4.0:

  • Đừng cố gắng tạo ra một mẫu regular expression quá đa nhiệm. Đôi khi sẽ biến tính năng thành lỗ hỏng. Cố quá sẽ thành quá cố >.<

Nên ràng buộc chiều dài với các kí tự tự do:

Ví dụ như không sử dụng \s+ hoặc \w+ \d+ mà nên ràng buộc chiều dài \s{1,3} \w{1,3}

  • Có thể sử dụng backreferences để kiểm tra số lần lặp lại của kí tự để loại bỏ các kí tự trùng.
  • Hãy xét thời gian thực hiện cho các lần sử dụng máy regex, nếu trường hợp việc xử lý đầu vào quá lâu thì có thể dừng tiến trình và thông báo chuỗi phức tạp.
  • Sử dụng *+ đúng lúc đúng chỗ.
  • Bắt chính xác các chuỗi thuộc group.
  • Sử dụng các thư viện khác như strip(),trim(),replace(),... để làm sạch các đầu vào trước khi dùng đến regular expression.
  • ...

VII. 0X05 Tài liệu liên quan

[0] Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...)

[1] implementing-a-regular-expression-engine

[2] Details of regular expression behavior

[3] Construct ∈-NFA of Regular Language L = 0(0+1)*1

[4] ReDoS-Attacks

[5] NFAs and regular expressions

[6] regular-expressions.info

Tác giả: Nguyễn Đặng Khải