Trao đổi với tôi

http://www.buidao.com

11/7/09

[Hacking] Một phương pháp chống DDoS bằng xFlash

Ý tưởng

Dựa vào gợi ý của Amit Klein:

Notice the first limitation of the technique - it states that no raw CR and LF can be placed in the body section. This means that the technique cannot be used to send (POST) requests whose body complies with the "multipart/form-data" content-type format (this format uses raw CRs and LFs to mark headers and boundaries). In other words, a (POST) request whose body is a valid "multipart/form-data" stream is guaranteed (as far as today's knowledge extends) not to be sent from a Flash player. Web application authors can therefore use HTML forms whose ENCTYPE attribute is set to "multipart/form-data", and enforce that the submission contains a valid multipart/form-data body. Once these mechanisms are in place, and a request passes through, it is known not to originate from a Flash player, so the attack
described here is irrelevant.
Gợi ý ở trên có thể được diễn giải như sau:
  • Cách thức browser xử lí các HTML form có enctype = "multipart/form-data" và enctype = "application/www-urlencoded" (default) hoàn toàn khác nhau. Điểm khác nhau đặc trưng là khi submit (nghĩa là tạo ra POST request) form "multipart/form-data", browser sẽ tự động set Content-type là "multipart/form-data", còn khi submit các form khác, browser sẽ sử dụng Content-type là "application/www-urlencoded".
  • Flash (với các hàm thường được sử dụng để DDoS như LoadVars, GetURL hay SendtoURL, etc...) không thể gửi POST request theo định dạng "multipart/form-data". Đây chính là "gót chân Asin" của Flash.
  • Do đó nếu bằng một cách nào đó, ta có thể set tất cả các form thành enctype = "multipart/form-data", nghĩa là ép tất cả POST request có Content-type là "multipart/form-data", ta sẽ có thể phát hiện ra những POST request xuất phát từ Flash, vốn dĩ luôn có Content-type là "application/www-urlencoded".
Hiện thực

Để hiện thực hóa ý tưởng này, ta cần phải có một cách nào đó biến tất cả các HTML form thành enctype = "multipart/form-data", rồi sau đó phải chỉnh sửa lại server-side code để xử lí các form này (tin vui: thử nghiệm với một vài ngôn ngữ lập trình phổ biến như PHP, Java và Ruby, tôi thấy rằng không cần phải chỉnh sửa server-side code, các ngôn ngữ này đều có cách thức xử lí giống nhau với hai loại enctype của HTML form).

Vậy nhiệm vụ còn lại là điều chỉnh HTML form. Cách dễ thấy nhất là sửa code HTML. Phần còn lại của bài này tôi trình bày một cách khác, không cần chỉnh sửa code HTML. Đó là sử dụng output filter của Apache 2.x.

Ý tưởng cơ bản là triển khai một cái reverse proxy bằng Apache 2.x, đứng trước tất cả các server cần được bảo vệ khỏi xFlash. Trên cái reverse proxy đó, ta sẽ sử dụng một output filter module làm nhiệm vụ tự động thêm attribute enctype="multipart/form-data" vào tất cả các HTML form mà nó thấy.

Ban đầu tôi tính viết riêng một cái Apache 2.x module để làm chuyện này, nhưng rồi vô tình phát hiện ra có sẵn một module đã làm chuyện đó rồi. Đó là module mod_line_edit:
mod_line_edit is a general-purpose filter for text documents. It operates as a simple on-the-fly line editor, applying search-and-replace rules defined in a configuration or .htaccess file.
Để sử dụng mod_line_edit, trước tiên bạn cần phải biên dịch nó. Có hai cách biên dịch: biên dịch mod_line_edit thành một module tĩnh hoặc thành một module động (DSO). Nói chung để tối ưu hóa tốc độ xử lý, nên biên dịch mod_line_edit thành một module tĩnh theo cách sau đây:

server$ cd /usr/local/src
server$ wget http://www.tux.org/pub/net/apache/dist/httpd/httpd-2.2.4.tar.gz
server$ wget http://apache.webthing.com/mod_line_edit/mod_line_edit.c
server$ tar -xzf httpd-2.2.4.tar.gz

server$ mkdir -p httpd-2.2.4/modules/line_edit
server$ cp mod_line_edit.c httpd-2.2.4/modules/line_edit
server$ cp httpd-2.2.4/modules/echo/Makefile.in httpd-2.2.4/modules/line_edit
server$ cd httpd-2.2.4/
server$ "./configure" \
"--prefix=/opt/httpd" \
"--with-module=line_edit:mod_line_edit.c"

Cấu hình mod_line_edit cực kì đơn giản. Đầu tiên thêm hai dòng này vào httpd.conf để kích hoạt mod_line_edit:
FilterProvider textedit line-editor resp=Content-Type $text/
FilterChain textedit
Để mod_line_edit tự động thêm attribute enctype="multipart/form-data" vào tất cả các HTML form, thêm dòng sau đây vào nơi thích hợp (virtual host, location, etc...)
LERewriteRule '(<>' '$1 enctype="multipart/form-data">' Ri
Rồi xong, tất cả các form HTML của bạn sẽ tự động có enctype = "mutilpart/form-data". Nghĩa là POST request của bạn sẽ luôn có Content-type là "multipart/form-data".

Việc còn lại là cấu hình mod_security để nó phát hiện và loại bỏ các POST request có Content-type là "application/www-urlencoded" xuất phát từ xFlash. Tôi dành phần này lại cho các bạn tự làm.

Ưu điểm và nhược điểm


Phương thức mà tôi trình bày ở trên có những ưu điểm nhất định so với các phương thức phổ biến hiện nay:
  • Thứ nhất, do phương thức này đánh vào "gót chân Asin" của xFlash nên bạn không cần thay đổi cấu hình mà vẫn có thể phát hiện được xFlash dẫu kẻ tấn công có thay đổi nơi chứa xFlash hay thay đổi mục tiêu tấn công.
  • Thứ hai, nếu áp dụng theo mô hình reverse proxy, bạn sẽ có thể cùng một lúc bảo vệ được nhiều web-server bên trong khỏi xFlash, rất thích hợp với các hosting provider.
Tuy vậy, phương thức này cũng có những nhược điểm:
  • Thứ nhất, nó chỉ chống được thế hệ xFlash hiện tại. Theo nghiên cứu của riêng tôi, Flash, cụ thể là Flash Player 9 với ActionScript 3, cực kì nguy hiểm. Cách làm này sẽ không thể chống được thế hệ xFlash mới được phát triển dựa trên tính năng của ActionScript 3. Ngoài ra, nếu kẻ tấn công biết cách khai thác các lỗ hổng của Flash 9 trở về trước, phương thức này cũng sẽ trở nên vô tác dụng.
  • Thứ hai, nó chỉ phát hiện và chống được POST request từ xFlash. Theo anh con-ma-le cho biết, một số biến thể xFlash hiện tại chỉ chơi GET request mà thôi.
  • Thứ ba, đối với những website có áp dụng AJAX, phương thức này có khả năng sẽ gây ra false positive. Lý do là XMLHTTPRequest của Javascript cũng gửi POST request có Content-type là "application/www-urlencoded". May mắn là tất cả các AJAX framework mà tôi biết đều có khả năng thêm custom header vào HTTP request, do đó bạn có thể nhìn vào header này để phân biệt giữa xFlash và AJAX.
  • Thứ tư, với cái rule của mod_line_edit ở trên, website của bạn có nguy cơ không còn tuân theo chuẩn của W3C nữa. Ví dụ như nếu một webpage của bạn đã có sẵn enctype = "multipart/form-data", khi mod_line_edit thêm vào một attribute tương tự, webpage này sẽ không còn đúng chuẩn W3C.
Kết luận

Phương thức này không phải là "silver bullet" có thể giải quyết dứt điểm xFlash. Tuy vậy nó cũng có khả năng hạn chế được sức tàn phá của thế hệ xFlash hiện tại. Tôi nghĩ chỉ có hai cách có thể giải quyết dứt điểm xFlash:
  • Không sử dụng Flash. Nếu bạn hiểu rõ Flash nguy hiểm đến cỡ nào, hoặc nếu bạn tin tưởng tôi, tôi khuyên bạn không nên sử dụng Flash hoặc it nhất mặc định là không cho chạy Flash, rồi có thể enable theo từng website cụ thể. NoScriptFlashBlock có thể giúp bạn làm chuyện này dễ dàng!
Đừng cố chống xFlash bằng cách nhìn vào các đặc trưng của nó. xFlash hoàn toàn có thể tạo ra những request giống y những request hợp lệ. Hãy chống xFlash như chống các loại DDoS khác, nghĩa là: a) đầu tư vào cơ sở hạ tầng, bao gồm hệ thống server, đường truyền và con người; b) tối ưu hóa hệ thống, đảm bảo tốc độ xử lí tốt nhất với chi phí bỏ ra; c) thiết kế hệ thống thật scalable, bởi xét cho cùng, bị xFlash tấn công cũng tương tự như lượng user của bạn tăng lên đột biến.

Link: http://vnhacker.blogspot.com/2007/07/mt-phng-php-chng-ddos-bng-xflash.html