banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Messages posted by: prof  XML
Profile for prof Messages posted by prof [ number of posts not being displayed on this page: 4 ]
 
25/4/2005
Mấy ngày qua triền miên với gia đình và bạn bè vì nơi tôi cư ngụ có ngày lễ lớn. Tôi cũng không lo ngại mấy cho HVA forum vì tôi biết chắc giải pháp tạm thời "ép" người dùng đi vào cổng 443 dùng "self signed" ssl của HVA hoàn toàn hoá giải những cú "x-flash" hết sức hợp lệ kia. Tôi không muốn (và không tiện) vùi đầu vào mớ luật phòng thủ của HVA trong khoảng thời gian này.

Chiều nay, một buổi chiều ngày lễ. Sau những trận họp mặt náo nhiệt, tôi được một buổi chiều yên tĩnh và rảnh rang. Tôi nghĩ ngay đến việc tạo ra thêm một lớp "vỏ" cho HVA forum như đã đề cập trong bài "ký sự" trước. Làm một ly cà fê, tôi thong thả ngồi xuống bàn và mở laptop lên.

Lần trước tôi đã đề cập như sau: "Một biện pháp cản lâu dài tôi có thể nghĩ ra trong khoảng thời gian hạn hẹp này là "cản" không cho bất cứ request nào đi thẳng đến *.php cả. Làm được điều này, sự cản trở đầu tiên sẽ là việc loại trừ khả năng các cú 'x-flash' "ép" HVA forum ngoan ngoãn gởi queries đến database và tạo load trên máy chủ. Cả request "hợp lệ" lẫn "bất hợp lệ" đều phải đi xuyên qua các đường dẫn trước khi các *.php thực thi công tác." Có lẽ câu nhận định này khá rõ ràng cho những ai từng theo dõi sâu sát những bài "ký sự" trước. Tôi không cần phải nhắc lại chi tiết lý do tại sao phải thực hiện chuyện này nhưng điểm cốt lõi của vấn đề nên được nhấn mạnh: dạng tấn công lúc này không có điểm nào dùng để cản. Nếu không cản được thì cho vào cả, nhưng cho vào với điều kiện do mình đặt ra.

Chắc bạn đã thấy chiến thuật đã thay đổi một cách nghiêm trọng? Từ chỗ tìm ra những dấu hiệu đặc thù của những cú "x-flash" để cản, đi đến chỗ cho phép mọi request đi vào với các điều kiện tiền định nào đó. Nếu bạn hiện đang truy cập HVA forum, bạn hẳn thấy có trang index và nút "e n t e r" để đi vào trong forum. Đây chính là phần cản phục vụ cho khái niệm tôi vừa nêu ra ở trên.

Chuyện gì xảy ra bên dưới "tấm màn" index.html này? Như đã có nhiều tay kinh nghiệm nhận định trước khi bài "ký sự" kỳ này được viết, quả thật tôi đã dùng đến những thứ có trên HTTP header để quyết định cho những request nào tiếp tục vào[b] và đẩy những request nào không thoả mãn điều kiện lại [b]tiếp tục vào... trang index.html smilie. Tôi không muốn nêu ra một cách chi tiết những gì có và không có trên HTTP header và những yếu tố nào tôi đã dùng để áp đặt từng bước "cho vào". Làm như vậy e tạo điều kiện quá dễ dàng cho "chủ nhân" các con "x-flash" kia (tôi đã sai lầm khi đã gợi ý cho chủ nhân "x-flash" đường hướng của dạng tấn công "không lan man" này và chỉ một lần là quá đủ). Đối với bạn, một admin có trách nhiệm quản lý server của mình, bạn chỉ cần dùng sniffer để "bắt" một mớ packets, thu thập những gói tin cho một xuất truy cập hợp lệ và so sánh với mớ gói tin được tạo từ "x-flash" dùng để tấn công thì bạn có thể dễ dàng thấy sự khác biệt. Cái khó và mất thời gian là bạn phải nắm rõ các URI nào diễn đàn dùng và chỉ cho phép chúng được truy cập dựa trên các luật nào đó cho phép. Những URI khác (và không tồn tại) sẽ phải được cản.

Viết thêm rules cho mod_security và .htaccess khá đơn giản sau khi hình thành kế hoạch rõ ràng nhưng thời gian dành cho debug có lẽ nhiều. Tôi bắt tay ngay vào thực hiện chuyện "viết rules" này. Sau hơn ba mươi phút, các rule cốt lõi cho cái "vỏ" đã sẵn sàng. Ba mươi phút kế tiếp tôi dành thời gian để "debug" mấy cái rules vừa hình thành. Mục tiêu chính là cố gắng giảm thiểu trường hợp những rule này tạo cản trở cho người dùng hợp lệ, đồng thời không vô tình để hở cho cho các cú "x-flash" đi vào. Điều khó khăn là tôi không thể "test" những rules này trên máy riêng ở nhà vì làm như vậy sẽ mất thời gian hơn để tạo các cú "x-flash giả" để thử nghiệm. Tuy nhiên, test các rules này ngay trên máy chủ HVA chắc chắn sẽ tạo bối rối cho nhiều thành viên nhưng... biết làm sao được?

Trong khi thao tác các bước cần thiết để tạo thêm lớp "vỏ" này, tôi đã ngầm e ngại một "triệu chứng phụ" sẽ xảy ra. Triệu chứng này không thể làm cho máy chủ HVA treo vì cạn kiệt tài nguyên nhưng lại có thể không cho người dùng truy cập vào diễn đàn HVA. Dù gì đi chăng nữa, phải hoàn tất mảnh "vỏ" index.html và các luật bảo vệ rồi lo liệu chuyện "triệu chứng phụ" sau. Sau hơn một giờ táy máy với máy chủ HVA, tôi chuyển server về lại tình trạng cũ, có nghĩa là thành viên HVA vẫn phải đi xuyên qua cổng 443 (HTTPS) vì tôi nhận thấy việc thử nghiệm này sẽ mất rất nhiều thời gian. Có lẽ tôi phải chờ đến trưa mai, khi có ít thời gian rảnh rang, tôi sẽ tiếp tục phần thử nghiệm này.

Tôi logoff HVA server và vươn vai đứng dậy.

26/04/2005
Hôm nay quả là một ngày cực kỳ bận bịu đối với tôi. Trưa nay, vừa ăn trưa tôi vừa tranh thủ logon HVA server để tiếp tục khoản công việc dở dang hôm qua. Tôi nhận thấy truy cập vào diễn đàn HVA bằng https vẫn được và vẫn ở tốc độ "có thể chấp nhận". Tuy nhiên, tôi không thoả mãn với giải pháp tạm bợ này, phải hoàn tất "lớp vỏ" bảo vệ mới cho diễn đàn HVA càng nhanh càng tốt nhưng... thời gian quả là hạn hẹp.

Tôi tiếp tục công việc "debug" các rules mới tạo cho mod_security, từng phần một. Kiểm tra kỹ lưỡng mỗi request từ client (từ trình duyệt của tôi) và response từ server (từ máy chủ HVA), phân tích tính chất của mỗi URI chính yếu của diễn đàn HVA. Trong khi thử nghiệm, tôi khám phá ra IPB và mớ .php của nó có những điểm bất nhất khi nhận requests và trả về responses. Những điểm bất nhất này khó thấy nhưng chúng trở nên rõ ràng khi tôi bắt tay vào việc "debug". Tôi quyết định dùng mod_security để che lấp chúng và dành công tác điều chỉnh trên .php về sau, khi có thời gian rộng rãi. Những điều tôi tìm thấy không hẳn là điểm yếu bảo mật; chúng chỉ làm cho bộ luật của mod_security thêm phần rối rắm để có thể "che" trọn bộ các URI một cách vững vàng.

Một giờ nghỉ trưa trôi qua, 2 phần 3 bộ luật đã được kiểm chứng và điều chỉnh, 1 phần 3 còn lại có lẽ phải dành cho lúc khác vì tôi phải trở lại làm việc. Khi logoff máy chủ HVA, tôi quên khuấy một điều là đã quên đóng cổng 80 lại, chỉ cho phép người dùng truy cập diễn đàn ở cổng 443. Kết quả của sự đãng trí này đã tạo ra không ít bối rối cho người dùng trong buổi chiều hôm ấy. Mãi đến tối ngày 26/04/2005, khi login HVA server để "tiếp tục công việc", tôi mới khám phá ra rằng cổng 80 vẫn còn mở và bà con vào diễn đàn ở cổng này. Chắc hẳn họ đã gặp phải nhiều hiện tượng "kỳ quặc" bởi bộ luật của mod_security chưa hoàn chỉnh.

Tối 26/04/2005
Hôm nay công việc quá bề bộn nên tôi về nhà khá trễ. Cơm nước xong đã gần 8 giờ tối. Nhìn đồng hồ, tôi thầm nghĩ "chẳng còn bao nhiêu thời gian để táy máy". Tuy vậy, tôi vẫn log vào HVA server để xem qua tình hình và xem thử có tiếp tục được bao nhiêu công việc đang dang dở.

Tôi nhận thấy server có vẻ chậm hơn trưa nay rất nhiều. Kiểm tra server load, tôi ngạc nhiên khi thấy load trung bình lên tới 98. Tôi tò mò muốn xem thử trò chơi mới của "x-flash" thế nào nên để yên server ở tình trạng như thế. Không còn thời gian để dump các packets này và tải về để xem trên Ethereal trên laptop, tôi phóng ngay lệnh tcpdump trên màn hình để xem chuyện gì xảy ra. Tôi cần tcpdump bắt trọn gói mỗi gói tin bất kể kích thước nào và hiển thị trên màn hình cho tôi ở dạng binary lẫn ASCII nên lệnh dùng thế này (nếu bạn cần biết):
Code:
# /usr/sbin/tcpdump -s0 port 80 -X

Tôi phải đảo mắt rất nhanh để theo dõi dòng thông tin "chảy" như thác trên màn hình. Thỉnh thoảng tôi phải tạm chấm dứt lệnh này để xem kỹ vài chi tiết rồi lại tiếp tục. Sau vài phút kiểm tra, tôi đã có đủ thông tin cần thiết để biết chuyện gì đang xảy ra. Tôi lẩm bẩm: "đúng là điên khùng!" khi thấy có 4 dạng request khác nhau đổ dồn vào HVA:
- GET /
- POST /
- GET /forum/
- POST /forum/index.php

và tất nhiên chẳng có mấy gói tin mang "x-flash" header. Trong khi "lớp vỏ" che cho forum ở web layer chưa hoàn tất, những cú gõ trên chỉ bị giới hạn ở mức connection limit tổng quát trên iptables. Số còn lại thả dàn đi vào. Tôi đành phải dùng một chước khá buồn cười là đổi trang mặc định của web server từ index.php thành start.php và restart lại apache. Tất nhiên là mới GET và POST điên khùng ở trên không thể đụng đến index.php để tạo load trên server. Sau vài phút, server load tụt xuống đáng kể và truy cập xuyên qua SSH nhanh hơn rõ. Cái "chước" đổi trang mặc định thành start.php chỉ ngăn được mớ POST cụ thể đến /forum/index.php. Số request còn lại trỏ thẳng vào / vẫn tạo ảnh hưởng đến server. Mặc dù server load tụt xuống nhanh chóng nhưng đến mức nào đó, nó dừng lại. Chà, tôi lẩm nhẩm "chẳng lẽ lại phải chuyển về https sao?". Thật tình tôi không muốn làm thế vì nó sẽ tạo thêm bối rối cho thành viên của diễn đàn. Vả lại, tôi cần debug cho xong các rules của mod_security.

Tôi log vào YIM để liên lạc với JAL, lão đang online! Tôi gởi JAL một thông điệp thông báo tình hình. Giờ này lão vẫn còn ở sở vì nơi JAL cư ngụ sau nơi tôi cư ngụ 2 giờ. JAL hí hoáy gì đó vài phút và bảo tôi "lão vào diễn đàn xem sao?".

Tôi log vào diễn đàn HVA bằng FireFox. Ái chà, khi bấm vào nút "enter" trên trang index.html, một khung hiện ra và đòi hỏi nhập username + password! Tôi lẩm bẩm "tricky, tricky!". Quả thật, chước này của JAL đã ngưng lại trọn bộ các request của "x-flash" vào mà chước đổi trang mặc định thành start.php của tôi không thể cản hết. Server load tụt xuống nhanh chóng và truy cập diễn đàn nhanh hơn hẳn. JAL đã dùng một chước rất "cổ điển" trên .htaccess nhưng hết sức hiệu quả ngay lúc này. Tôi chỉ cần làm sao cho server load giảm xuống để có thể hoàn tất mớ luật kia. Tôi gởi JAL một thông điệp "Quá hay đó bồ, tuyệt cú mèo! nhưng làm sao cho cái ID và password trên dialog đó trông rõ hơn một tí." Tất nhiên là JAL đồng ý.

Tôi quyết định để yên server như vậy và kiểm tra nhóm luật cho mod_security lại. Từng dòng một, tôi cân nhắc, điều chỉnh, dùng grep trên cygwin -61- để xác thực các mảnh regular expression hoàn toàn "match" và ứng hiệu. Tôi dành hơn ba mươi phút cho công tác này và đã gần hoàn tất trọn bộ nhóm luật. Nhìn đồng hồ tôi thấy không còn sớm nữa. Tôi phải tạm ngưng vì ngày mai phải đi làm sớm.

Chú thích:
-61- cygwin, môi trường *nix chạy trên Windows có số lượng rất lớn các chương trình dựa trên *nix và được mang sang môi trường Windows. Xem thêm về cygwin ở" http://www.cygwin.com

Các bạn có thể theo dõi tiếp phần 21 tại http://hvaonline.net/hvaonline/posts/list/512.html
22/04/2005
Hai ngày vừa qua, 21/04 và 22/04/2005, HVA hứng đỡ một dạng tấn công mới của "x-flash". Điểm đặc biệt của dạng này là hơn 95% các gói tin gởi vào HVA hoàn toàn hợp lệ từ giao thức cho đến header và payload. Tại sao tôi biết được chúng chính là "x-flash"? lý do rất đơn giản là khoảng 5% các gói tin lần này vẫn còn mang header "x-flash-version: 7,0,19,0". Vì lý do gì đó, 95% các gói tin còn lại không có header như thế (có lẽ như mọi lần, các cú x-flash này được một hoặc nhiều proxy "lột" mất header) nhưng nội dung y hệt nhau.

Hãy thử xem một mảnh request như sau:
Code:
GET /forum/index.php HTTP/1.1
Accept: */*
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Connection: Keep-Alive
Cache-Control: no-cache
Host: hvaonline.net

Không thể bắt bẻ ở đâu được, bạn nhỉ?

Hãy xem thêm một mảnh khác:
Code:
POST /forum/index.php HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Host: www.hvaonline.net
Connection: Keep-Alive
Cache-Control: no-cache
num=2

Bạn thử tìm xem có bất cứ dấu hiệu gì đáng chú ý trên mảnh POST ở trên không? Trên header của cả 2 cú GET và POST ở trên, mọi parameters đều hợp lệ và hoàn toàn đúng quy định. Chỉ có trên phần payload của cú POST có vỏn vẹn thông tin: num=2. Nói về mặt giao thức, num=2 chẳng có gì trái quấy cả cho nên chúng vẫn tạo load trên máy chủ. May thay, để nhận diện và tạo một luật loại trừ nó, các mảnh "num=" này là chìa khoá. Các cú POST ở dạng này đã "bị" tiêu hủy nhanh chóng sau khi một rule mới được hình thành trên cơ chế phòng thủ của HVA. Ngoài ra, trong đợt tấn công này, "chủ nhân" của mớ x-flash còn kèm theo vài dạng URL request khá ngớ ngẩn và không đáng để đào sâu. Tuy nhiên, đa số các cú request dùng để tấn công lần này ở dạng GET (như trên) cho nên việc cản lọc các cú POST và các cú request mang header "x-flash" chỉ giảm thiểu một phần rất nhỏ lượng tấn công.

Theo bạn, trong 2 ví dụ trên ví dụ nào khó xử lý? Tôi nghĩ cú GET cực kỳ khó xử lý. Chúng khó xử lý vì có 2 điểm chính:

1. Chúng hoàn toàn hợp lệ (ít ra có đến 95% các gói tin ở dạng này không còn mang x-flash header)
2. Chúng được gởi đến HVA từ trên 500 IP khác nhau trên thế giới và mỗi IP gởi request với biên độ bất thường, xấp xỉ 1 giây 3 request hoặc ít nhiều nằm trong biên độ này. Đây là lý do chúng dễ dàng đi qua khỏi cơ chế limit connection của HVA.

Không may, mấy ngày qua tôi bị "dính" vào giai đoạn cao điểm của mấy project lớn ở công ty nên không có nhiều thời gian tẩn mẩn với các mảnh "tcp". Trong suốt 2 ngày 21 và 22 tháng 4, tôi cố gắng log vào HVA server (xuyên qua SSH) nhiều lần nhưng bị thất bại vì bị lỗi "connection timeout". Tôi đoán rằng đường dây HVA dùng đã lên đến mức báo động vì tắc nghẽn sau khi JAL cho biết (thông qua YIM) rằng server load không quá cao.

Chiều nay, tôi quyết định dành ít thời giờ cho HVA để xem xét cái "vấn nạn" x-flash dai dẳng này. Tôi log vào YIM và nhờ JAL tắt hết mọi dịch vụ, chỉ để SSH chạy. Chúng tôi thử "liên thủ" thao tác như lần trước nhưng lần này tình hình có vẻ căng hơn vì SSH cực chậm. Tuy nhiên, rốt cuộc tôi cũng log vào được.

Điều đầu tiên tôi thực hiện là điều chỉnh firewall để nó cho phép traffic dành cho SSH được ưu tiên cao nhất (hay nói một cách khác, các rules dùng để điều tác traffic dành cho SSH được đưa lên đầu trong các rules). Tôi restart lại firewall và ngồi chờ. Chỉ mỗi việc load lại firewall rule trong điều kiện tắc nghẽn này cũng mất hơn 2 phút. Tôi chậc lưỡi, log vào SSH của HVA server lần nữa. Quả thật, sắp xếp lại thứ tự cho SSH rules tạo nên thay đổi rõ rệt. Tại sao tôi không điều chỉnh luật cho SSH như thế ngay từ đầu nhỉ? Xem như đây là một trong những cái nhìn hạn hẹp khi tôi thiết lập firewall rules cho HVA ngay từ đầu. Tôi đã không nghĩ đến khả năng các gói tin tấn công đường dây optic fibre của JAL có thể đi đến tình trạng không thể log vào SSH.

Tôi bắt tay vào việc xem xét HVA server.

Điều đầu tiên tôi nhận thấy là các request ở trên không còn "đánh" lan man vào các URL không tồn tại nữa mà "đánh" rất cụ thể vào index.php. Đây là một điểm rất yếu về cấu trúc của HVA forum (hay bất cứ php-based forum nào). Nói cho cùng, người thiết kế IPB forum này là một người hiền hoà, có lẽ anh ta chẳng bao giờ nghĩ rằng có ai đó sẽ request index.php một ngàn lần trong một giây smilie. Thực tế nặng nề mà HVA đang hứng chịu có lẽ nằm ngoài tưởng tượng của người thiết kế IPB. Như bạn biết, khi một request đụng phải index.php, php engine "ngoan ngoãn" biên dịch và thao tác những bước cần thiết (kể cả việc gởi ít nhất 5 queries đến database) để hình thành một "trang động" trước khi gởi ngược về trình duyệt. Trong trường hợp HVA có vài trăm người cùng vào, kẻ gởi bài, người xem bài thì máy chủ của HVA vẫn có thể đảm đang một cách khá dễ dàng. Tuy nhiên, có máy nào chịu nổi vài ngàn request một giây với 5 - 12 queries đến database cho mỗi request?

Tại sao không cản? Bạn hỏi. Cản gì đây? Tôi trả lời bằng câu hỏi ngược lại. Với các request như đã dẫn ở trên, thực tế chẳng có bất cứ đặc điểm nào để cản cả. Chúng đâu phải "x-flash" (mặc dù chúng chính là "x-flash" nhưng không có thông tin biểu thị "x-flash" trong header). Một biện pháp cản lâu dài tôi có thể nghĩ ra trong khoảng thời gian hạn hẹp này là "cản" không cho bất cứ request nào đi thẳng đến *.php cả. Làm được điều này, sự cản trở đầu tiên sẽ là việc loại trừ khả năng các cú 'x-flash' "ép" HVA forum ngoan ngoãn gởi queries đến database và tạo load trên máy chủ. Cả request "hợp lệ" lẫn "bất hợp lệ" đều phải đi xuyên qua các đường dẫn trước khi các *.php thực thi công tác. Để thực hiện chuyện này, tôi có thể vận dụng một trong hai cách: a) dùng mod_rewite trong .htaccess hoặc b) dùng mod_security và thiết lập bộ "luật" tinh vi hơn. Cả hai cách tôi đều cần một ít thời gian để thực hiện.

Đã gần giờ tan sở, tôi e rằng tôi không còn bao nhiêu thời gian để thực hiện ý định này. Trao đổi với nhau xuyên qua YIM, tôi thông báo tình hình cho JAL biết. Sau một hồi, JAL đề nghị: "hay mình thử dùng ssl đi lão". Tôi đồng ý ngay vì tôi biết rõ ssl trong tình trạng hiện tại là cách xử lý nhanh nhất, hy vọng tạm thời có thể đỡ được trận DoS cho đến khi dự định "dài hạn" ở trên được thực hiện.

Tôi thử log vào HVA forum xuyên qua https. Không nhanh, nhưng cũng không chậm. Tôi gởi JAL một thông điệp: "mình phải đóng luôn cổng 80 và tìm cách ép request đến cổng 80 được wwwect sang cổng 443 thì mới ổn" và lý do tại sao tôi gởi JAL thông điệp này thì quá hiển nhiên, bạn nhỉ? smilie. Sau vài thử nghiệm tôi quyết định dùng cách ra lệnh iptables "ép" các gói tin đi đến cổng 80 phải chuyển sang cổng 443 ở tầng IP. Nếu không thực hiện quy trình này, sau khi đóng cổng 80, mọi request đến đây rồi dừng hẳn vì chẳng hề có dịch vụ nào đang chạy trên cổng 80 để thực thi "rewrite" hay bất cứ phương cách tương tự nào.

Trên hồ sơ cấu hình apache, tôi "comment" dòng "lắng nghe" trên cổng 80 như sau:
Code:
# Listen *:80

Làm như thế, máy chủ HVA hoàn toàn không còn dịch vụ nào lắng nghe trên cổng 80.

Trên IP layer, tôi dùng iptables để "wwwect" như sau:
Code:
iptables -t nat -A PREROUTING -i eth0 -p tcp --syn -s any/0 -d $IP --dport 80 -j REDIRECT --toport 443

Làm như thế, khi một gói tin đi vào với đích là cổng 80 thì sẽ được iptables chuyển thẳng đến cổng 443. Khi gói tin này đi đến tầng application, nó không thể đi thẳng vào forum của HVA mà sẽ "khựng" lại ở hai chỗ:

a) chỗ thứ nhất khi request từ trình duyệt đòi hỏi dịch vụ ở cổng 80 nhưng lại được đưa đến cổng 443 (không qua cơ chế rewrite trên application layer nào cả), trình duyệt sẽ không tiếp tục đi vào. Người dùng "hợp lệ" sẽ nhận được thông báo đại loại là "bạn cần dịch vụ ở cổng 80 nhưng lại kết thúc ở cổng 443, dùng thế này không hợp lý. Đề nghị dùng https://hvaonline.net".

b) khi người dùng nhận được thông báo trên, đa số (99.9%) người dùng sẽ bấm theo đường dẫn https://hvaonline.net ở trên mà đi vào diễn đàn. Tuy nhiên, ở bước này trình duyệt lại "khựng" thêm một lần thứ nhì vì vấn đề ssl certification mà HVA dùng. Nếu HVA dùng CA certificate (do Verisign, Thawe....) cung cấp thì sẽ không có tình trạng này vì chìa khoá của HVA đã được xác thực bởi một CA và chìa khóa công cộng của CA nào HVA dùng đã có sẵn trong trình duyệt theo mặc định. Thực tế, HVA dùng "self cert", có nghĩa là HVA tự tạo cho mình "chìa khoá" và tự ký xác nhận cho mình luôn. Bởi thế, trong trình duyệt của người dùng không có gì để xác thực là chìa khoá của HVA đáng tin cậy nên nó lại "cảnh báo" người dùng trước khi họ tiếp nhận hay không tiếp nhận certificate này.

Với tình trạng DoS hiện thời, chỉ mỗi bước a) ở trên đã đủ ngăn cản đám "x-flash hợp lệ" kia. Nếu "chủ nhân" của đám x-flash sớm nhận ra điều này, anh chàng có thể đổi mục tiêu tấn công từ thành https://www.hvaonline.net. Tuy nhiên, bước b) trên sẽ tiếp tục cản đám x-flash vì các của request xuyên qua x-flash hoàn toàn chạy ngầm và người dùng không hề biết có x-flash đang thực thi (để tấn công HVA) nên việc xác nhận + chấp nhận ssl của HVA hoàn toàn không xảy ra ---> các cú x-flash ngưng lại ở đây.

Tôi restart lại firewall và apache sau khi thực hiện các thay đổi cần thiết. Nhìn đồng hồ, tôi chậc lưỡi "chà, trễ tàu rồi". Tuy nhiên, tôi yên tâm khi thấy server load của máy chủ HVA tụt xuống nhanh chóng và truy cập xuyên qua https với tốc độ tạm chấp nhận được. Tôi gởi JAL thông điệp "tình hình có vẻ ổn rồi đó bồ, tớ phải dzọt!".

Chuyện tiếp tục xảy ra những ngày sau đó? Mời bạn đón xem phần kế tiếp.

Các bạn có thể theo dõi tiếp phần 20 tại http://hvaonline.net/hvaonline/posts/list/511.html
Trưa 17/04/2005
Mấy ngày vừa qua HVA bị "dội" liên tục. Liệu tôi có nên tiếp tục gọi những trận DoS này là "x-flash" DoS nữa hay không? Tôi đặt câu hỏi này vì thông tin thống kê được từ IDS và các log files từ HVA server cho thấy chỉ có 1/3 các gói tin mạng thông tin "x-flash" trên header. Số lượng 2/3 các gói tin còn lại không mang bất cứ dấu tích gì thuộc về "x-flash". Tuy nhiên, payload của chúng hoàn toàn như nhau. Điều này tôi đã đề cập vài lần trong những bài ký sự trước đây nhưng tôi nhắc lại điểm này vì thấy rằng số lượng các gói tin không mang "x-flash" trên header giảm xuống rõ rệt.

Tôi đã thử trace ngược lại một số nguồn tấn công HVA ở dạng "x-flash" này và đã "đụng" phải khá nhiều proxy servers (được dùng để gởi x-flash đi đến HVA). Quả thật, một số proxy server này đã "lột" mất thông tin "x-flash" trên header của các cú POST và GET dùng để tấn công HVA trước khi gởi chúng ra ngoài. Điều này chứng tỏ người tạo ra các cú "x-flash" vẫn không hề chủ động với sự thay đổi của số lượng gói tin có "x-flash" (hoặc không có x-flash) trên header mà vẫn do các proxy servers đứng trên đường đi giữa các máy con và HVA server. Điều này cũng khiến cho việc ứng dụng các "matching pattern" để xử lý các cú "x-flash" (có và không không có trên header kia) cần được cụ thể hơn và có biên độ rộng hơn.

Hai ngày sau khi bài "ký sự" mới nhất được đăng lên trên diễn đàn HVA, một đợt tấn công mới đã tiếp tục xảy ra. Lần này, 100% các gói tin "đen tối" đi vào chứa các cú POST có nội dung sau:
Code:
POST / HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 719
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: www.hvaonline.net
Connection: Keep-Alive
Cache-Control: no-cache
total=8&Submit=Submit&attack=1&url1=http%3A%2F%2Fwww%2Ehvaonline%2Enet&typ=&url2=http%3A%2F%2Fwww%2Ehvaonline%2Enet&url3
=http%3A%2F%2Fwww%2Ehvaonline%2Enet&cena%5Fdo=&location=&wojewodztwo=0&catid=%40&custom%5Ffield%5F1=%40&submit%
5Fsearch=Search&submit%5Ffcheck=1&email=cakhuc%5Ftinhyeu%40yahoo%2Ecom&s=&do=emailpassword&url=http%3A%2F%2Fwww%2Eqvfc%
2Ecom%2Fforums%2Flogin%2Ephp®%5Fusername=hvaonline%40hvaonline%2Enet®%5Fpassword=trieutranduc%40hvaonline%
2Enet&username=admin&oldpsd=Casanova&emaila=trieutranduc%40hvaonline%2Enet&act=Search&CODE=show&searchid=
8842deef29382aa4339b084489437347&search%5Fin=posts&result%5Ftype=topics&highlite=&referer=http%3A%2F%2Fhvaonline%
2Enet&idx=&PassWord=hacker&CookieDate=1

Decode đoạn payload trở thành thế này:

total=8&Submit=Submit&attack=1&url1=&typ=&url2=&url3
=&cena_do=&location=&wojewodztwo=0&catid=@&custom_field_1=@&submit_search=Search&submit_fcheck=1
&email=cakhuc_tinhyeu@yahoo.com&s=&do=emailpassword&url=http://www.qvfc.com/forums/login.php®_username=hvaonline@
hvaonline.net®_password=trieutranduc@hvaonline.net&username=admin&oldpsd=Casanova&emaila=trieutranduc@hvaonline.net
&act=Search&CODE=show&searchid=8842deef29382aa4339b084489437347
&search_in=posts&result_type=topics&highlite=&referer=http://hvaonline.net&idx=&PassWord=hacker&CookieDate=1


Dường như "nhóm" tấn công HVA không hiểu nổi những điểm tôi đã đưa ra trong đoạn kết của bài ký sự lần trước, hoặc họ cố tình làm ngơ nó, hoặc muốn xác nhận điều tôi đưa ra có giá trị hay không. Từ các thông tin được lưu trên HVA, tôi có thể minh hoạ cho bạn một số chi tiết lý thú như sau:

- ngày thứ nhất của đợt tấn công mới nhất này, số lượng các gói tin "đen tối" ở dạng x-flash bị huỷ, cản, cho phép, đi vào black hole.... có tổng số là 2.735Gb.

- ngày thứ hai, con số này tăng lên thành 3.557Gb

- ngày thứ ba, con số này giảm xuống còn 1.78Gb

Những thông tin sau không nhằm mục đích minh hoạ tác hại đến máy chủ HVA mà để nhấn mạnh độ phí phạm băng thông của trò chơi quái gở này. Con số 3.557Gb cho một ngày tương đương (hoặc hơn) mức ấn định bình thường của một web site ở dạng dịch vụ host ("share hosting") cho một tháng. Nếu bạn tò mò thì tôi xin tiết lộ rằng trong lúc HVA bị DoS cao điểm nhất, server load chưa bao giờ lên quá giới hạn 1.0.

Ngay trong lúc HVA "bị" DoS cao điểm nhất, tôi nhờ JAL thử liên hệ một số thành viên ở VN để hỏi thăm tình hình truy cập vào HVA nhanh, chậm thế nào. Tôi được biết hầu hết các thành viên dùng VDC và FPT ít nhiều bị ảnh hưởng vì gateway đi ra ngoài (để đến HVA tràn ngập những gói tin dành tấn công HVA). Để phần nào giải quyết tình trạng này, tôi quyết định mở rộng thêm giới hạn "connection limit" gấp đôi số lượng mặc định. Số lượng mặc định được hình thành qua nhiều phân tích mức độ truy cập hợp lệ ở mức bình thường đến HVA; kết quả tìm được nhân 3 lần (để trừ hao trường hợp các gói tin bị hủy và cần được gởi lại - nếu có). Sau thay đổi này, tôi nhận được hồi báo từ nhiều thành viên cho biết tình trạng truy cập hơi chậm hơn bình thường một tí và chấp nhận được.

Liên tục trong ba ngày, tôi thâu thập được khá nhiều thông tin lý thú. Ví dụ, có một host (có lẽ đây là một proxy server) đi từ thư viện địa phương của một thị trấn thuộc tiểu bang California, host này liên tục gởi các gói tin tấn công HVA suốt 8 giờ đồng hồ. Đôi lúc, tôi chột dạ và cho rằng đây là một hệ thống "DoS" tự động. Tuy vậy, sau khi lọc và hình thành các thông tin cụ thể cho host này, tôi lại tin rằng các gói tin đi từ host này là do nhiều người dùng bởi vì độ gián đọan giữa các đợt packet gởi đi mang nặng "tính người".

Tôi cũng thấy có rất nhiều thông tin lý thú khác. Ví dụ, độ gia giảm của các gói tin tấn công HVA tùy thuộc vào múi giờ. Có những gói tin đi từ Hoa Kỳ, Canada, rồi từ Bắc Âu, từ Đông Âu, xuất phát từ Nga, từ Trung Quốc và rồi từ các nước Đông Nam Á như Mã Lai, Nam Dương. Các gói tin xuất phát từ Úc, Tân Tây Lan.... Nếu tính theo múi giờ, thời gian cao điểm của mỗi vị trí này thường xảy vào ban đêm. Điều này cũng dễ hiểu nhỉ? smilie

Cuối ngày thứ 3, các cú POST ở trên giảm dần và tắt hẳn. "Chủ nhân" của các trận DoS này nghĩ gì? tôi không rõ nhưng tôi biết chắc một điều, "chủ nhân" này không mấy vui thích vì chẳng thấy được kết quả gì cho rõ ràng. Sáng nay, tôi "bắt" được một đợt POST mới, rất thưa thớt và không đáng kể. Chúng có payload như sau:
Code:
POST /forum/index.php HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 697
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; (R1 1.5); .NET CLR 1.0.3705)
Host: hvaonline.net
Connection: Keep-Alive
Cache-Control: no-cache
total=506&Submit=Submit&attack=1&url1=http%3A%2F%2Fhvaonline%2Enet%2Fforum%2Findex%2Ephp&url2=http%3A%2F%2Fhvaonline%2Enet%
2Fforum%2Findex%2Ephp&url3=&cena%5Fdo=&location=&wojewodztwo=0&typ=&catid=%40&custom%5Ffield%5F1=%40&submit%
5Fsearch=Search&submit%5Ffcheck=1&email=cailon%40concac%2Ecom&s=&do=emailpassword&url=http%3A%2F%2Fhvaonline%2Enet%2Fforum%
2Flogin%2Ephp®%5Fusername=support%40hvaonline%2Enet®%5Fpassword=concac%40cailon%
2Enet&username=admin&oldpsd=Casanova&emaila=trieutranduc%40hvaonline%2Enet&act=Search&CODE=show&searchid=
8842deef29382aa4339b084489437347&search%5Fin=posts&result%5Ftype=topics&highlite=&referer=http%3A%2F%2Fhvaonline%
2Enet&idx=&PassWord=hacker&CookieDate=1

Bạn thấy payload ở trên và payload này có những gì khác nhau? Chúng khác nhau đấy và.... "cay" hơn đoạn trước. Bạn thử decode payload này xem có gì thú vị? . Bạn đừng hiểu lầm những trận "x-flash" kia là thú vị, ý tôi cái "thú vị" ở đây chỉ nằm trong những payload có phần nào phảng phất trạng thái tinh thần của "chủ nhân" của chúng.

Tôi e rằng những trận tấn công "x-flash" này vẫn sẽ còn tiếp diễn. Hết GET sẽ sang POST, hết POST trở lại GET. Nên chăng tôi than thở rằng "chống đỡ" những trận DoS này vất vả quá để tay "chủ nhân" "động lòng" từ bỏ trò chơi quái đản này? Nên chăng tôi "xúc thêm" để còn những bài "ký sự" khác tiếp tục? Tôi e rằng, chừng nào "chủ nhân" của các cú "x-flash" kia còn chưa hiểu nổi chuyện gì đã xảy ra với HVA trong mấy ngày qua (tôi chắc rằng "chủ nhân" này đã vào thử HVA để xem tình hình trong suốt thời gian này), chừng ấy những trận DoS sẽ vẫn còn tiếp diễn. Biết đâu chừng, HVA sẽ phải tiếp tục đón nhận những trận DoS này và nó sẽ trở thành một chuyện bình thường cho đến khi nào người "chủ nhân" ấy thực sự... grown up smilie.

Các bạn có thể theo dõi tiếp phần 19 tại http://hvaonline.net/hvaonline/posts/list/510.html

Trưa 4/4/2005
Mấy ngày vừa qua (từ ngày 28/3/2005) các trận DoS tấn công HVA "thưa dần rồi tắt hẳn", hay nói một cách khác, "thưa dần rồi tạm tắt".

Trưa nay, với mấy phút còn lại của giờ nghỉ trưa, tôi log vào HVA diễn đàn để xem qua và thấy truy cập diễn đàn thật chậm. Một trận tấn công mới? Tôi vội log vào HVA xuyên qua SSH và vất vả lắm (3 lần log vào) mới vào được. Tôi thật ngạc nhiên khi thấy server load khá thấp:

# w
load average: 4.25, 5.52, 4.96


Nhưng tại sao chậm thế này nhỉ? Tôi không tin đường dây sử dụng Internet của công ty có sự cố và bị chậm. Tuy nhiên, để xác thực tình hình, tôi gọi điện nhờ một người bạn kiểm tra dùm và như tôi dự đoán, tay bạn cho biết là vào HVA cực kỳ chậm. Tôi thử kiểm tra tình hình của web service bằng lệnh:
Code:
# ps -ef | grep httpd | wc -l
257

Ôi chao, apache đã dùng tới mức tối đa cho phép của "MaxClients" là 256 processes và rõ ràng những processes này hoàn toàn bị chiếm hết và liên tục được sử dụng. Tôi mở một cái "tail" đến log file của apache và ngay lập tức, hàng loạt các cú GET có dạng:
/forum/?file=hvaonline_net&url=http%3A%2F%2Fhvaonline%2Enet%2Fforum%2F%3Ffile%3Dhvaonline%5Fnet&t=3660%260%2E372
đang hối hả "dội" đến HVA. Điều đáng chú ý ở đây là tính đơn giản nhưng cụ thể của request URL. Rõ ràng các cú GET này được tạo ra để tấn công cụ thể đến HVA.

Sau vài phút, tôi thử kiểm tra lại số lượng httpd process đang chạy, vẫn 257. Điều này chứng tỏ các process này đã bị "max out" tối đa nhưng lại không tạo ảnh hưởng mấy đến database server. Có lẽ ứng dụng trên mod_security của lần trước đã "bao" luôn trường hợp này. Tôi mở cấu hình của apache ra và chỉnh sửa lại giá trị "Keep-alive" timeout ngắn bớt lại chỉ còn 1/3 giá trị nguyên thuỷ với mục đích "ép" các cú GET này đang dùng "keep-alive" phải chấm dứt sau một khoảng thời gian nào đó để tạo điều kiện cho người dùng khác có thể vào. Sau khi restart lại apache và tiếp tục theo dõi, tôi nhận thấy tình hình không cải thiện được bao nhiêu. Khi duyệt HVA forum, có quá nhiều khoảng đứt đoạn và vẫn rất chậm. Tôi phóng ngay một cú tcpdump để lấy thông tin phân tích xem sự thể ra sao.

Trong khi tcpdump đang chạy, tôi trầm ngâm suy nghĩ "nếu những cú GET này có thể đi xuyên qua được bức cản connection limit và rate limit thì có nghĩa số lần gởi phải thấp hơn quy định cản trên firewall không thì chúng đã bị firewall DROP ngay từ bên ngoài." Sau 2 phút, tôi dừng tcpdump, nén kết quả sniff được và tải về máy của tôi. Tôi nhận thấy cú GET với URL kia chưa rõ nội dung là gì như rõ ràng nó không thuộc một URI hợp lệ nào của HVA cả. Chắc chắn nó sẽ được "wwwect" về trang mặc định của HVA và làm như thế, số query đến server vẫn xảy ra --> tạo server load. Tôi quyết định lập thêm một rule trên mod_security để cản cú GET mới này.

Vẫn chưa thoả mãn với tình trạng bị "maxed out", tôi bắt tay ngay vào điều chỉnh số "MaxClients" được "hardcoded" trong httpd.h là 256 (vì tôi không thể gia tăng quá con số này trên cấu hình httpd.conf) và biên dịch lại apache. Công việc này chỉ mất chưa tới 5 phút trên HVA server (xeon CPU có khác!). Tôi điều chỉnh lại giá trị MaxClients thành 512 và restart lại apache. Lần này, khi theo dõi số lượng child process được apache tạo ra tôi thấy nó không gia tăng quá nhanh chóng sau khi vượt khỏi con số 257. Cứ mỗi 5 phút lại có thêm chừng 2 child process mới. Điều này chứng tỏ số lượng IP dùng để tạo các cú GET không gia tăng (hoặc gia tăng rất ít). Hy vọng người dùng có thể tiếp tục vào được diễn đàn HVA ở tình trạng tạm thời "cầm cự" thế này cho đến tối, khi tôi rảnh rỗi hơn để có thể điều chỉnh xác thực hơn.

Mới đó mà đã hết giờ ăn trưa và trước mắt tôi là một mớ công việc kinh khủng cần phải giải quyết. Tôi thở dài, chỉnh lại firewall để hạn chế số lượng connection. Khởi động lại firewall, tôi hy vọng với hạn chế này cộng với rule mới cho mod_security sẽ giảm thiểu tác hại của các cú GET tai quái (nhưng hợp lệ) kia. Tôi phải quay lại với mớ công việc đang bề bộn ở sở làm.

Chiều 4/4/2005
Đã gần đến giờ tan sở, tôi vào thử HVA lần nữa. Tình hình vẫn không khá hơn bao nhiêu. Tôi thử log vào HVA server bằng SSH, kẹt cứng! không vào được. Tôi thử đi thử lại cả chục lần cũng không được. Chẳng lẽ lão JAL đã rút dây cắm luôn sao? smilie. Từ SSH console tôi dùng để tunnel từ nhà, tôi thử nmap HVA và biết chắc nó vẫn còn online. Tuy nhiên có quá nhiều packets bị hủy (lost). Tôi chậc lưỡi "không lẽ trận DoS này đã saturate luôn cả đường dây Internet của HVA sao?". Còn 10 phút nữa tan sở, tôi quyết định tạo tunnel từ sở về máy ở nhà và tạo đường ra để connect với YIM (xuyên qua tunnel). Tôi log on YIM và lão JAL đang "vàng khè" trên danh sách YIM. Tôi gởi vội cho lão một thông điệp vào báo rằng tôi không vào SSH được. Cả hai chúng tôi đều đoán rằng có lẽ đường dẫn Internet của HVA đã bị saturate hoặc máy chủ HVA quá bận rộn (ít nhất là trên socket) nên tôi không log vào được. Tôi đề nghị lão JAL tắt bỏ apache, tắt bỏ luôn monit để tránh không cho nó tự động restart lại apache. Tôi vẫn vào không được! JAL đã thử restart lại server hai lần và ngưng hẳn apache nhưng tôi vẫn không thể vào được. Dường như ngay khi máy chủ HVA online, đường dẫn của nó bị ngập ngụa các packets tấn công hoặc có thể nó đang bị tấn công bởi một dạng khác. Tiếc thay tôi không thể làm gì được lúc này.

Tình hình xem ra gay go. Tôi than thầm "hèm, trúng ngay một ngày bận rộn mà chơi thật ác". Trước khi rời sở, tôi đề nghị JAL điều chỉnh lại trọn bộ chế độ logging của firewall để giảm thiểu số lượng logs đang được tạo ra với cơn lũ DDoS đang ập vào HVA server. Tôi đề nghị JAL tạm ngưng ở đó, khi tôi về đến nhà tối nay, tôi sẽ liên lạc với JAL qua YIM và tiếp tục xử lý. Tôi xếp laptop lại, phóng nhanh ra cửa để kịp chuyến tàu.

Trên tàu, trên đường về nhà, tôi mở mảnh tcpdump lấy được lúc trưa để xem xét. Tôi thấy ngay một lượng GET khổng lồ đã ập vào HVA server từ hàng trăm IP (từ VN và nhiều nơi khác trên thế giới). Cú get có nội dung và header như sau:
Code:
GET /forum/?file=hvaonline_net&url=http%3A%2F%2Fhvaonline%2Enet%2Fforum%2F%3Ffile%3Dhvaonline%5Fnet&t=3660%260%2E37203 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: hvaonline.net
Connection: Keep-Alive
Cookie: session_id=74814b8ff967ad0d282ed5945d39276a


Đoạn trên cho chúng ta những thông tin gì? quả là không nhiều. Trước tiên ta thấy cú GET này hoàn toàn không có thông tin nào về x-flash cả. Đây là lý do tại sao chúng đi xuyên qua firewall và không hề bị cản trở (ngoài số requests vi phạm luật connection limit). Kế tiếp, giá trị request được "pass" qua URL hoàn toàn không vi phạm luật bảo mật đã được áp đặt trên HVA server (cho các vấn đề thuộc về xss, buffer overflow, sql inject....). Các giá trị request được "urlencoded" hoàn toàn đúng quy cách. Decode đoạn request trên cho kết quả như sau:

/forum/?file=hvaonline_net&url=http://hvaonline.net/forum/?file=hvaonline_net&t=3660&0.37203

Đây là lý do tại sao chúng lại tiếp tục đi xuyên qua các cơ chế cản lọc ở tầng application và "tàn phá". Có lẽ sau khi tôi áp dụng một rule mới trên mod_security đã giảm thiểu loại GET này nhưng server tiếp tục bị tấn công bằng phương thức khác. Lúc nãy JAL cho tôi biết cổng 25 (SMTP) của HVA server cũng có hàng đống request nhưng không chắc phải do DoS hay không.

Tôi tiếp tục duyệt qua đoạn tcpdump, đoạn này chỉ chạy trong 2 phút lúc trưa nhưng sau khi liệt kê thông tin trong đoạn này, tôi tổng kết có khoảng trên 75 ngàn cú GET đến HVA server trong 2 phút ngắn ngủi và đi từ ít nhất 400 IP khác nhau. Tôi trầm ngâm nghĩ ngợi và hình thành 2 trường hợp có thể xảy ra với HVA từ trưa nay:

1) loại GET ở trên bị loại trừ và một (hoặc nhiều loại khác) đang tấn công HVA mà tôi chưa rõ là dạng nào.
2) lối cản bằng mod_security đã tạo ra "phản ứng phụ" như tôi đã trình bày trong phần cuối của bài ký sự lần trước.

Cả hai giả định này đều có thể xảy hoặc có thể đang cùng xảy ra.

Hãy thử phân tích trường hợp 1 trước.
- Nếu HVA đang bị tấn công bằng một dạng (hoặc nhiều dạng GET) khác thì có nghĩa là màng lưới phòng thủ trên HVA không cản lọc hết hoặc không hề cản lọc.
- Nếu các cú GET ở dạng khác dạng GET ở trên và không hề mang thông tin gì chứng tỏ nó là x-flash thì chắc chắn nó được đi xuyên qua firewall và tất nhiên snort cũng chẳng có gì để thông báo.
- Nếu các cú GET này không hề vi phạm các luật cản lọc của mod_security, chúng sẽ tiếp tục đi vào.

Điều này cho thấy nếu mod_security định chỉnh định chặt chẽ hơn và sâu sát hơn cho cấu trúc của web application chạy trên HVA, trường hợp những cú GET "đen tối" nhưng "hợp lệ" sẽ giảm thiểu. Đây là điều mà thôi đã đề cập trong bài "ký sự" lần trước về việc sắp xếp và chỉnh định lại web application của HVA để loại bỏ phần lớn những khả năng tấn công "một cách hợp lệ" của DDoS. Nói cho cùng, mod_security đã không phải là một tấm màn che cốt lõi trong các tầng phòng thủ của HVA. Tôi vẫn rất e ngại khi phải dùng các hệ thống cản lọc trên application layer vì lý do hiệu xuất nhưng nếu cần phải dùng đến nó để gia tăng độ chặt chẽ của "vòng đai phòng thủ" thì cũng phải dùng vậy. Nhưng có lẽ phải tối ưu dạng ứng dụng này đến mức tối đa có thể được. Thực tế lúc này tôi chưa dùng mod_security cho mục đích bảo vệ ở bình diện DoS và sự thể đã quá hiển nhiên.

Với trường hợp 2, tôi e rằng ứng dụng mod_security hồi trưa nay đã tạo những "phản ứng phụ". Phản ứng phụ ở đây là hàng loạt các cú FIN mà mod_security tạo ra để kết thúc những cú GET "đen tối" tạo ra. Như đã phân tích ở cuối bài "ký sự" lần trước, bởi mod_security thực thi các bước cần thiết và đúng quy định trên giao thức TCP nên chính nó đã bị sức ép về mặt tài nguyên để thực thi. Tôi hình dung ra hàng ngàn sockets đang ở tình trạng FIN-WAIT-1, FIN-WAIT-2 và TIME-WAIT đang hiện diện trên HVA server lúc này. Nói về mặt tài nguyên (như memory, disk space, bandwidth) thì HVA server đủ sức để chống chọi ít nhất vài giờ nhưng tình trạng sẽ trở nên tệ hại nếu như số lần mod_security thực thi để kết liễu các cú GET kia càng tăng. Quả thật, đây là điều tôi lo ngại hơn hết bởi vì sức ép của tình trạng dần dần cạn kiệt tài nguyên chắc chắn sẽ xảy ra nếu như không có một phương pháp nào giải quyết nhanh chóng hơn là phó mặc vào cơ chế triệt bỏ các cú GET của mod_security. Tuy những cú GET này không thể đi sâu hơn vào hệ thống để tạo server load nhưng nói về mặt tác dụng của mục đích DoS, nó có tác dụng hơn những cú POST chậm chạp kia. Những cú POST có thể đạt được ở mức tối đa và có thể đụng tới giới hạn số connection database server cho phép rồi dừng lại ở đó (vì không thể đi xa hơn). Với những cú GET kia và với số lượng IP dày đặc nhằm dung hoà đường dẫn của HVA thì tình hình nằm trên phương diện hoàn toàn khác.

Trước mắt tôi e rằng số lượng "MaxClients" trên apache có thể đã "maxed out". Điều này có nghĩa rất ít cơ hội người dùng hợp lệ có thể vào được diễn đàn HVA vì số lượng "MaxClients" đã tới giới hạn và gần như bị những cú GET tai quái kia chiếm giữ. Vậy, điểm cốt lõi ở đây là làm sao giải toả tình trạng bị "maxed out" ở trên, làm sao "discard" được những cú GET đi vào nhanh như vũ bão kia. Từ khoá "discard" đã cho tôi ngay một đáp án. Tôi chưa hình thành ngay được phương pháp cụ thể làm thế nào để giải toả nhưng tôi tự gật gù sau khi nảy ra cho mình một hướng giải quyết.

Tối 4/4/2005
Cơm nước xong, tôi phải dành nửa giờ để kiểm soát bài vở của thằng cu con. Khi mọi chuyện đâu vào đó thì đã 8 giờ tối nơi tôi cư ngụ, chừng 6 giờ chiều giờ máy chủ. Đối với người dùng, diễn đàn HVA đã offline hơn 2 giờ.

Tôi thử log vào HVA server bằng SSH. Vẫn không vào được! Mở YIM lên, JAL đang online, có lẽ lão đang sẵn sàng tác chiến smilie. Tôi gởi JAL một thông điệp đề nghị chỉnh firewall để block luôn cổng 80, không cho phép bất cứ request nào đi vào được trong máy. JAL thực hiện ngay việc này nhưng... tôi vẫn không thể log vào cổng SSH trên HVA server. Cha chả, tôi ngầm đoán lần này HVA bị tấn công với số lượng IP chưa từng có. Cứ cho mỗi IP chỉ gởi 3 request trong một giây và có 5, 7 trăm hoặc cả ngàn IP cùng gởi một lượt thì có thể đường dây Internet của HVA bị dung hoà (saturated).

Tôi lại đề nghị JAL đóng luôn cổng SMTP và cổng SSH nhưng mở lại SSH trên một cổng hoàn toàn khác xem sao. Sau một phút, JAL hồi báo cho biết là đã thực hiện xong đề nghị của tôi. Tôi thử log vào HVA xuyên qua cổng SSH "mới" và quả nhiên, tôi log vào được. Vẫn còn rất chậm nhưng điều quan trọng là tôi đã có thể vào HVA server. Tôi thử bắt đầu điều chỉnh HVA server nhưng nhận ra ngay là không thể làm việc trong tình trạng như thế này để khắc phục nhanh chóng tình trạng hiện thời của HVA bởi vì những gì tôi gõ hoặc duyệt trên console mất quá nhiều thời gian để thực thi. Tôi quyết định nhờ JAL triển khai dùm các bước (vì lão ngồi ngay trước server nên không bị tình trạng chậm như tôi).

Trong khi trao đổi thông tin với JAL để lão điều chỉnh trên server, tôi tranh thủ điều chỉnh một số chi tiết khác. Tôi mất hơn 20 phút để điều chỉnh lại cấu hình của apache, thêm 15 phút để điều chỉnh lại firewall và kiểm tra chế độ log. JAL đã hoàn tất các điểm tôi đề nghị JAL chỉnh sửa từ lâu, còn tôi phải gần 1 giờ trôi qua mới kết thúc mọi việc. Trong lúc tôi kiểm tra và điều chỉnh lại những điểm quan trọng trên HVA server, JAL signed off YIM nhưng trở lại sau vài phút.

Tôi bảo JAL: "bồ sẵn sàng chưa? hãy khởi động lại các dịch vụ!"

JAL cười, đáp lại: "có tự tin không đó lão?"

Tôi đáp: "cùng lắm là rút dây ra đi ngủ cho ngon giấc thôi ".

Và... thế là chúng tôi khởi động lại các dịch vụ cần thiết. Thật tuyệt! server load không những giảm xuống mà giảm thật nhanh. Giá trị lấy từ # netstat -nat | grep TIME_WAIT tụt xuống từ trên 4000 ngàn còn lại vài chục trong mấy phút đồng hồ. Nhìn trên cái stats của server, tôi tủm tỉm cười một mình vì từ khoá "discard" tôi nảy ra trong đầu khi đang ở trên tàu lửa chiều nay quả thật ứng hiệu ngoài ý muốn. Điều đáng chú ý là ngay lúc apache khởi động lại, tôi phát hiện ra hàng loạt "x-flash" ở dạng GET (phối hợp với vài dạng x-flash khác) và có request rất ngắn gọn như sau:

GET /forum/index.php?

Tuy nhiên, những cú GET này đã được chuyển hướng đến một nơi khác và không có cơ hội đi vào HVA forum. Bạn có thể thắc mắc tại sao các request ở dạng /forum/index.php? lại không thể đi vào HVA forum, nếu thế thì cả những request từ người dùng hợp lệ cũng sẽ bị "hoá giải" cả sao? Điều tôi có thể tiết lộ ở đây là một request thiếu hợp lệ được gởi từ "x-flash" có tính chất khác biệt so với request gởi từ trình duyệt bình thường (như Internet Explorer hoặc FireFox...). Nếu bạn dùng packet sniffer để bắt lấy một đoạn thông tin và thử phân tích kỹ lưỡng, bạn sẽ nhận ra điều này. Sự khác biệt không những từ thông tin biểu thị x-flash (nếu có) mà còn ở một số thông tin khác trên HTTP header. Tính đặc biệt này đã không được ứng dụng để "cản" các cú "x-flash" ở tầng IP (trên iptables) bởi vì dẫu có nhận ra, iptables cũng không thể xử lý được chúng (ngoại trừ có một iptables module chuyện dụng cho vấn đề này, nhưng tôi e rằng nó không tuyệt đối hiệu quả). Sau khi ứng dụng mod_security, các gói tin đi đến tầng HTTP và mang tính chất đặc biệt này đã bị xử lý một cách dễ dàng vì chúng ở trên cùng một tầng giao thức.

Rất tiếc tôi không / (chưa) có thể tiết lộ chi tiết kỹ thuật của phương pháp ứng dụng lúc này vì nhiều lý do nhạy cảm. Tuy nhiên, tôi có thể gợi ý một điểm cốt lõi: nếu bạn phải cản một nguồn lực đẩy vào, bạn sẽ hao tổn sức lực. Nhưng nếu bạn cho phép nó vào và dẫn nguồn lực này đến một nơi không gây tác hại, không gây "phản ứng phụ" thì bạn không còn bị hao tổn. Nguyên tắc này hoá giải hàng ngàn sockets ở dạng "orphans" trên HVA server. Chẳng những thế, sau đó nó không còn bất cứ cơ hội để tạo thêm "orphan" nào trên socket vì "4 bước kết thúc" xuất truy cập hoàn toàn không xảy ra đối với các gói tin vi phạm. Tất nhiên các xuất truy cập hợp lệ vẫn hoạt động bình thường và đúng quy định của giao thức.

Mười lăm phút trôi qua, server load của HVA xuống còn 0.5 trong khi mớ log của snort vẫn tường trình các cú x-flash đổ vào như nước. Ngay lúc các dịch vụ trên HVA khởi động lại, tôi và JAL cùng log vào diễn đàn HVA (bằng FireFox). Có lẽ JAL cũng như tôi, cũng nhẹ nhõm khi thấy vận tốc duyệt diễn đàn có phần nhanh hơn trước. Phải chăng tôi tưởng tượng?

Tôi gởi JAL một thông điệp: "thôi, tớ đi ngủ đây!" và logoff.

Các bạn có thể theo dõi tiếp phần 18 tại http://hvaonline.net/hvaonline/posts/list/508.html
Hello hmnm,

Cảm ơn bạn đã đăng bài viết hữu ích này. Tuy nhiên, nếu có thời gian, bạn nên "định dạng" lại bài viết để mọi người tiện việc tham khảo hơn.

Thân.
Sáng sớm 28/3/2005
Cả buổi chiều hôm qua đến khuya, tôi không hề động đến cái laptop. Lại chạy lăng xăng, lại nhậu lai rai và lại "nửa say, nửa tỉnh" (đúng là lễ Phục Sinh có khác smilie). Mãi đến 2 giờ sáng ngày 28/3/2004, tôi nhận được một cú gọi từ công ty vì hệ thống máy chủ bị sự cố. Sự cố này khá đơn giản, tôi chỉ mất hơn 5 phút để tìm ra nguyên nhân và chỉnh sửa ngay. Sẵn tiện, tôi thử vào HVA forum xem sao.

Chậc, lại chậm rì thế này. Chắc chắn là chậm hơn hồi chiều hôm qua ngay lúc tôi ngồi tẳn mẳn với mớ log và packet dump. Tôi quyết định log nhanh vào HVA server để xem qua tình hình (mặc dầu lúc này não bộ của tôi muốn nghĩ ngơi). Tôi log vào HVA server khá dễ dàng, hơi chậm nhưng chỉ một lần là được. Tôi thấy server load không cao, số lượng process được tạo trên server quả nhiều hơn bình thường khá nhiều (và đây là chuyện hiển nhiên) nhưng request từ FireFox vẫn rất chậm. Tôi trầm ngâm "phải thực hiện việc chỉnh sửa lại firewall rule không thì kẹt". Ngay lúc log vào HVA server, tôi cũng nhận ra lão JAL đang ngồi chễm chệ với một console và có lẽ cũng đang dán chặt đôi mắt vào mớ thông tin từ apache log. Tôi định gởi cho lão một message nhưng lại thôi.

Cách khắc phục tình thế nhanh nhất lúc này là phải huy động đến chức năng SecFilterScanPOST On của mod_security (xem thông tin ở chú thích -41-) và chỉnh tạo lại một số rules cụ thể cho mod_security để cản mớ x-flash dai dẳng kia. Tôi nhẩm tính thật nhanh, 1) mở chức năng này của mod_security lên sau khi chỉnh vài cái rules cho nó 2) restart lại apache để ứng hiệu chức năng này 3) chỉnh lại firewall rule để mở rộng connection hơn (để tạo điều kiện cho người duyệt HVA có thể vào). Có lẽ tôi chỉ mất vài phút để thực hiện các bước trên. Nói là làm, tôi thực hiện ngay chuyện này và sau 3 phút, mọi chuyện đã hoàn tất. Tôi dùng FireFox để duyệt HVA forum thử lần nữa và thấy tình hình khả quan hơn nhiều.

Thật sự mà nói tôi không muốn lệ thuộc hoàn toàn vào chức năng SecFilterScanPOST để làm bức màn cản lọc vì lý do hết sức đơn giản: tôi không muốn hiệu năng của HVA server bị giảm thiểu. Một khi filter này được dùng, không có thứ gì trong mớ payload của các cú POST có thể tránh khỏi "bị" mod_security xét duyệt. Nói trên bình diện bảo mật thì đây là chuyện tốt. Tuy nhiên, cái giá phải trả, theo tôi, là quá đắt vì nó làm giảm hiệu năng của web service một cách đáng kể. Để ứng hiệu SecFilterScanPOST một cách tối ưu đòi hỏi một số thay đổi căn bản trên web application mà HVA đang dùng và đây là công tác lâu dài. Trong hoàn cảnh HVA đang bị "dội" dồn dập như thế này, trách nhiệm rà tìm và cản lọc của mod_security sẽ tạo ra hai vấn đề:

1) không thể có một cú x-flash POST nào có thể đi vào đến apache, cho nên việc tác động đến database query (để tạo load trên server) là chuyện sẽ không xảy ra. Đây là chuyện tốt.

2) bởi vì SecFilterScanPOST phải rà cản payload của từng cú POST, mọi request đến apache đều chậm lại (kể cả đối với người dùng hợp lệ). Đây là chuyện không tốt cho nên cần phải điều chỉnh và tối ưu hoá.

Đã 2 giờ rưỡi sáng. Tôi phải ngưng ở đây (dù ngày mai vẫn là ngày lễ "Happy Monday Easter"). Tôi xếp máy lại.

Trưa 28/3/2005
Trưa nay tôi có vài giờ để thong thả tiếp tục táy máy với HVA server. Tôi log vào HVA forum bằng FireFox và vào HVA server bằng SSH. Tình hình không khác gì sáng sớm nay khi tôi "dựng" SecFilterScanPOST lên. Hay nói một cách khác, server load không hề lên quá 2.0 và truy cập vẫn chậm hơn bình thường. Đây là chuyện hiển nhiên vì mọi cú request đều bị rà cản.

Tôi trở lại mớ firewall rule cần phải cải thiện (như đã đề cập trước đây). Có hai điểm khá nghiêm trọng mà tôi cần phải chỉnh sửa đó là: 1) thứ tự của các rule giới hạn connection và các rule cản lọc x-flash cụ thể 2) phân tích và ấn cụ thể "chiều dài" và tính chất của các gói tin được thẩm sát và cản lọc. Tôi không muốn đi sâu vào chi tiết cấu trúc các rules này vì tính bảo mật cũng như tính nhạy cảm của chúng nhưng tôi có thể chia xẻ với bạn những điểm trọng yếu về mặt nguyên tắc như sau:

- thứ tự của các rules: một chi tiết tôi đã không áp đặt một cách tỉ mỉ trước đây nhưng bây giờ đã trở thành một vấn đề hết sức rõ ràng và cần phải khắc phục. Trên nguyên tắc, thứ tự các firewall rule nên được sắp xếp để bảo đảm tối đa tính bảo mật và hiệu năng của nó. Trong trường hợp này, lưu thông đến cổng 80 là lưu thông chính đến HVA server. Cho nên, luật cho phép cũng như cản lọc các gói tin đến cổng 80 phải ở mức ưu tiên. Đây là điều tôi đã hình thành ngay từ đầu. Tuy nhiên, thứ tự của các luật giới hạn connection và luật cản lọc x-flash cụ thể đã không nằm đúng thứ tự dẫn đến tình trạng quá nhiều gói tin không được kiểm soát đúng mức khi cơn lũ "x-flash" ập vào.

- "chiều dài" các gói tin được kiểm soát để loại trừ x-flash: mặc dù đã ứng dụng "pattern matching" để cản lọc x-flash ở tầng thấp nhất (vì lý do hiệu năng), tôi chưa hoàn chỉnh các luật này để tối ưu hoá chúng. Đối với bình diện "pattern matching", việc thâu hẹp biên độ tìm kiếm "pattern" trong một packet là điều tối quan trọng bởi vì những pattern này phải được nhận diện và xử lý với tốc độ tối đa. Trong tay tôi đã có đầy đủ các thông tin biểu thị "chiều dài" nói chung của các cú "x-flash" kia, vấn đề còn lại cần phải giải quyết là "giúp" firewall thâu hẹp biên độ tìm kiếm -58-.

Tôi bắt tay vào thực hiện ngay phương án đã định. Sau mười lăm phút liệt kê sẵn thông tin và chỉnh sửa lại firewall, tôi hài lòng với những gì đã được hình thành. Khởi động lại firewall, tôi náo nức chờ xem kết quả thế nào. Mở một cái "tail" để theo dõi diễn biến trên syslog, thôi không hề thấy bất cứ thông điệp nào thuộc dạng Packet too big to attempt sublinear string search như đã dẫn trước đây. Một dấu hiệu tốt đầu tiên! Kế tiếp, tôi theo dõi server load bằng tiện ích top và thấy server load hạ xuống đáng kể. Dấu hiệu đáng mừng tiếp theo!

Tôi mở FireFox ra và thử duyệt HVA forum. Tình hình đã khá hơn rất nhiều. Tuy nhiên, chắc chắn vẫn còn dăm ba tiểu tiết có thể nắn sửa để cải thiện hơn nữa. Tôi điều chỉnh thêm vài chi tiết trên firewall và apache, xem xét lại một số tcp settings ở kernel level rồi restart lại apache. Thêm mười lăm phút trôi qua, lúc này tốc độ duyệt HVA forum gần như đã trở lại mức bình thường (được xác thực bằng load stat của forum) mặc dù cơn lũ x-flash vẫn đổ vào đều đặn. Tôi hài lòng với hơn một giờ đồng hồ táy máy với HVA server.

Có lẽ bạn vẫn còn thắc mắc việc tôi đề cập trước đây: "Tôi tìm ra không chỉ một mà là hai điểm hở khiến cho các cú x-flash có thể vuột qua hàng phòng thủ nếu như số lượng x-flash đạt tới mức dồn dập nào đó và nếu như apache đã cho phép "keep-alive". Thực trạng lúc này đều thoả mãn cả hai điểm nếu như ở trên". Điểm lại những chi tiết tôi vừa trình bày ở trên, bạn hẳn thấy firewall không hoàn toàn hiệu xuất và đã được chỉnh sửa. Lý do trọng yếu cho tính "thiếu hiệu xuất" này ở chỗ "pattern matching" ở IP layer không phải là một giải pháp vẹn toàn. Có thêm nó là một điều hay nhưng không thể trông cậy hoàn toàn ở nó. Lý do, có những packets quá lớn và modules dùng để kiểm tra "pattern" trong một packet từ chối kiểm tra. Giới hạn này có lý do hoàn toàn hợp lý khi từ chối không kiểm tra gói tin quá lớn: tính hiệu xuất. Nếu một luật đi theo để cản những gói tin quá lớn (vì không kiểm tra được) thì mức độ false positive (cản nhầm gói tin hợp lệ) quá cao. Các gói tin quá lớn này đã được phép đi qua khỏi hàng rào cản của firewall. Trong số này, có khá nhiều các gói chứa x-flash tấn công HVA. Đây chính là lý do server load của máy chủ HVA lên cao.

Lý do apache cho phép "keep-alive" là vì mục đích nâng cao hiệu xuất cho người dùng (hợp lệ). Trước đây tôi đã phân tích vấn đề này khá chi tiết, nếu thích, bạn nên đọc lại các bài trước đây. Tuy nhiên "keep-alive" là con dao hai lưỡi bởi vì đối với người dùng hợp lệ, nó cho phép dùng socket connection đang có để tiếp tục đẩy thông tin đi thay vì phải mở ra nhiều socket làm tốn tài nguyên và tạo truy cập chậm. Đối với các dụng đích "thiếu trong sáng" thì việc dùng socket connection đang có để tiếp tục đẩy thông tin mang tính phá hoại thì độ hư hoại đến máy chủ khó mà lường được. "Keep-alive" trên bình diện IP đơn giản là một tcp/ip stream chỉ có 1 lần "3way handshake" xảy ra, sau đó thông tin thông thường được đưa đi xuyên qua các cú ACK-PSH (acknowledge và push). "keep-alive" trên bình diện application (trên tầng apache chẳng hạn) có nghĩa là nhiều cú POST đi xuyên qua một connect đã hình thành. Hẳn bạn đã nhận thấy "2 điểm hở" rồi chứ?

Bạn có thể hỏi "tại sao không ra lệnh cho iptables tìm và cản những gói ACK-PSH có chứa thông tin x-flash? Tôi sẽ trả lời: A very smart question! nếu bạn hỏi tôi câu này. Tất nhiên là thế, tất nhiên là phải ra lệnh cho iptables "tìm và loại bỏ" những gói ACK-PSH "đen tối" kia nhưng, câu hỏi được đặt ra: kiểm soát "pattern matching" cho mọi gói ACK-PSH sao?. Được thôi! tuy nhiên vấn đề hiệu xuất sẽ trở thành chuyện đau đầu ở đây. Hơn nữa, không phải gói ACK-PSH nào cũng dài tương tự nhau, không phải các gói ACK-PSH lúc nào cũng trọn vẹn mà chúng có thể được tách nhỏ ra (xem khái niệm fragmentation trong chú thích -59-). Điều này dẫn tới vấn đề gì? chắc chắn sẽ có những gói tin "đen tối" đi vuộc qua khỏi hàng rào cản của firewall. Tuy nhiên, nếu cứ đưa ra mục tiêu cản được 2/3 số lượng các gói tin "đen" kia và để dành 1/3 cho SecFilterScanPOST lo liệu xem ra có thể chấp nhận được chăng? Hãy thử làm một bài toán nhỏ như sau:

Cho đến 12 giờ trưa ngày 28/3/2004 (giờ máy chủ), đã có gần 5 triệu rưỡi cú POST đi vào (dựa trên thông tin snort thông báo). Cứ làm tròn thành 5 triệu cú và cứ cho 9/10 số lượng này là các cú ACK-PSH hoàn chỉnh, 1/10 còn lại là các cú ACK-PSH bị tách nhỏ ra và iptables không kiểm soát được. Nếu, iptables có thể kiểm soát 2/3 của 9/10 tổng số 6 triệu cú POST kia thì:

9/10 của 5 triệu POST = 4 triệu rưỡi
2/3 của 4,500,000 = 3 triệu.
số còn lại để mod_security lo: 1 triệu rưỡi

Ở tình trạng này, tất nhiên sẽ không còn tình trạng mỗi cú x-flash tạo ra ít nhất 4 queries trên database server. Tuy nhiên, ảnh hưởng đến tài nguyên của máy chủ nằm ở đâu? Tất nhiên là ở socket level. Hãy thử phân tích qua vấn đề này xem sao.

a) Nếu iptables cản 3 triệu gói ACK-PSH có chứa payload của POST thì có những chuyện như sau xảy ra:
- giai đoạn "3-way handshake" giữa nguồn gởi x-flash và firewall đã xảy ra một cách hợp lệ.
- gói tin ACK-PSH tiếp theo đi từ nguồn x-flash sẽ bị cản nếu nó thuộc dạng x-flash. Nếu gói tin này gói gọn cú POST mà không được tách ra thành nhiều gói nhỏ (như đã đề cập với khái niệm fragmentation ở trên) thì trọn bộ xuất truy cập của cú x-flash này kết thúc tại đây. Những gói tin đi theo sau (nếu có) sẽ bị liệt vào dạng "INVALID STATE" và sẽ tiếp tục bị cản vì đối với firewall, chúng chẳng thuộc một "state" hợp lệ nào.
- nếu gói ACK-PSH này là phần thứ nhất của nhiều gói chia nhỏ ra thì có hai chuyện xảy ra: 1) nếu header của gói tin này có bất cứ thông tin gì dùng để nhận diện nó là x-flash, nó sẽ bị cản và trạng thái xử lý sẽ y hệt như trên. 2) nếu header của gói tin này không có bất cứ thông tin nào để nhận diện nó là x-flash, payload của nó sẽ được kiểm tra. Nếu trong payload có bất cứ thông tin nào để nhận diện nó mang tính chất một gói x-flash, nó sẽ bị cản như trên, nếu không, nó sẽ được đi vào như một gói tin hợp lệ.

False positive trong phương thức này? tất nhiên là có bởi vì không hệ thống nào lại không có false positive. Nếu có false positive, người dùng hợp lệ phải "refresh" lại trình duyệt của họ để tạo một xuất truy cập mới. False postive rate? hy vọng là không cao vì những cú x-flash có những tính chất rất đặc thù so với những gói tin hợp lệ. Vậy, nếu x-flash hoặc các dạng DoS khác có những "pattern" mới thì sao? Phương thức dùng "matching pattern" ứng dụng regex (xem chú thích -42-) nên một số biến thiên nào đó sẽ nằm trong khoảng kiểm soát của các firewall cho phương thức cụ thể này. Tuy nhiên, nếu các gói tin có payload hoàn toàn mới thì e rằng hệ thống phòng thủ không còn ứng hiệu ở mức tối đa. Trong tình trạng này, cơ phận duy nhất còn tác dụng là phần điều tác giới hạn connection.

Vậy ảnh hưởng về mặt tài nguyên của những trường hợp trên ở đâu? Bất cứ gói tin nào mang tính hợp lệ để có thể hoàn tất "3-way handshake", chúng đều chiếm một lượng tài nguyên nhất định cho bước này (ở socket level). Tuy nhiên, trạng thái SYN chuyển sang các flags sau đó (như ACK, ASK-PSH...) rất nhanh nên SYN không bị chiếm quá lâu (ngoại trừ bị syn flood một cách thực sự). Tuy nhiên, dạng syn-flood cổ điển đến nay đã không còn tác dụng mấy đến những kernel mới của linux và *bsd. Tài nguyên bị "phí" nhiều nhất ở giai đoạn socket được đóng (vì 1 trong hai đầu truy cập kết thúc), chuyển đến trạng thái FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT. Trong trường hợp firewall can thiệp vào việc kết thúc một cuộc truy cập thì tình hình có khác nếu xử dụng target khác nhau (DROP hay REJECT và REJECT với chọn lựa nào đó).

- nếu firewall cản gói tin bằng phương thức DROP, gói tin vi phạm bị hủy bỏ một cách yên lặng, như thể không có chuyện gì xảy ra. Trên mức độ socket, không hề có gói RST (reset) hay gói FIN (finish) gởi từ máy chủ về lại nguồn của gói tin vi phạm để "thông báo" chuyện gì đã xảy ra. Với tình trạng này, nguồn gởi gói tin vi phạm sẽ bị vướng vào trường hợp bị hàng đống các "dead sockets" vì gói ACK-PSH gởi đi không hề có gói ACK từ máy chủ (bị tấn công) hồi đáp. Nếu máy nguồn gởi càng nhanh, càng dồn dập thì số lượng socket ở tình trạng "TIME-WAIT" sẽ tồn tại rất nhiều trên máy và đến một lúc nào đó, chính nó sẽ bị cạn kiệt tài nguyên (memory để giữ socket ở tình trạng "TIME-WAIT" đến khi timeout).

- nếu firewall cản gói tin bằng phương pháp REJECT, gói tin vi phạm này bị hủy nhưng đồng thời firewall sẽ gởi trả một thông điệp (tùy chọn lựa REJECT nào đó). Thông thường, một gói FIN hoặc một gói RST (tùy ứng dụng) sẽ được gởi trả về máy nguồn của gói tin vi phạm. Với tình trạng này, chính firewall phải tốn tài nguyên để tạo gói tin hồi đáp và máy nguồn của gói tin vi phạm được "thoát" khỏi tình trạng bị "dead socket". Cách này có vẻ "nice" đối với nguồn tấn công nhưng tùy vào giao thức mà dùng. Có những giao thức cần phải dùng REJECT để giải phóng tài nguyên cho cả hai đầu.

Vậy, khi iptables cản 3 triệu gói ACK-PSH vi phạm kia bằng phương thức DROP, sẽ có chừng 3 triệu "dead sockets" nằm đâu đó trên các máy dùng để tấn công. 3 triệu "dead socket" thì có gì ghê gớm? có đó! Cứ một dead socket chiếm 1.5Kb real memory (không phải swap). Cần bao lâu và cần bao nhiêu "dead socket" để máy này cạn kiệt memory nếu mỗi "dead socket" chiếm 1.5Kb và cần 180 giây để được hủy bỏ hoàn toàn (1.5Kb này sẽ được tái dụng)? Đây chỉ là khái niệm thuần toán, thực tế hẳn phải đa dạng hơn rất nhiều vì không chỉ 1 máy dùng để tấn công.

b) Nếu mod_security được dùng như một dạng firewall ở tầng application và phối hợp với firewall ở tầng IP thì có những chuyện sau xảy ra:
- các request thoả mãn "3-way handshake" ở ngay firewall (tầng IP) sẽ được tiếp tục xử lý. Nếu chúng (các gói ACK-PSH) là những gói vi phạm thì sẽ bị firewall ở tầng này cản lọc như đã phân tích ở trên.
- nếu các gói ACK-PSH được tách ra và firewall ở tầng IP không kịp xử lý chúng, khi lên đến mod_security (tầng application), chúng sẽ bị khám xét và cản lọc. Biên độ cản lọc trên mod_security rất rộng bởi vì nó đảm nhiệm việc khám xét trên request URL, trên các arguments được chuyển vào trong request (thường dùng cho các cú GET) và nhất là trong payload của các cú POST.

Độ cản lọc trên mod_security có thể rất chi tiết dựa trên một "pattern" cụ thể hoặc rất rộng nếu ứng dụng regex đúng mức. Khả năng các request "xấu" đi xuyên qua mod_security để tạo các queries trên database cực kỳ thấp (nếu chuẩn bị cẩn thận các rules cho mod_security). Tuy nhiên, phản ứng phụ trên tầng firewall này là một vấn đề không nhỏ. mod_security không DROP gói tin một cách lặng lẽ như firewall ở tầng IP mà nó kết thúc request nào mang tính vi phạm theo đúng quy cách ứng dụng của giao thức TCP.

Như bạn đã biết, giao thức TCP cần 3 bước để thiết lập một cuộc truy cập (3-way handshake) nhưng lại cần đến 4 bước để kết thúc một cuộc truy cập -60-. mod_security trước tiên gởi trả lại nguồn vi phạm một thông điệp (hay một HTTP error status tùy theo cấu hình ứng dụng), sau đó nó mới gởi một cú FIN (finish) ngược lại nguồn vi phạm và đợi đầu này gởi về một cú FIN-ACK, tiếp theo đó mod_security gởi một cú FIN-ACK và phải tiếp tục đợi đầu bên kia gởi trả một cú ACK trước khi cuộc truy cập này hoàn toàn đóng. Trên bình diện hoạt động bình thường, các bước kết thúc này chẳng có gì đáng phải bàn vì chúng cần thiết để bảo đảm một cuộc truy cập được kết thúc một cách trơn tru, tránh tình trạng time-out, tránh cơ hội bị "dead socket"... Tuy nhiên, trong tình huống một máy đang bị DoS dồn dập các bước kết thúc đúng quy cách này càng tạo thêm sức ép cho máy chủ. Cứ mỗi cú x-flash đi vào, trước tiên máy chủ phải tốn tài nguyên cho "3-way handshake", sau đó tốn tài nguyên để dò tìm nội dung vi phạm của gói tin. Để kết liễu nó, máy chủ cần thêm 2 gói tin cuối cùng cộng với thời gian chờ đợi đầu bên kia hồi báo. Trong lúc mod_security phải hoàn tất xử lý một cuộc truy cập vi phạm đúng quy cách thế này thì có lẽ đã có vài chục, vài trăm hoặc vài ngàn cuộc truy cập khác đang đứng chờ được xử lý. Có lẽ bạn đã hình dung ra hoàn cảnh của server thế nào nếu đang bị tấn công dồn dập. mod_security sẽ càng ngày càng ngập ngụa với công việc, request càng ngày càng dồn ứ. Chuyện gì xảy ra nếu tình trạng này xảy ra?

- người dùng hợp lệ dùng trình duyệt sẽ thấy vận tốc duyệt càng ngày càng chậm.

- trên máy chủ càng ngày số socket ở tình trạng FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT càng nhiều.

Cho dù các cú DoS không đi vào tới database để tạo server load, chính máy chủ sẽ đi đến chỗ cạn kiệt vì hết memory do phải tuân thủ các bước "đóng" cuộc truy cập như đã nói ở trên. Thử phân tích sơ qua với số liệu 1 triệu rưỡi cú x-flash trong nửa ngày mà mod_security phải cản và giải quyết xem:

1,500,000 / 12 / 60 / 60 = 35 cú POST mỗi giây


Mỗi cú POST được mod_security triệt tiêu nhưng phải đi qua giai đọan FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT. Theo mặc định trên Linux kernel, mỗi FIN-WAIT-1 sẽ tồn tại 60 giây và chiếm 1.5Kb real memory trong lúc nó còn tồn tại:

35 x 1.5Kb = 52.5Kb mỗi giây

Quá ít? Hãy xem thử trong 60 (trước khi một socket chuyển từ dạng FIN-WAIT-1 sang FIN-WAIT-2):

52.5 x 60 = 3,150kb

Sang đến giây thứ 61 mới trả lại 52.5K memory nếu cơ chế này hoạt động nhịp nhàng và không có sự cố:

3,150 - 52.5 = 3,097.5Kb


Giả sử chỉ phó mặc cho mod_security lo hoàn toàn các cú x-flash trong trường hợp này thì:

5,000,000 / 12 / 60 / 60 = 116 cú POST mỗi giây
116 x 1.5Kb = 174Kb
174Kb x 60 = 10,440Kb


Mất toi 10Mb RAM một cách dễ dàng!

Nếu kẻ tấn công chọn phương pháp gọn nhẹ hơn (như GET chẳng hạn) và gia tăng từ 116 cú POST thành vài ngàn cú GET mỗi giây thì chuyện gì sẽ xảy ra? Đó là chưa kể trường hợp kernel phải lo điều tác với số "orphans sockets". Cứ mỗi "orphan" chiếm 64Kb real memery trước khi chúng được mang ra khỏi hàng đợi để được giải quyết. Điều tệ hại hơn nữa là các request hợp lệ phải đứng chờ lượt mình được mod_security "xét" và hiệu xuất giảm sút đáng kể. Phần tài nguyên hao hụt (khó thấy) nhất là phần logging xảy ra bên dưới. Mỗi trường hợp vi phạm (26 trường hợp mỗi giây) đều lưu lại ít nhất là 25Kb log và cơ chế read-write (cho disk I/O) bận rộn chưa từng có.

Ý tôi không phải "chê" mod_security là tệ nhưng thật sự nó được thiết kế để chống những loại tấn công đơn lẽ như xss, sql injection, buffer overflow... dù những loại tấn công này hoàn toàn tự động hoá (bằng scripting chẳng hạn) cũng không có trường độ và cường độ tương tự như DDoS. Bởi vậy, việc điều chỉnh và chọn lựa phản ứng cho mod_security trong hoàn cảnh này là điểm tối quan trọng nếu như quyết định dùng nó như một application firewall.

Ngay lúc tôi đang còn dông dài với bài viết này thì HVA đã trở lại bình thường (dù vẫn bị "gõ" đều đặn). Bạn tò mò muốn biết những gì đã xảy ra sau đó? Mời bạn xem phần tiếp theo.

Chú thích:
-58- dành cho những bạn thích đào sâu: đối với iptables, cách đơn giản nhất là dùng match length (-m length) để xác định độ dài của các packets cần được kiểm tra. Ngoài ra còn có nhiều kỹ thuật phức tạp hơn và chính xác hơn là phối hợp với một số netfilter's helpers và kỹ thuật "nắn" gói tin (traffic shaping) để kiểm soát các gói tin hiệu quả hơn. Đây chỉ là một gợi ý tổng quát.

-59- thuật ngữ mạng và bảo mật gọi là "packet fragmentation". Một gói tin có thể quá lớn để khít vào một MTU (Maximum Transmission Unit). Giả sử Ethernet có MTU là 1500 và gói tin có độ dài là 1550 chẳng hạn, nó phải được "tách" ra để tiếp tục gởi phần còn lại trên gói tin kế tiếp. Xem thêm chi tiết "packet fragmentation" trong bất cứ tài liệu nào nói về tcp/ip. Đối với iptables, các fragmented packets đều được nhập lại ở dạng hoàn chỉnh trước khi được kiểm soát. Tuy nhiên, với tinh thần vấn đề đang phân tích ở đây, sau khi các gói tin được nhập lại ở dạng hoàn chỉnh có thể trở nên quá lớn và đã bị từ chối kiểm tra "pattern".

-60- Nên tham khảo một cuốn sách nói về các giao thức trong tcp/ip suite. Tôi cho rằng bộ tcp/ip illustrated 1,2,3 của Richard Steven là một bộ sách không thể thiếu cho những ai muốn đào sâu về giao thức mạng.

Các bạn có thể theo dõi tiếp phần 17 tại http://hvaonline.net/hvaonline/posts/list/506.html
Tối 26/3/2005
Vừa xong một trận nhậu tưng bừng, khách khứa đã ra về. Mở FireFox ra để xem qua HVA có gì mới, tôi hết sức ngạc nhiên khi thấy truy cập vào HVA cực kỳ chậm; một trang load mất hơn 9.5s (?). Đây là dấu hiệu rất bất thường. Dù tôi đang "nửa say, nửa tỉnh" nhưng cũng cố login HVA server để xem qua tình hình. Việc đầu tiên tôi nhận thấy là log vào HVA server (xuyên qua SSH) cực kỳ chậm và bị "timeout" liên tục. HVA bị DoS rất nặng rồi! đây là chuyện không còn phải nghi ngờ gì nữa.

Sau vài lần thử log vào, rối cuộc tôi cũng vào được shell của HVA server. Xem thử tình hình tổng quát thế nào, tôi gõ:

# w
load average: 98.20, 120.75, 100.80

Ôi trời, cái gì mà kinh thế? Chẳng lẽ "hàng phòng thủ" của HVA đã vỡ sao? Tôi thử "tail" phần log của web server xem chuyện đây?
Code:
24.18.234.44 - - [26/Mar/2005:20:44:42 -0400] "POST /forum/ HTTP/1.1" 200 640 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
24.18.234.44 - - [26/Mar/2005:20:44:42 -0400] "POST /forum/ HTTP/1.1" 200 640 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
24.18.234.44 - - [26/Mar/2005:20:44:44 -0400] "POST /forum/ HTTP/1.1" 200 640 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"

Ái chà, lại là mớ POST quỷ quái kia. Tất nhiên là không chỉ có 3 dòng đơn giản như trên mà các dòng tương tự như thế từ hàng trăm IP khác nhau hiển thị như... nước chảy trên màn hình. Tôi vò đầu, sao lạ nhỉ? làm sao mấy cú POST ngớ ngẩn này có thể "đột phá" HVA và làm cho server load tăng đến mức kinh khủng đến thế? Tôi xem lại cấu hình của firewall và thấy quả là firewall có phần dễ dãi. Tuy vậy, mức độ "mở cửa" của firewall lúc này cũng không thể dẫn đến tình trạng server load của HVA lên cao như thế được.

Tôi quyết định điều chỉnh lại firewall và tái khởi động nó rồi theo dõi cụ thể sau.

Năm phút sau,

# w
load average: 16.50, 78.65, 90.40

Hừm.... xem tạm chấp nhận được. Tôi thử dùng FireFox để vào lại diễn đàn HVA và thấy vận tốc truy cập khá hơn lúc nãy rất nhiều. Tôi quyết định "dump" một mớ packets để xem thử sự thể ra sao:

# tcpdump -s0 port 80 -w 26-03-2005

Chờ khoảng 60 giây, tôi ngưng tcpdump, zip hồ sơ "26-03-2005" và tải về laptop của tôi. Tuy nhiên, tôi lại gặp thêm một khó khăn khác. Bất cứ mọi phương tiện tôi dùng để tải hồ sơ trên về máy (scp, sftp hay rsync xuyên qua ssh....) -56- đều bị gián đoạn nửa chừng. Có lẽ do "timeout" giữa mỗi gói tin gởi nhận giữa laptop của tôi và HVA server (máy chủ HVA quá bận rộn vì đang bị DoS dồn dập). Tôi thở dài lẩm nhẩm "đành phải tạm ngưng web service thôi". Miệng nói, tay làm; tôi ngưng ngay apache và cũng không quên ngưng luôn monit (monit đã được đề cập trong một phần trước đây của loạt ký sự này) để nó khỏi tự động restart lại apache trước khi tôi hoàn tất chuyển tải hồ sơ 26-03-2005.gz về máy mình.

Voila, hồ sơ gần 3 Mb được chuyển về sau hơn 2 phút.

Tôi khởi động lại apache và monit ngay sau đó và liên tục kiểm tra server load suốt 15 phút sau khi khởi động lại apache. Server load lúc này đã giảm xuống đáng kể, không khi nào lên quá 5.0 load. Tôi logoff HVA server và đi ngủ (lượng alcohol trong máu không cho phép tôi ngồi lâu hơn nữa).

Trưa 27/03/2005
Tôi thức dậy hơi trễ so với thường ngày vì trận nhậu sáng hôm qua. Sáng nay lại có ít việc phải lo nên tôi không vào HVA suốt buổi sáng. Mãi đến sau buổi trưa, khi mọi chuyện đã đâu vào đấy, tôi mở máy lên, thử vào HVA forum bằng FireFox. Chà, trang web load chậm kinh khủng, tôi có cảm giác chậm hơn tối hôm qua nữa. Chuyện gì đây nhỉ?

Tôi log vào HVA server bằng SSH để xem xét tình hình. Sau 5 lần bị timeout (không connect được đến server), tôi tắc lưỡi than thầm "chết thật, server bị dội kinh thế này sao?". Lần thứ 6, tôi vào được. Việc đầu tiên tôi làm là kiểm tra ngay server load:

# w
load average: 55.30, 86.62, 85.43


Chà, không bằng tối qua nhưng sao chậm thế nhỉ? Tôi hình dung ngay lượng connection đến database, nơi duy nhất có thể tạo ra tình trạng chậm lê thê thế này. Tôi thử kiểm tra ngay số lượng process dùng để truy cập đến database:

# ps -ef | grep mysqld | wc -l
200


Ôi, ôi, ôi! 200 process cho mysql? Như vậy có nghĩa là mysql đang ngập ngụa, lết thếch với lượng connection đang diễn ra. Cũng ngay khi đó, Firefox báo lỗi "server bị sự cố, không thể truy cập vào database". Tôi gật gù, "hẳn nhiên là thế rồi". Câu hỏi tiếp theo nảy ra trong đầu "lý do tại sao các cú x-flash có thể vượt qua được hàng phòng thủ?". Tôi kiểm tra log của firewall, log của snort và log của apache trong cùng một khoảng thời gian (từ 11 giờ sáng đến 11:15 sáng giờ máy chủ) để tìm câu trả lời tổng quát cho thắc mắc ở trên. Sau 15 phút grep, awk, sort.... -57- tôi nhận ra một điều tối yếu: hàng phòng thủ không cáng đáng nổi lượng x-flash ập vào server.

Tôi vò đầu lẩm nhẩm "cho đến lúc này đã có hơn 3 triệu 9 trăm ngàn cú POST đi vào, tính từ nửa đêm, giờ máy chủ. Vậy có nghĩa suýt soát 45 cú POST mỗi giây". Dựa trên thông tin của apache và firewall, tôi ước tính firewall chỉ cản được 2/3 số lượng này, như vậy cứ mỗi giây có chừng 15 cú POST đi vào. Mỗi cú POST kích động ít nhất 4 queries đến database server, mỗi query mất chừng 0.05 giây. Vậy, 15 POST sẽ cần:
Code:
15 POST x (4 queries x 0.05 giây) = 3 seconds

để giải quyết request, dọn dẹp và trở lại tư thế sẵn sàng phục vụ. Bạn có thể hình dung chuyện gì đã xảy ra rồi chớ? Hèm, cứ mỗi giây lại có một khối lượng requests cần đến 3 giây để giải quyết (tính trung bình), vậy cứ mỗi giây đi qua thì có chừng 2 giây cấp số đến khối lượng công việc.

Đã có nhận định tổng quát tình hình, tôi cần phải giải quyết ngay 2 điều:
1) giảm thiểu số lượng POST càng nhiều càng tốt để lấy lại mức độ quân bình
2) điều tra xem lý do tại sao chỉ có 2/3 số lượng x-flash POST bị cản thành công

Tôi dừng ngay apache, mysqld và monit. Chỉnh lại firewall và ấn định connection limit ở mức tối thiểu và khởi động các dịch vụ trở lại. Vừa theo dõi mức biến thiên của server load, tôi vừa mở mớ packet dump tôi lấy được tối hôm qua.

Hãy thử so sánh payload của x-flash POST lần này và lần trước
Code:
POST /forum/ HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 801
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
Host: www.hvaonline.net
Connection: Keep-Alive
Cache-Control: no-cache
total=1171&Submit=Submit&attack=1&url1=http%3A%2F%2Fwww%2Ehvaonline%2Enet%2Fforum%2F&url2=http%3A%2F%2Fwww%2Ehvaonline%
2Enet%2Fforum%2F&url3=http%3A%2F%2Fwww%2Ehvaonline%2Enet%2Fforum%2F&search%5Fkeywords=%2A&search%5Fterms=any&search%
5Fauthor=&search%5Fforum=1&search%5Ftime=0&search%5Ffields=all&search%5Fcat=1&sort%5Fby=0&sort%5Fdir=DESC&show%
5Fresults=topics&return%
5Fchars=200&act=Reg&termsread=1&agree%5Fto%5Fterms=1&CODE=02&coppa%5Fuser=0&UserName=abcxyzmanginternet&PassWord=123456&PassWord%
5FCheck=123456&EmailAddress=thienthan%40hvaonline%2Enet&EmailAddress%5Ftwo=binhquamit%40cuchuoi%2Ecom&allow%5Fadmin%
5Fmail=1&allow%5Fmember%5Fmail=1&time%5Foffset=7&dst=1®id=cfdcc4645bbf06325a1680e405e4edb9®%5Fcode=4754125&page=search%
5Fresult&catid=0&search%5Fqkeywords=Thang+Beo&category%5Fid=0

phần payload được decode như thế này:
Code:
total=1171&Submit=Submit&attack=1&url1=/forum/&url2=/forum/&url3
=/forum/&search_keywords=*&search_terms=any&search_author=&search_forum=1&search_time=0
&search_fields=all&search_cat=1&sort_by=0&sort_dir=DESC&show_results=topics&return_chars=200&act=Reg&termsread=1
&agree_to_terms=1&CODE=02&coppa_user=0&UserName=abcxyzmanginternet&PassWord=123456&PassWord_Check=123456
&EmailAddress=thienthan@hvaonline.net&EmailAddress_two=binhquamit@cuchuoi.com&allow_admin_mail=1&allow_member_mail=1
&time_offset=7&dst=1®id=cfdcc4645bbf06325a1680e405e4edb9®_code=4754125&page=search_result&catid=0
&search_qkeywords=Thang Beo&category_id=0

Phần POST xảy ra trước đây như sau:

POST /forum/ HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Content-Type: application/x-www-form-urlencoded
Content-Length: 712
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)
Host: 219.207.204.25
Connection: Keep-Alive
Cache-Control: no-cache

total=23&Submit=Submit&attack=1&diachi=http%3A%2F%2Fviemarket%2Ecom%2F&url1=
http%3A%2F%2F219%2E207%2E204%2E25%2Fforum%2F&url2=http%3A%2F%2F219%2
E207%2E204%2E25%2Fforum%2F&url3=http%3A%2F%2F219%2E207%2E204%2E25%2F
forum%2F&option=search&s=&do=login&url=http%3A%2F%2Fvikhoa%2Ecom&agree=1&
password%5Fmd5=&passwordconfirm%5Fmd5=&username=Tintucvietnam&password=
thangcho&passwordconfirm=thangcho&email=admin%40tintucvietnam%2Ecom&emailconfirm=
admin%40tintucvietnam%2Ecom&imagestamp=tintuc&imagehash=47b4a32f7767bfc7b83f8f3e
cf2e8c66&timezoneoffset=8&dst=2&options=&adminemail=1&vb%5Flogin%5Fusername=Hoanghiep
&cookieuser=1&vb%5Flogin%5Fpassword=dumemaykhoa&forcewwwect=1&vb%5Flogin%5Fmd5
password=&%5F%5FOoO%5F%5F=1&1=

Phần payload ở trên được decoded như sau:
Code:
total=23&Submit=Submit&attack=1&diachi=http://viemarket.com/&url1=http://219.207.204.25/forum/&url2=
 http://219.207.204.25/forum/&url3=http://2...=&do=login&url=
 http://vikhoa.com&agree=1&password_md5=&pa...etnam&password=
thangcho&passwordconfirm=thangcho&email=admin@tintucvietnam.com&emailconfirm=admin@tintucvietnam.com&
imagestamp=tintuc&imagehash=47b4a32f7767bfc7b83f8f3ecf2e8c66&timezoneoffset=8&dst=2&options=&adminemail=
1&vb_login_username=Hoanghiep&cookieuser=1&vb_login_password=dumemaykhoa&forcewwwect=1&vb_login_md5password=
&__OoO_


Chúng khác nhau không? Chắc chắn là khác rồi. Chúng có những điểm giống nhau? hiển nhiên là thế. Xem kỹ phần payload mới của các cú x-flash POST:

/forum/&search_key...1&search_time=0
&search_fields=all&search_cat=1&sort_by=0&sort_dir=DESC&show_results=topics&return_chars=200&act=Reg&termsread=1
&agree_to_terms=1&CODE=02&coppa_user=0&UserName=abcxyzmanginternet&PassWord=123456&PassWord_Check=123456
&EmailAddress=thienthan@hvaonline.net&EmailAddress_two=binhquamit@cuchuoi.com&allow_admin_mail=1&allow_member_mail=1
&time_offset=7&dst=1®id=cfdcc4645bbf06325a1680e405e4edb9®_code=4754125&page=search_result&catid=0
&search_qkeywords=Thang Beo&category_id=0


Tôi phải gật gù tán thưởng với mức sáng tạo lần này của kẻ tấn công HVA. Bạn nói sao? tại sao phải gật gù? smilie. Đúng vậy, tôi gật gù vì ý định "tàn phá" trong payload của các cú POST lần này không chỉ POST khơi khơi mà có dụng đích rõ ràng, mặc dù dụng đích này không có tác dụng gì ngoài việc "buộc" code của forum phải tạo 4, 5 cái query đến database server cho mỗi cú POST. Những query này dừng lại ở mức độ thâu thập thông tin để hiển thị kết quả cú POST (mặc dù chẳng có kết quả gì để hiển thì ngoài một mớ sườn của diễn đàn). Ý định của các cú POST trên là thực thi lệnh "search" và từ khoá để search là một "wild card" * nhằm lấy về càng nhiều kết quả càng tốt. Nếu ý định này thành công thì chẳng mấy chốc diễn đàn HVA chết đứ đừ vì database server phải làm việc ở mức căng thẳng nhất. May thay, nội dung payload này khá vô ích và không "hiệu năng" gì hơn lần trước. Rõ ràng nội dung payload nhắm đến hvaonline.net nhưng cú pháp thì không mảy may tương ứng với hàm "search" của hva.

Trong 30 phút vừa qua, server load chưa hề lên quá 3.0. Tôi thử vào diễn đàn HVA bằng FireFox; có vẻ chậm hơn bình thường nhưng không ở tình trạng trì trệ như một giờ trước đây. Được rồi, hãy bắt tay vào phân tích xem cái firewall bị gì mà không cản hết những cú POST kia. Tôi mở hồ sơ cấu hình của firewall lên và tập trung vào "bộ luật" dành riêng cho HTTP. Tôi dò từng dòng, từng chữ của nhóm luật này và chỉ sau một phút, tôi nhận ra ngay "độ hở" của một số luật dùng để đối phó với x-flash. Hãy xem thử syslog báo những gì, tôi cần xác nhận điều tôi vừa tìm ra hoàn toàn đúng:

Code:
# tail -f messages
Mar 27 12:48:05 hvaonline kernel: Packet too big to attempt sublinear string search (1128 bytes)
Mar 27 12:48:08 hvaonline kernel: NET: 4 messages suppressed.
Mar 27 12:48:08 hvaonline kernel: Packet too big to attempt sublinear string search (1161 bytes)
Mar 27 12:48:14 hvaonline kernel: NET: 3 messages suppressed.
Mar 27 12:48:14 hvaonline kernel: Packet too big to attempt sublinear string search (1379 bytes)
Mar 27 12:48:19 hvaonline kernel: NET: 3 messages suppressed.
Mar 27 12:48:19 hvaonline kernel: Packet too big to attempt sublinear string search (1319 bytes)
=307 DF PROTO=TCP SPT=48256 DPT=25 WINDOW=6432 RES=0x00 ACK PSH FIN URGP=0
Mar 27 12:48:24 hvaonline kernel: NET: 5 messages suppressed.
Mar 27 12:48:24 hvaonline kernel: Packet too big to attempt sublinear string search (1420 bytes)
D=1937 DF PROTO=TCP SPT=38923 DPT=25 WINDOW=24820 RES=0x00 ACK PSH URGP=0
Mar 27 12:48:29 hvaonline kernel: NET: 15 messages suppressed.
Mar 27 12:48:29 hvaonline kernel: Packet too big to attempt sublinear string search (1255 bytes)
Mar 27 12:48:34 hvaonline kernel: NET: 19 messages suppressed.
Mar 27 12:48:34 hvaonline kernel: Packet too big to attempt sublinear string search (1316 bytes)
Mar 27 12:48:43 hvaonline kernel: NET: 5 messages suppressed.
Mar 27 12:48:43 hvaonline kernel: Packet too big to attempt sublinear string search (1194 bytes)
Mar 27 12:48:43 hvaonline kernel: Packet too big to attempt sublinear string search (1194 bytes)
Mar 27 12:49:28 hvaonline kernel: Packet too big to attempt sublinear string search (1269 bytes)
Mar 27 12:49:30 hvaonline kernel: NET: 5 messages suppressed.
Mar 27 12:49:30 hvaonline kernel: Packet too big to attempt sublinear string search (1130 bytes)
Mar 27 12:49:35 hvaonline kernel: NET: 3 messages suppressed.
Mar 27 12:49:35 hvaonline kernel: Packet too big to attempt sublinear string search (1128 bytes)

Quả vậy, quả vậy. Tôi tìm ra không chỉ một mà là hai điểm hở khiến cho các cú x-flash có thể vuột qua hàng phòng thủ nếu như số lượng x-flash đạt tới mức dồn dập nào đó và nếu như apache đã cho phép "keep-alive". Thực trạng lúc này đều thoả mãn cả hai điểm nếu như ở trên. Có lẽ bạn cũng thấy vào lúc 12:48:34 có đến 19 thông điệp ngay trong cùng một lúc (và kernel chỉ tường trình một thông điệp và cho biết có 19 thông điệp khác y hệt). Đây là một chi tiết minh hoạ rõ ràng nhất mức độ "dội" của x-flash đến HVA trong lúc này.

Điểm nổi bật trong cuộc tấn công của x-flash lần này là số lượng IP được huy động làm nguồn gởi x-flash đến HVA, cho đến lúc này ít nhất gấp 3 lần đợt tấn công vừa rồi (đầu năm 2005).

Ngay khi tôi chuẩn bị bắt tay vào điều chỉnh lại firewall thì có khách đến. Kẹt nhỉ? Tôi nghĩ thầm "cứ để tạm như vậy, hiện giờ server load không hề lên cao, chỉ hơi chậm một tí, từ từ fix sau". Tôi xếp laptop lại.

Chú thích:
-56- scp (Secure Copy) và sftp (Secure ftp) thuộc bộ Open-SSH. Dùng các phương tiện này để chuyển tải dữ liệu giữa các máy xuyên qua Internet an toàn hơn ftp và rcp (remote copy) cổ điển hơn rất nhiều. rsync xuyên qua ssh (hay còn gọi là "rsync over ssh" theo thuật ngữ tiếng Anh). Đây là một phương pháp để chuyển tải dữ liệu giữa các máy xuyên qua ssh tunnel. Theo tôi, đây là cách hiệu xuất và an toàn nhất.

-57- các lệnh thông dụng trên *nix dùng để tách lọc thông tin trong các log files để phân tích.

Các bạn có thể theo dõi tiếp phần 16 tại http://hvaonline.net/hvaonline/posts/list/320.html
Trưa 22/1/2005
Giờ ăn trưa, tôi dành vài phút login HVA server để xem tình hình. Hiện có hơn 60 người đang ở trên diễn đàn, tuy nhiên server load thật thấp:

# w
load average: 0.15, 0.43, 0.26


"Tail" snort log, tôi vẫn thấy rỉ rả những cú GET buồn cười kia đi vào. Điều tôi hết sức ngạc nhiên là không hề có tăm tích một cú x-flash POST nào đi vào. Tôi thử grep cái alert log hiện dụng của snort xem sao:

# grep POST /var/log/snort/alert | wc -l
7989


Vậy là vẫn có POST ấy chứ nhưng con số này quá ít, chuyện gì nhỉ? Để xem thử cú POST cuối cùng đi vào lúc nào. Tôi tiếp tục dùng grep để xác định cú POST cuối cùng xảy ra lúc nào:

# grep POST /var/log/snort/alert
01/22-04:17:35.30666 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 210.245.122.43:3228 -> 219.207.204.25:80

4 giờ 17 phút 35 giây sáng ngày 22/1/2005, giờ máy chủ. Có nghĩa là chừng 2 giờ 15 sáng giờ VN hoặc 6 giờ 15 sáng giờ Sydney.

Thử xem có bao nhiêu cú GET từ nửa đêm (12 giờ khuya giờ máy chủ):

# grep GET /var/log/snort/alert | wc -l
28413


Whoa, POST đi, GET về . Giờ này khoảng 10 giờ 30 sáng trên máy chủ. Vậy sau 10 giờ 30 phút trôi qua có 28413 cú GET:
28413 / 10.5 hours = 2706 cú GET mỗi giờ
2706 / 60 = 45.1 cú GET mỗi phút
45.1 / 60 = 0.752 cú GET mỗi giây


Tính ra trung bình 3 giây có 2 cú GET đi vào. Con số này lên tới hai mươi tám ngàn có lẽ đã xảy ra hồi khuya vì ngay lúc này, khi tôi thử "tail" thì nó chỉ "rỉ rả" mà thôi.

Tôi đã quá ngấy những con số và dữ liệu này nên mở ra mấy cái signature của snort để điều chỉnh thêm. Tôi dùng Ethereal để "gọi" một đoạn packets lấy được hôm qua và xem xét kỹ các "pattern" đặc biệt của các cú POST và GET kia. Tôi tối ưu hoá chúng bằng cách tính toán kỹ lưỡng "offset" của các pattern này nằm trong khoảng (bytes) nào của gói tin để đưa vào signature của snort. Làm như thế, snort không phải mất thời gian tìm kiếm trong trọn bộ nội dung của gói tin và làm chậm trễ bước xử lý.

Cho đến lúc này, máy chủ HVA ở trong tình trạng bình thường (nếu không muốn nói là rảnh rang) mặc dù lúc này trong ngày diễn đàn HVA đã bắt đầu đông đúc lên. Tôi lẩm nhẩm "để xem tình hình sắp tới ra sao".

Trưa 23/1/2005:
Tôi nhận được một số thông báo (xuyên qua Yahoo messenger) có một số thành viên ở VN, đặc biệt là từ HN không thể vào được diễn đàn HVA (bất kể ngày đêm) trong mấy ngày qua. Tuy nhiên, họ có thể vào diễn đàn HVA nếu đi xuyên qua một proxy server nào đó. Một điều tôi nắm chắc là firewall của HVA không có (và không muốn dùng) quy định cản hẳn một hoặc nhiều IP để khắc chế nạn DoS. Chính tôi là người đầu tiên phản bác giải pháp này và cũng chính tôi là người cố tìm giải pháp khác để thay thế.

Dựa trên thông tin của các log files trên server và trên firewall, tôi thấy rõ có rất nhiều request đến từ VN nói chung và HN nói riêng nhưng không hề có bất cứ một gói tin hợp lệ nào bị cản. Tôi gởi thông điệp đến một số cá nhân khác ở HN và hỏi thăm xem họ có gặp sự cố "không vào được HVA" hay không và họ đều cho biết có thể vào được nhưng đôi khi nhanh, đôi khi chậm. Bởi trong tay tôi không có một bằng chứng gì rõ ràng, tôi chỉ có thể tạm đoán rằng một trong những dịch vụ Internet ở HN đã cố tình cản các request đến HVA và nếu các gói tin này bị cản ở khu vực ấy thì không thể có bất cứ thông điệp hay dấu hiệu gì trên HVA server về tình trạng này được vì các gói tin bị cản không thể đi ra ngoài được.

Tôi đoán có ít nhất hai trường hợp có thể xảy ra:
1. Hai ngày trước, khi các "quả" x-flash từ những người dùng dịch vụ Internet nào đó (nay đã bị cản) dồn dập đi vào máy chủ HVA khiến cho đường dẫn của dịch vụ này bị ứ nghẽn và người dùng hợp lệ không có cơ hội truy cập HVA. Vấn đề này hoàn toàn có thể nếu như bandwidth của dịch vụ ấy quá hẹp. Nên nhớ, dẫu máy chủ HVA được gắn liền với một đường dây 10Mbit đi chăng nữa mà đầu bên kia bé tẹo và bị ứ nghẽn do hàng triệu gói tin đi ra (để đến HVA) thì chính người dùng ở đầu bên ấy là nạn nhân đầu tiên.

2. Cũng có thể tay admin nào đó của dịch vụ Internet này phát hiện ra "cơn lũ" từ mạng của anh ta đang ùn ùn đi ra và có mục tiêu là IP của máy chủ HVA. "Cơn lũ" này làm ảnh hưởng đến các người dùng khác trong mạng của dịch vụ này. Có hai cách giải quyết: a) truy ngược lại các IP nào trong mạng của anh ta tham gia vào việc tạo "cơn lũ" và xử lý từng IP, cách này chậm và mất thời gian. b) cản ngay tại router / firewall của mạng này mọi request đi đến HVA server, cơn lũ đi ra sẽ hết đường ra và sẽ bị triệt tiêu nhanh chóng, cách này nhanh nhưng vô tình tay admin này tiếp tay cho ý đồ "từ chối dịch vụ" của ai đó.

Theo tôi, trường hợp thứ 2 có vẻ gần với thực tế xử lý hơn bởi vì những thành viên từ dịch vụ này không thể vào HVA bằng đường trực tiếp nhưng lại có thể vào HVA nếu dùng một proxy server nào khác. Nếu quả thật trường hợp 1 xảy ra trên thực tế thì ngay cả "đi vòng" qua một proxy khác, người dùng từ dịch vụ này cũng khó lòng đi đến được HVA vì đường dẫn của dịch vụ đang ở trong tình trạng ứ nghẽn. Trường hợp người dùng không thể vào HVA server trong hoàn cảnh "bị cản" hoặc bị "ứ nghẽn" ở đâu đó là một hoàn cảnh không thể giải quyết được (từ phía HVA). Nếu các admin của các dịch vụ là những tay có kinh nghiệm hoặc kiến thức bảo mật, xử lý các vấn nạn này không khó. Nếu họ xử lý được, không những họ cân bằng được chất lượng đường dẫn cho khách hàng của họ mà còn loại bỏ những gói tin phá hoại để tiết kiệm băng thông, giảm thiểu phí tổn.

Trưa nay máy chủ HVA vẫn tiếp tục trong tình trạng hoàn toàn bình thường và ổn định mặc dù các cú GET vẫn đều đều "gõ". Tôi "log off" máy chủ HVA và trở lại "đối đầu" với hàng đống công việc ở sở.

Trưa 4/2/2005

Đã gần 2 tuần lễ trôi qua, đều đặn mỗi ngày tôi chạy thử một cái script (từ laptop của tôi) để kiểm tra khối lượng các cú GET và POST. Server load của máy chủ vẫn nằm ở mức thấp và từ đó đến nay chưa bao giờ lên quá giới hạn 4.0 load. Sau đây là một số thông tin tôi nghĩ có thể chia xẻ với bạn:

alert của snort vào ngày 29/1
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
9726

Trong đó, zcat là lệnh tương tự như gunzip -c, nó dùng để "cat" một hồ sơ đã được nén (thay vì bạn phải xả nén hồ sơ này trước rồi mới dùng "cat" đối với một hồ sơ không được nén). alert.1.gz là alert log của snort được lưu giữ trên hệ thống ở dạng nén. Cơ chế đổi log hàng ngày tự động tạo một alert log mới cho snort và lưu alert log cũ ở dạng .1.gz, .2.gz.... cho đến con số bao nhiêu đó tuỳ bạn ấn định cho hệ thống của mình. Các lệnh grepwc không có gì đặc biệt, bạn muốn tìm hiểu thêm về chúng thì đơn giản thử man grepman wc.

Thông tin trên cho thấy có đến 9726 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào.

alert của snort vào ngày 30/1
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
8899

Tại sao vẫn là alert.1.gz? Cái này do ngày 31/1 tôi lấy thông tin cho ngày 30/1 nên alert log của snort đã trở thành alert.1.gz, alert log của snort cho ngày 29/1 trở thành alert.2.gz. Tôi phải đợi sang ngày hôm sau mới lấy thông tin vì tôi muốn có trọn bộ thông tin cho từng ngày.

Thông tin trên cho thấy có đến 8899 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào.

alert của snort vào ngày 31/1
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
8317

Thông tin trên cho thấy có đến 8317 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào. Có giảm sút.

alert của snort vào ngày 1/2
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
10816

Thông tin trên cho thấy có đến 10816 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào. Có gia tăng chút đỉnh.

alert của snort vào ngày 2/2
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
8949

Thông tin trên cho thấy có đến 8949 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào. Có giảm sút chút đỉnh.

alert của snort vào ngày 3/2
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
9312

Thông tin trên cho thấy có đến 9312 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào. Lại gia tăng chút đỉnh.

alert của snort vào ngày 4/2
Code:
[root@network snort]# zcat alert.1.gz | grep POST | wc -l
0
[root@network snort]# zcat alert.1.gz | grep GET | wc -l
8588

Thông tin trên cho thấy có đến 8588 quả x-flash GET nhưng hoàn toàn không có quả x-flash POST nào đi vào. Lại giảm đi phần nào.

Thông qua một chuỗi thông tin trên, tôi liên tưởng các con số như những cú "hits" trên một trang web nào đó. Nó ổn định và đều đặn. Mức thay đổi không quá lớn. Lý do tôi liên tưởng đến các cú hits trên một trang web là vì thông tin trên alert log của snort cho thấy các cú GET này rải khá đều trong ngày và chỉ tập trung cao độ ở những giờ cao điểm ở VN. Một cái banner hấp dẫn ở đâu đó để người dùng bấm chăng? hay một đoạn phim... "người nhớn" bằng flash để "dụ" những kẻ tò mò? và bên dưới đoạn flash này có cái gì đó thì.... tôi chỉ đoán vậy thôi smilie.

Thế còn monit đóng vai trò đắc lực hay không? Tôi thử duyệt qua syslog thì thấy:
Code:
[root@network snort]# grep "'apache' started" ../messages*
../messages.1:Jan 24 08:48:27 network monit[27564]: 'apache' started
../messages.1:Jan 24 09:08:08 network monit[30083]: 'apache' started
../messages.2:Jan 22 15:24:37 network monit[19359]: 'apache' started

Hèm, khoảng xế chiều ngày 22/1 monit đã khởi động lại apache. Vì lý do gì đó, monit đã thực hiện chuyện này nhưng tôi không quan tâm lắm đến chi tiết. Ngày 24/1 có một loạt thông báo về monit (khá nhiều) nhưng tôi phát hiện ra cấu hình có điểm không hoàn chỉnh và đã điều chỉnh lại. Hai thông báo cho ngày 24 ở trên quả thật monit đã khởi động lại apache. Có lẽ luật theo dõi tôi ấn định cho monit khắt khe quá chăng? tôi để yên monit và tiếp tục theo dõi, từ đó đến nay không có một thông báo nào khác. Điều đáng ngạc nhiên là từ khi đưa monit vào, database server không còn dở chứng thêm lần nào nữa.

Chuyện gì sẽ tiếp tục xảy ra? Tôi không rõ nhưng tôi có hai giả định: 1) anh chàng tấn công HVA đến nay hẳn đã thấy kết quả của những loạt tấn công của mình đến HVA và cảm thấy... nhàm với trò chơi vô bổ này? 2) anh chàng càng cay cú hơn và đang "luyện đan" để tiếp tục oanh tạc HVA? Ai mà biết? Riêng tôi, tôi muốn dành thời gian để làm những chuyện ích lợi hơn là phải "xem" những cái logs vô tri kia. Bạn nghĩ sao?

Các bạn có thể theo dõi tiếp phần 15 tại http://hvaonline.net/hvaonline/posts/list/294.html
Sáng sớm 22/01/2005

Như thường lệ, tôi thức dậy rất sớm. Vừa pha café, tôi vừa mở laptop lên (chức năng hibernate của laptop cũng có lúc tiện dụng). Đã có sẵn trình duyệt cho diễn đàn HVA từ tối qua, tôi nhấn nút "refresh". Diễn đàn "refresh" thật nhanh. Tôi nhìn cái stat bên dưới của diễn đàn và thấy chỉ có vỏn vẹn mười mấy "mống" đang ở trên diễn đàn. "Refresh" nhanh cũng phải. Tôi an tâm xếp laptop lại và tiếp tục chuẩn bị đi làm. Hai mươi phút sau đó, tôi rời nhà.

Trên tàu lửa tôi mở laptop ra và bắt đầu "ngâm" mớ packets được sniff từ tối hôm qua. Tôi bật cười vì không hiểu tại sao lại các cú GET banner của HVA lại xảy ra.

Tháng 11 năm ngoái, một cú GET từ x-flash có nội dung như sau:
Code:
GET /style_images/1/banner.swf HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74


Và bây giờ, một cú GET từ x-flash có nội dung thế này:
Code:
GET /forum/style_images/fusion[1]/banner.swf HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 13 Jan 2005 10:09:08 GMT
If-None-Match: "10e771-103fb-1bd0b900"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
Host: www.hvaonline.net
Connection: Keep-Alive
Cookie: VTYPMOD=1; VSPELL=1; VONOFF=1; member_id=12648; pass_hash=12154ab8ae9a74cfd4ac79d83ea8c422; anonlogin=1; forum_read=a%3A16%3A%7Bi%3A113%3Bi%3A1106121280%3Bi%3A83%3B
i%3A1104427108%3Bi%3A136%3Bi%3A1095706102%3Bi%3A109%3Bi%3A11
04863490%3Bi%3A139%3Bi%3A1104967565%3Bi%3A99%3Bi%3A1101271117
%3Bi%3A144%3Bi%3A1106104588%3Bi%3A90%3Bi%3A1104172553%3Bi%3A98
%3Bi%3A1099075304%3Bi%3A121%3Bi%3A1098733149%3Bi%3A92%3Bi%3A1099414867
%3Bi%3A137%3Bi%3A1099587235%3Bi%3A82%3Bi%3A1106104572%3Bi%3A91%3Bi%3A1101287346
%3Bi%3A88%3Bi%3A1104437429%3Bi%3A1%3Bi%3A1106105574%3B%7D; session_id=7ad1713d4597b723157e7aab86bb27f9


Có biến cải? hẳn nhiên rồi nhưng những biến cải này là gì? hãy cùng nhau phân tích xem (chỉ trên bình diện kỹ thuật, tôi không đi sâu vào nội dung dữ liệu trên có những gì trong đó).
- cả hai cái GET đều dùng HTTP 1.1
- cả hai đều có x-flash client cùng phiên bản 7,0,19,0
- cả hai đều khai báo tiếp nhận encoding cho compresion dùng gzip
- cả hai đều dùng Windows
- cả hai đều "muốn" keep-alive connection
nhưng, đặc biệt GET mới đã loại bỏ "Cache-Control: bypass-client" và có thêm 2 điều kiện (thuật ngữ của giao thức HTTP gọi là "conditional GET") :

If-Modified-Since: Thu, 13 Jan 2005 10:09:08 GMT
If-None-Match: "10e771-103fb-1bd0b900"


Điều kiện "If-Modified-Since" theo tôi đoán (và rất thường xảy ra) là do proxy server nào đó trên đường đi của cú GET đến HVA server tự động đưa vào, ngay cả người tạo ra cú GET nào không đòi hỏi chuyện này. Điều này xảy ra là vì proxy server nào đó "tự động" cho rằng: nếu phiên bản "banner.swf" trên HVA server không thay đổi từ lúc 10 giờ, 9 phút, 8 giây sáng giờ Greenwich ngày 13, tháng Một năm 2005 thì mới lấy bản mới từ HVA server, còn không thì dùng bản có sẵn trong cache. Hẳn nhiên là "banner.swf" không hề thay đổi từ.... năm ngoái (và vẫn còn con số 2004 trên banner - hey, ai làm chủ cái banner đó chịu khó sửa lại thành 2005 nhe? ). Điều này hoá ra proxy nào đó sẽ thong thả mà dùng bản có sẵn trong cache để cung cấp cho client nào gởi cái GET đến HVA server. Nếu vậy thì việc gì phải chọn cái banner làm chi cho mệt nhỉ? smilie Tôi không thấy có một tác dụng gì rõ rệt để dùng GET trong trường hợp này cả.

Điều kiện "If-None-Match" lại càng lý thú hơn. Mục đích của directive này là để tạo hiệu suất cho cache của proxy server bằng cách xác định xem "nó" có cần được cập nhật hay không. Mục đích tối hậu của conditional GET này là để giảm thiểu tối đa tài nguyên tiêu tốn cho vấn đề cập nhật thông tin. Với directive này, tôi càng tin chắc là nguồn gởi đi cú GET không hề biết là sẽ phải đi xuyên một cái proxy server... "cắc cớ" đến như vậy. Nó vô tình triệt tiêu mục đích "flood" HVA server. Điều đáng nói là đa số (theo thống kê tôi lấy được từ mớ packets đang phân tích ở đây có khoảng hơn 90%) các cú GET này đều "dính" 2 cái directives ở trên.

Giả sử những cú GET ở dạng này "thoát" qua được connection limit của firewall, lần lên tới web server và không hề có mod_security đứng cản thì chuyện gì xảy ra? Thì HVA web server sẽ trả lời bằng một thông điệp vỏn vẹn 225 bytes và kết thúc cuộc truy cập:

Code:
HTTP/1.1 304 Not Modified
Date: Mon, 22 Jan 2005 09:43:25 GMT
Server: WindowsNTserver 4.0 - IIS 2.0 - Perl v5.001 build 110 - ANT
Connection: close
ETag: "10e79d-390-1bd0b900"


(Ngày hôm sau) tôi cố tình tắt bỏ các signatures của snort chuyên detect những cú "x-flash" GET để xem kết quả ra sao thì thu nhận được thông tin ở trên. Đối với client (trình duyệt đã khởi tạo cú GET trên) không hề thấy có gì khác thường vì thông điệp trên chỉ dành cho vấn đề thông tin cập nhật cho cache. Thông điệp này không hề đi đến trình dịch của client và hiển thị trên màn hình. Nói về mặt kỹ thuật, cú GET trên có tác dụng y hệt một cú HTTP HEAD dùng để kiểm tra xem một thông tin nào đó có được cập nhật hay không. Dùng nó để DoS thì sẽ có kết quả gì? Bạn cũng tự hình dung ra được.

Vậy, những cú GET trên dẫu có đi vuột qua khỏi connection limit của firewall và mod_security cũng chẳng tạo bao nhiêu ảnh hưởng đến HVA server vì trọn bộ quy trình "hỏi" / "trả lời" này hết sức ngắn ngủi và im ắng. Tuy nhiên, tại sao phải bắt máy chủ HVA phí tài nguyên để đáp ứng cho những request dạng này (cho dù chúng nhỏ nhoi đi chăng nữa)? Bởi thế, snort và mod_security (nhất là snort) nằm ở vị trí của chúng với tác dụng triệt tiêu ngay các sockets phí phạm và vô ích này, để dành phục vụ cho các request hợp lệ.

Trên tàu lửa, sau khi phân tích xuyên qua mớ packets lấy xuống laptop tối hôm qua và thấy rằng tôi không cần phải thêm bất cứ một signature nào cho "x-flash" GET. Có chăng, tôi nên tối ưu hoá các signatures này bằng cách thâu hẹp vùng dữ liệu cho snort tìm kiếm để giảm thiểu thời gian tìm kiếm mà thôi.

Tôi đến văn phòng làm việc sớm hơn giờ làm bình thường đến ba mươi phút. Tôi lẩm nhẩm "dành ba mươi phút này để tối ưu hoá mấy cái snort signatures cũng hay". Thực hiện ngay ý đinh, tôi mở laptop lên và log vào HVA server.

Điều đầu tiên tôi phát hiện ra là connection đến database server mất tiêu và chính database server cũng "ngỏm" từ lúc nào. Cách đây một tiếng rưỡi tôi còn duyệt được diễn đàn HVA, điều này chứng tỏ database server "chết" lúc nào đó trong vòng một tiếng rưỡi qua. Tôi lục lọi trong mớ logs nhưng không tìm ra được lý do nào khác thường. Database service chỉ đơn giản "terminated" vì một lý do nào đó. Tình trạng này đã từng xảy ra vài lần trước đây. Tôi không muốn mất thêm thời gian với vấn đề này vì điều tôi quan tâm nhất lúc này là làm sao ngăn ngừa tình trạng một dịch vụ nào đó tự động "chết" như vậy. Nếu không thể "chia ca" cho một ai theo dõi tình hình máy chủ thì tại sao không dùng thêm một dịch vụ nào khác để lãnh trọng trách này?

Tôi quyết định dùng thêm một "vũ khí phòng thủ" nữa có cái tên là "monit" (bạn có thể tìm hiểu về nó dễ dàng bằng google). Tôi tải ngay mã nguồn của monit về máy chủ HVA và biên dịch + điều chỉnh cấu hình cụ thể để đáp ứng với hoàn cảnh của HVA. Một cách tổng quát mà nói, monit là một tiện ích nhỏ gọn và độc đáo cho việc theo dõi tình trạng hoạt động của các dịch vụ đang chạy trên một máy chủ (on hoặc off). Nó còn có khả năng theo dõi tình trạng tải của máy chủ (server load, CPU usage và memory usage....). Tôi tạo ra hồ sơ cấu hình cho monit và đưa vào các ấn định quan trọng nhất + cần thiết nhất để bảo đảm nếu một dịch vụ nào đó tự động thoát ra thì monit sẽ khởi tạo nó lại. Tôi còn điều chỉnh cho monit tái khởi động một số dịch vụ trọng yếu nếu như các dịch vụ này dùng bao nhiêu phần trăm CPU liên tục trong một khoảng thời gian nào đó (dấu hiệu của dịch vụ này đang bị ở tình trạng quá tải vì bị tấn công dồn dập).

Bạn có thể thắc mắc việc dùng monit để restart lại một dịch vụ nào đó đang chạy e rằng hơi quá "nặng tay" vì nó có thể làm hỏng các xuất truy cập của người dùng? Thắc mắc này hoàn toàn giá trị và hợp lý bởi vì bất cứ xử lý nào làm trở ngại người dùng truy cập đều không thể chấp nhận được (nói trên bình diện bền bỉ và đáng tin cậy của dịch vụ cho người dùng). Bởi thế, việc restart ở đây được ấn định rất rõ là nó phải đợi cho trọn bộ các process này đang phục vụ hoàn tất rồi mới restart, nó nặng hơn "graceful restart" (xem lại chú thích -33-) nhưng không "tàn nhẫn" như việc restart theo phương cách cắt ngang các dịch vụ. Việc tái khởi động này có tác dụng rất lớn đến tình trạng tài nguyên của máy chủ trong lúc đang tải nặng (vì bị DoS dồn dập chẳng hạn). Nó giúp hệ thống thu hồi và cân bằng tài nguyên của máy chủ một cách hữu hiệu. Nếu bạn đã theo dõi và tham khảo kỹ các chú thích -38-, -39--40-, bạn sẽ thấy vấn đề cân bằng tài nguyên của máy chủ tương quan với tính hiệu xuất quan trọng như thế nào. Nếu mang tinh thần "DoS cho xụm" vào đây thì bạn hẳn sẽ thấy mức quan trọng của việc điều hoà tài nguyên ra sao. Giả sử web server bị DoS nặng nề, mức dùng CPU của nó lên đến 99% liên tục trong nhiều phút, chuyện gì có thể xảy ra? Có rất nhiều chuyện có thể xảy vì tình trạng ứ ngẽn này và sẽ có cơ hội dẫn đến máy chủ hoàn toàn kiệt quệ.

Giả sử monit đã hiện diện và hoạt động sáng sớm nay thì có lẽ đã không có tình trạng database server bị "chết" (tôi muốn xác thực ở đây database server không phải chết vì bị DoS bởi vì server load cực thấp, nhưng chết vì một lý do bí hiểm nào khác) và tôi phải khởi tạo nó lại bằng tay.

Liệu những chỉnh định của tôi hoàn chỉnh không? tôi không chắc. Bởi thế, tôi lần lượt tắt bỏ từng dịch vụ và quan sát xem monit có thực thi đúng nhiệm vụ nó được giao hay không. Sau mười lăm phút thử nghiệm và một vài điều chỉnh, monit làm việc một cách hoàn hảo. Chỉ một thử nghiệm cuối tôi chưa thực hiện là tự DoS chính máy chủ HVA để tạo server load và quan sát xem monit làm gì. Tôi "whip" ngay một đoạn bash script đơn giản để thực hiện chuyện này ngay trên chính máy chủ HVA. Rất tiếc lần này tôi không thể trình bày đoạn script "DoS" ở đây nhưng bạn chỉ cần biết, sau vòng lặp thứ mười của đoạn script, CPU dành cho web server vượt quá giới hạn quy định và lập tức "bị" monit tái khởi động nó ngay.

Hoá ra ba mươi phút dự định cho snort lại dành trọn cho monit. Tuy nhiên, tôi rất hài lòng với kết quả của ba mươi phút máy mó ngắn ngủi này. Đã đến lúc tôi phải bắt tay vào công việc ở sở (thật ra tôi đã "ăn gian" mất mười phút của sở vì đã nấn ná, táy máy thêm với monit). Vậy, chuyện gì đã tiếp tục xảy ra? mời bạn xem tiếp phần sau.

Các bạn có thể theo dõi tiếp phần 14 tại http://hvaonline.net/hvaonline/posts/list/286.html
Tối 21/01/2005

Ăn tối xong, tôi log vào HVA server. Việc đầu tiên tôi làm là tải về một bản snort ổn định và biên dịch nó với những chọn lựa cụ thể và cá biệt cho nhu cầu trên HVA server. Thực hiện trọn bộ công việc tải nguồn của snort và các nguồn của các thư viện cần thiết cho snort cũng như quy trình biên dịch, cài đặt chỉ mất chưa tới ba mươi phút.

Tôi quyết định dùng các hồ sơ cấu hình có sẵn của snort và chỉ dùng binaries mới vừa biên dịch bởi vì snort đã từng hoạt động trên server này (ở mức căn bản). Trên đường về nhà chiều hôm nay, tôi đã hình thành xong mấy cái signature mới cho snort. Tôi copy chúng vào nhóm luật "chống x-flash" trước đây và khởi động snort. Syslog thông báo snort khởi động thành công, không hề có sự cố nào. Tôi "tail" vào log của snort để xem tình hình ra sao. Tôi dự phỏng sẽ thấy hàng tràng thông tin chạy trên màn hình nhưng thật lạ lùng, snort hoàn toàn im ắng. Lạ nhỉ? hay là mấy cái signature bị sai? không thể nào vì dẫu signatures của tôi tạo ra có sai thì một số các signatures do snort cung cấp phải hoạt động và thông báo tình hình.

Tôi kiểm tra lại từ đầu từng phần một trong cấu hình của snort và khám phá ra rằng: chỉ một con số sai trong subnet được ấn định cho snort "lắng nghe" làm cho nó không hề thấy bất cứ thông tin nào đi xuyên qua hệ thống (vì snort bị áp đặt lắng nghe trên một subnet không tồn tại). Loay hoay tìm kiếm và điều chỉnh cho trục trặc này làm mất thêm mười lăm phút nữa. Cuối cùng, tôi khởi động snort lại và phóng một cái "tail" đến snort log. Tôi gật đầu hài lòng khi thấy trên màn hình hiện ra vun vút những dòng log của snort:

01/21-19:37:28.369857 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP 221.132.48.226:15283 -> 219.207.204.25:80
01/21-19:37:28.369857 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 221.132.48.226:15283 -> 219.207.204.25:80
01/21-19:37:28.399600 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.123.197:64104 -> 219.207.204.25:80
01/21-19:37:28.399600 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.123.197:64104 -> 219.207.204.25:80
01/21-19:37:28.406221 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.210.212.141:35762 -> 219.207.204.25:80
01/21-19:37:28.406221 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.210.212.141:35762 -> 219.207.204.25:80
01/21-19:37:28.441929 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 211.198.94.249:4859 -> 219.207.204.25:80
01/21-19:37:28.441929 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 211.198.94.249:4859 -> 219.207.204.25:80
01/21-19:37:28.485582 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.169.142:1501 -> 219.207.204.25:80
01/21-19:37:28.485582 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.169.142:1501 -> 219.207.204.25:80
01/21-19:37:28.507376 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.169.142:1317 -> 219.207.204.25:80
01/21-19:37:28.507376 [**] [1:0:0] POST Null - Flash attack HVA [**] [Classification: POST-attack] [Priority: 1] {TCP} 203.162.169.142:1317 -> 219.207.204.25:80

Nếu bạn xem kỹ phần thời gian của mỗi biến cố xảy ra (màu đỏ), bạn hẳn sẽ thấy mức độ x-flash dồn dập đổ vào HVA server thế nào. Số liệu ở trên chỉ là một đoạn tượng trưng. Ở chế độ fast log và logging theo dạng binaries, snort ghi nhận một số lượng x-flash "đụng" đến NIC của HVA server kinh khủng hơn như thế rất xa.

Cũng trong khi đó, web server của HVA thông báo các thông tin như sau:

220.79.101.75 - - [21/Jan/2005:19:37:28 +0900] "POST /forum/ HTTP/1.1" 403 327 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
220.79.101.75 - - [21/Jan/2005:19:37:28 +0900] "POST /forum/ HTTP/1.1" 403 327 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

210.245.57.38 - - [21/Jan/2005:19:37:28 +0900] "GET /favicon.ico HTTP/1.1" 404 331 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0"
217.29.82.40 - - [21/Jan/2005:19:37:22 +0900] "GET /forum/index.php?act=Reg&CODE=00 HTTP/1.1" 200 6317 "/forum/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
222.252.232.163 - - [21/Jan/2005:19:37:28 +0900] "GET /forum/jscripts/ipb_forum.js HTTP/1.1" 304 - "/forum/index.php?showforum=87&prune_day=100&sort_by=Z-A&sort_key=last_post&topicfilter=all&st=30" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
221.132.48.226 - - [21/Jan/2005:19:37:28 +0900] "POST /forum/ HTTP/1.1" 403 327 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
203.162.123.197 - - [21/Jan/2005:19:37:28 +0900] "POST /forum/ HTTP/1.1" 403 327 "-" "Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)"


Đoạn màu đỏ chính là đoạn các cú x-flash đi vào và web server log ghi nhận chúng. Điều cần chú ý ở đây là status 403 cho mỗi x-flash log (xem lại chú thích -27-).

Hai đoạn log ở trên cho thấy:
- trong khoảng thời khắc 19:37:28-xx có khoảng 12 cú x-flash đi vào (snort log ghi nhận được, log ở dạng binaries ghi nhận nhiều hơn gấp bội). Tuy nhiên, lên đến web server (application layer) thì có 4 cú x-flash xuất hiện nhưng lại bị dính status 403.

- điều này chứng tỏ có ít nhất là 8 cú x-flash bị loại bỏ trước khi chúng có thể đi lên đến web server (có thể do firewall loại bỏ từ vòng ngoài vì quá connection limit, có thể do snort bắt gặp và gởi các gói RST để cắt đứt chúng...). Khi đến web server, một lần nữa 4 cú x-flash sống sót ở mức này lại bị loại bỏ vì mod_security phát hiện và trả ngược về nguồn gởi đi cú x-flash bằng status 403. Chúng đã không có cơ hội đi sâu hơn.

- điều này cũng cho thấy web server phải nhận số lượng tải cao hơn bình thường (vì vẫn có những cú x-flash vượt qua, và vì chúng hoàn toàn hợp lệ về mặt giao thức). Tuy nhiên, mức độ gia tăng trên web server thật sự không đáng kể bởi vì lúc này snort và iptables đã "hoá giải" ít nhất 80% cơn lũ x-flash. Sở dĩ server load đã lên tới con số kỷ lục chiều nay là vì firewall đã mở cổng một cách dễ dãi. Nó cho phép một số lượng truy cập khá lớn đến từ mỗi client (x-flash hoàn toàn không bị loại trừ vì chúng hợp pháp trên mặt giao thức). Người dùng cảm thấy chậm ngay lúc ấy là vì các socket đóng / mở hoàn toàn phụ thuộc và quy định tiêu chuẩn của kernel (nên thời gian TIME_WAIT và FIN_WAIT kéo dài theo đúng quy định). Ngay khi snort hoạt động, các cú RST của nó hủy bỏ những truy cập từ x-flash và có đến ít nhất 50% số lượng socket được tái dụng.

- nói về mặt tài nguyên (CPU, RAM), máy chủ HVA thừa sức để cung cấp cho web service hoạt động cao tải hơn. Nói về mặt băng thông, vì những cú POST trên "bị" cắt xén nhỏ đi (để vừa khít trong một cú chuyển gởi) nên hoá ra những cú POST này chẳng nặng nề hơn những cú GET bình thường. Tài nguyên được dùng chủ yếu trong hoàn cảnh này là tài nguyên cho mod_security; nó cần phải kiểm tra các gói tin (giao thức HTTP) và xử lý theo các luật đã định.

Mười lăm phút sau khi snort hoạt động, tôi xem lại server load:

# w
load average: 0.78, 1.04, 8.75


Trong vòng 5 phút vừa qua, server load chỉ còn 0.78
Trong vòng 15 phút vừa qua, server load chỉ còn 1.04
Trong vòng 30 phút trước đây, server load nằm ở mức 8.75 (tương đương như hồi chiều).

Snort log vẫn ghi nhận cơn lũ x-flash ùn ùn tuôn vào. Server log vẫn lác đác ghi nhận các x-flash bị status 403 và ngay lúc ấy, tôi log vào diễn đàn HVA bằng trình duyệt. Tình hình được cải thiện thấy rõ so với chiều nay. Tôi duyệt qua các trang trong diễn đàn và cảm thấy tốc độ truy cập hoàn toàn có thể chấp nhận. Ngay trong khoảng thời gian này tôi bắt đầu thấy lác đác một số GET request (cụ thể) đến cái banner chính của hva với URI như sau:

GET /forum/style_images/fusion[1]/banner.swf HTTP/1.1. Điều này chứng tỏ kẻ tấn công HVA vừa dàn dựng loạt GET này mới toanh (bởi vì HVA vừa nâng cấp phiên bản diễn đàn và cấu trúc URI dùng để chứa các bức hình đã thay đổi). URI trên chỉ vừa được cập nhật mấy ngày trước đây. Tôi bèn tail cái log của snort để kiểm nghiệm sự hiện diện các cú GET này như sau:

# tail -f /var/log/snort/alert | grep GET

Quả thật cứ mỗi giây lại có dăm ba "quả" GET đi vào. Tôi quyết định "dump" một mớ packets để phân tích xem các cú GET này có những thay đổi gì hay không. Sau hai phút, tôi tắt bỏ tcpdump và tải gói dump này về laptop của tôi. Tôi tự nhủ "chuyện phân tích này có thể để dành cho sáng mai, trên đường đi làm".

Tôi dành khoảng thời gian ngắn ngủi còn lại của ngày 21/1 để thực hiện một loạt penetrating test đến HVA server ở tầng thấp (bao gồm scanning, flooding và gởi một loạt các gói tin "bất hợp lệ") để kiểm tra "thái độ" của máy chủ HVA. Tôi không tiện nêu ra kết quả ở đây vì nó quá... tế nhị. Điều tôi có thể tiết lộ với bạn là sau khi khởi động snort, nó đã cảnh báo đến vài chục loại tấn công đến HVA server (nhiều loại, nhiều kiểu, nhiều mức độ khác nhau).

Mười lăm phút sau nữa, tôi kiểm tra lại server load và thấy các con số trung bình không thay đổi gì mấy (vẫn ở mức 0.7 - 1.0 0.8 ). Tôi lẩm bẩm "chỉ tại snort vắng mặt và firewall quá dễ chịu mà ra nông nổi" và log off HVA server.

Kinh nghiệm đáng nêu lên ở đây (cho những ai có trách nhiệm bảo mật cho các máy chủ):
- môi trường máy chủ càng ổn định thì máy chủ càng vững vàng. Càng nhiều dời đổi, càng tạo nên những thiếu sót (khó thấy).
- mọi thay đổi trên máy chủ (như cập nhật phiên bản, thay đổi cấu hình hoạt động, thay đổi địa chỉ...) đều phải được ghi nhận trong một hồ sơ nào đó để tiện theo dõi và xử lý khi cần.
- tạo một "check list" để kiểm tra trọn bộ các cơ phận liên quan trực tiếp và gián tiếp trong cơ chế bảo mật của (các) máy chủ.
- sau mỗi lượt thay đổi / cập nhật, phải thực hiện một quy trình thử nghiệm cho máy chủ này. Thử nghiệm này có thể trải dài từ thử nghiệm tính năng cho đến thử nghiệm tính bền bỉ và vững vàng của máy chủ (penetrating test hay còn gọi là pen test).

Chuyện gì tiếp tục xảy ra với các cú POST và GET? Mời bạn đón xem phần http://hvaonline.net/hvaonline/posts/list/280.html

Trưa 21/01/2005
Các cuộc tấn công "x-flash" được biên cải sẽ tiếp tục xảy ra với HVA trong tương lai, đó là điều tôi đã ngầm phỏng đoán. Chỉ có điều, nó đã xảy ra muộn hơn tôi nghĩ nhưng nó đã xảy ra.

Trưa nay, lúc ăn trưa, tôi log vào diễn đàn HVA, mọi chuyện vẫn có vẻ bình thường. Không hiểu sao tôi lại quyết định logon HVA server để xem xét qua tình hình server. Điều đầu tiên tôi kiểm tra (theo thói quen) là server load:

# w
load average: 1.32, 2.02, 1.25


Hơi cao hơn bình thường với thời điểm này trong ngày.

Tôi thử "tail" log của web server và hết sức ngạc nhiên (lý thú) khi thấy lác đác những mảng log như sau:
Code:
152.163.101.6 - - [21/Jan/2005:11:35:21 -0400] "POST /forum/ HTTP/1.1" 200 312 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
203.162.177.113 - - [21/Jan/2005:11:35:45 -0400] "POST /forum/ HTTP/1.1" 200 312 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
221.132.58.28 - - [21/Jan/2005:11:36:22 -0400] "POST /forum/ HTTP/1.1" 200 312 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
24.34.4.118 - - [21/Jan/2005:11:36:25 -0400] "POST /forum/ HTTP/1.1" 200 317 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)"


Dạng log này quá quen thuộc với tôi vài tháng trước đây. Tôi lẩm bẩm "rốt cuộc cũng hiện lên lại đây, hơi trễ hơi dự đoán nhưng cũng đã xuất hiện trở lại".

Tôi chạy tcpdump để capture một mớ packets điều tra xem thử chuyện gì xảy ra:

# tcpdump -s0 port 80 -w /tmp/dump-21-01-2005

Sau hai phút, tôi ngưng tcpdump, nén kết quả capture được (để tải về laptop của tôi cho nhanh). Sau khi tải gói nén .gz này về, tôi kiểm tra lại server load một lần nữa rồi logoff (server load vẫn giữ mức 2.+ và tôi phải quay lại làm việc).

Tôi vùi đầu vào mớ công việc ở công ty liên tiếp mấy giờ và quên bẵng gói nén .gz kia, quên bẵng chuyện gì (có thể tiếp tục) xảy ra với HVA. Tôi chuyển qua "Firefox" và thử "refresh" trang forum HVA: hiện có hơn trăm mạng đang ở trên forum. Trang load chậm hơn bình thường (chậm theo cảm giác của tôi).

Tôi dành 15 phút của giờ giải lao chiều (afternoon tea time) để kiểm tra xem gói nén .gz chứa mớ packets được capture hồi trưa này có cái quỷ quái gì trong đó.

Đập ngay vào mắt tôi là đoạn sau:
Code:
POST /forum/ HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Content-Type: application/x-www-form-urlencoded
Content-Length: 712
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)
Host: 219.207.204.25
Connection: Keep-Alive
Cache-Control: no-cache
total=23&Submit=Submit&attack=1&diachi=http%3A%2F%2Fviemarket%2Ecom%2F&url1=
http%3A%2F%2F219%2E207%2E204%2E25%2Fforum%2F&url2=http%3A%2F%2F219%2
E207%2E204%2E25%2Fforum%2F&url3=http%3A%2F%2F219%2E207%2E204%2E25%2F
forum%2F&option=search&s=&do=login&url=http%3A%2F%2Fvikhoa%2Ecom&agree=1&
password%5Fmd5=&passwordconfirm%5Fmd5=&username=Tintucvietnam&password=
thangcho&passwordconfirm=thangcho&email=admin%40tintucvietnam%2Ecom&emailconfirm=
admin%40tintucvietnam%2Ecom&imagestamp=tintuc&imagehash=47b4a32f7767bfc7b83f8f3e
cf2e8c66&timezoneoffset=8&dst=2&options=&adminemail=1&vb%5Flogin%5Fusername=Hoanghiep
&cookieuser=1&vb%5Flogin%5Fpassword=dumemaykhoa&forcewwwect=1&vb%5Flogin%5Fmd5
password=&%5F%5FOoO%5F%5F=1&1=


Ôi, một biến thái mới!

POST? hiển nhiên là POST vì trên log của web server (ở trên) đã biểu thị chi tiết này rồi. Gì nữa nhỉ?
Content-Length: 712? cha chả, rõ ràng có cải tiến. So với đợt tấn công bằng "POST" cách đây vài tháng, Content-length có giá trị khoảng 2387 bytes hoặc nhiều hơn. Tôi tin chắc kẻ tấn công đã đọc loạt "ký sự" này và đã rút tỉa những chi tiết cốt lõi để ứng dụng cho lần này. Tại sao "Content-length" chỉ còn 712 bytes? Đơn giản là anh chàng muốn tránh tình trạng "Continuation", tránh sự nặng nề của khối lượng payload làm chậm các cú "POST" và quả thật điều này có tác dụng.
Connection: Keep-alive?Cache-control: no-cache? Xét lại phần tôi đã phân tích trước đây về vấn đề dùng proxy server nào đó trên đường đi của gói tin để tấn công HVA nhanh hơn và đỡ tốn tài nguyên cho máy khởi tạo gói tin hơn - một lối chơi "cao tay", tôi e rằng anh chàng đã không tính toán một cách cao tay mà chỉ là một sơ sót vô tình của lần trước. Lần này, cho dù áp đặt trình duyệt (x-flash cho trường hợp này) đòi hỏi "Keep-alive" và "no-cache" nhưng tay này làm ngơ hoặc (không đọc kỹ bài ký sự) với một chi tiết hết sức quan trọng là HVA web server không hề cho "keep-alive" từ dạo ấy. Mỗi request đi vào có payload quá lớn, cần được "chẻ" ra để tiếp tục gởi đi vẫn phải đi qua chu trình tạo thêm socket mới. Bởi thế HVA firewall mới điều tác được giới hạn connection.

Thử "decode" cái mớ bùng nhùng ở trên xem có gì?
Code:
total=23&Submit=Submit&attack=1&diachi=http://viemarket.com/&url1=http://219.207.204.25/forum/&url2=
 http://219.207.204.25/forum/&url3=http://2...=&do=login&url=
 http://vikhoa.com&agree=1&password_md5=&pa...etnam&password=
thangcho&passwordconfirm=thangcho&email=admin@tintucvietnam.com&emailconfirm=admin@tintucvietnam.com&
imagestamp=tintuc&imagehash=47b4a32f7767bfc7b83f8f3ecf2e8c66&timezoneoffset=8&dst=2&options=&adminemail=
1&vb_login_username=Hoanghiep&cookieuser=1&vb_login_password=dumemaykhoa&forcewwwect=1&vb_login_md5password=
&__OoO_

Đọc kỹ đoạn trên có lẽ bạn sẽ đoán được phần nào lứa tuổi và tâm thức của kẻ tấn công HVA. Bạn cũng có thể thấy ViKhoa (nào đó) bị "ghét cay, ghét đắng" và tintucvietnam cũng "bị" lôi vào . Điều đáng nói về mặt kỹ thuật với nhúm thông tin ở trên là: cho dù tay tấn công HVA có biến cải nội dung và tính chất của các cú "POST" lần này (hoặc những lần khác nữa), hắn vẫn không thể không để lại một vài ấn tích đặc biệt nào đó. Các ấn tích này là chìa khoá để snort và firewall làm việc. Tôi sẽ không nêu ra cụ thể các "ấn tích" này ở đây nhưng chỉ gợi ý một cách tổng quát như thế. Nếu tay tấn công HVA tiếp tục đọc ký sự này, hắn có cái để suy nghĩ

15 phút giải lao trôi qua nhanh chóng. Tôi chuẩn bị phải lao vào một cuộc họp kéo dài 2 giờ đồng hồ. Trước khi vào họp, tôi kiểm tra nhanh qua tình hình của HVA server. Ôi chao, server load lên tới 82? Cái khỉ gì đây nhỉ?

Grep thử xem có bao nhiêu cú SYN ngay trong lúc này:

# netstat -nat | grep SYN | wc -l
3879


Tôi choáng váng..... vò trán và lẩm bẩm: "what the?"

Tôi xem lại cấu hình của firewall thì thấy nó quá "cởi mở" . Tôi điều chỉnh ngay cấu hình firewall để tương thích với tính chất hoạt động của web server và tái khởi động firewall. Hai phút sau, server load từ 82 giảm xuống còn khoảng mức 7 đến 8. Truy cập vào diễn đàn HVA còn chậm lắm nhưng tôi phải vào họp rồi. Tối nay, sau bữa ăn tối, tôi phải điều tra kỹ lưỡng xem có chuyện gì xảy ra. Tạm thời các cú "đấm" không thể làm chết nổi HVA server nhưng thành viên truy cập vào sẽ bị chậm thấy rõ nhưng cứ tạm thời là thế. Tôi đành xếp laptop lại và sẽ hình thành vài cái snort signature trên tàu lửa, trên đường đi làm về nếu không còn thời gian để thực hiện chuyện này ngay lập tức.

5 giờ 15 phút chiều 21/1/2005
Tôi vừa họp xong. Trong đầu ngổn ngang các vấn đề cho công việc ở sở. Đã đến lúc ra về nhưng tôi cần lấy thêm vài thông tin trên HVA server để phân tích trong khi ngồi trên tàu lửa về nhà. Tôi login HVA server một lần nữa.

Chà, server load vẫn ở mức 7-8. Grep thử xem có bao nhiêu cú SYN ngay trong tích tắc này:

# netstat -nat | grep SYN | wc -l
389



Chờ 30 giây, tôi chạy lệnh trên lần nữa:

# netstat -nat | grep SYN | wc -l
416


Có gia tăng! Nhưng không đáng kể. Có lẽ số lượng IP đang cùng "đấm" HVA gia tăng ngay lúc này.

Tôi kiểm tra nhanh snort log. Ôi trời, hoàn toàn trống rỗng, snort log không có lấy một cái entry. Thử xem có process nào của snort không:

# ps -ef | grep snort

Bặt vô âm tín. Tôi ngỡ ngàng nhận ra rằng snort đã không hề hoạt động tự khi nào. Chuyện này phải xem lại, ngay lúc này tôi phải khởi động ngay snort để đỡ một số cú đấm một cách tạm thời, tôi hí hoáy thêm vào hai cái signatures mới trong mới rules của snort:

# /etc/init.d/snort start

Ôi chao, snort failed? Xem thử syslog báo cái gì, tôi tail 50 dòng cuối cùng của syslog và thấy ngổn ngang những vấn đề cần phải điều chỉnh lại cho snort. Tôi sực nhớ ra rằng JAL quyết định dùng ngay cái server dùng để chuyển đổi và nâng cấp forum (thành công) làm server mới cho HVA (vì đã gặp quá nhiều trục trặc trong khi chuyển đổi database). Server này không hề chỉnh định gì cụ thể cho snort ngoài phiên bản đã cài theo mặc định. Đúng là một thiếu sót sau khi chuyển đổi server. Thôi rồi, tối nay tôi phải biên dịch lại trọn bộ snort từ nguồn và sắp xếp từ đầu đến cuối.

Tôi xếp laptop lại, phóng nhanh ra cửa cho kịp chuyến tàu.

Các bạn có thể theo dõi tiếp phần 12 tại http://hvaonline.net/hvaonline/posts/list/213.html
Sáng 3/11:
Sáng nay tôi vào sở trễ hơn thường ngày vì tối qua thức quá khuya. Nói là trễ nhưng thật sự chỉ mới 7 giờ 30 sáng. Tôi quyết định dành riêng 30 phút để "thanh tra" HVA server và hoàn tất những gì tôi bỏ dở trước khi bắt tay vào chuyện viết bản báo cáo sự cố xảy ra trên server của công ty tối hôm qua.

Việc đầu tiên là tôi thử truy cập diễn đàn HVA bằng trình duyệt. Dự tưởng trong đầu chắc sẽ chậm lắm đây nhưng sự thử hoàn toàn trái ngược với điều tôi nghĩ; vào diễn đàn HVA vẫn nhanh như bình thường. Tuy nhiên, trình duyệt hiện ra thông báo "database is not available". Tôi thầm nghĩ: chắc giờ này chẳng ai thèm DoS và giờ này bên VN chỉ 4 giờ 30 sáng nhưng database không có thì có lẽ server vẫn sống nhưng database thì chết tiêu." Tôi log ngay vào HVA server và quả thật, server HVA vắng hoe; server load nằm ở mức 0.02. Tôi kiểm tra nhanh qua tình hình server xem nó có "bị" restart tối hôm qua hay không:
$ uptime
05:49:08 up 19 days, 10:04, 1 users, load average: 0.02, 0.02, 0.25


vậy là server vẫn còn sống sót sau "cơn bão" kinh hoàng. Chạy thử vài lệnh tiếp theo để kiểm tra process thì rõ ràng database đã "chết" tự khi nào. Tôi không rõ database bị "down" từ lúc nào và tôi cần rõ điều này. Chạy thêm vài lệnh grep đến mấy cái log, tôi xác định được database bị down từ 10 giờ 22 phút giờ trên server, có nghĩa là khoảng 0 giờ 22 phút giờ nơi tôi cư ngụ và khoảng 9 giờ 22 phút giờ VN. Tôi vò đầu lẩm bẩm: "chỉ có vài phút sau khi tôi logoff HVA server tối hôm qua! tại sao tôi không restart lại cái database server sau khi restart lại web server nhỉ?" Dù gì đi chăng nữa cũng là sự đã rồi. Có lẽ lý do HVA server sống sót tối hôm qua là do database server bị down suốt đêm (?)

Tối hôm qua, ngay khi tôi login HVA server và điều chỉnh web service để tháo bỏ ấn định "keep-alive", có lẽ lúc ấy database server đã tràn ngập QUERY và ở trong tình trạng "sống dở, chết dở" rồi nhưng tôi lại không để tâm đến nó. Có lẽ do não bộ của tôi bị mụ mẫm sau một ngày làm việc dài dằng dặt hôm qua nên không còn sáng suốt để suy xét vấn đề nữa. Tôi quyết định để yên database server ở tình trạng "down" như vậy để tiện làm việc.

- trước tiên, tiện tay tôi kiểm tra cấu hình database và xét qua số lượng connection cho phép. Giá trị ấn định này khá cao, nên tôi điều chỉnh để giảm bớt số lượng connection tương thích với lượng connection limit được ấn định trên firewall.

- kế tiếp tôi kiểm tra lại cấu hình của web server, điều chỉnh vài giá trị quan trọng nhất trong ấn định process được fork như thế nào để phục vụ requests (xem lại chú thích 45) đồng thời đưa vào một chuỗi filter cho mod_security.

- tôi tiếp tục chuyển xuống tầng snort và đưa vào mấy cái signatures đang dang dở; điều chỉnh thêm vài chi tiết nhỏ để cố gắng tạo hiệu xuất hơn và tái khởi động snort. Sau khi tái khởi đông, Snort hoạt động bình thường nhưng chưa thông báo thông tin nào về vấn đề DoS ở dạng URI ngẫu nhiên cả. Điều này hiển nhiên là vì tôi chẳng hề thấy dấu hiệu DoS ngay từ lúc logon HVA server.

- kế tiếp tôi xem xét lại firewall. Lần này tôi quyết định mở rộng connection limit trên firewall tương phản với việc thắt chặt nhiều điểm quan trọng trên web server. Sở dĩ tôi làm thế là vì muốn tạo cơ hội cho người dùng có thể truy cập được. Làm như thế server load sẽ gia tăng nhưng bằng mọi giá tôi phải tạo cơ hội cho người dùng hợp pháp có thể truy cập đến diễn đàn. Sau khi hoàn chỉnh firewall, tôi tái khởi động nó ngay (kẻo lại quên).

- và cuối cùng, tôi dành một phần lớn thời gian trong 30 phút ngắn ngủi kia để điều chỉnh tất cả giá trị liên quan đến tcp stack trên kernel có thể xử lý khối lượng request khổng lồ tương tự như tối hôm qua. Nguyên tắc điều chỉnh các giá trị kernel này rất đơn giản:

1. tôi muốn có tối đa lượng memory để cho phép một số lượng socket khổng lồ được mở bởi vì không có gì tệ hơn tình trạng socket bị DoS chiếm hết và người dùng hợp lệ không thể vào.

2. tôi muốn thời gian một cú SYN tồn tại ngắn hơn bình thường vì nếu các cú SYN được dời khỏi hàng đợi (queue) càng nhanh thì cơ hội server có thể tiếp nhận thêm SYN càng nhiều.

3. tôi muốn thời gian chờ đợi FIN và RST hoàn tất (các giá trị biểu thị TIME_WAIT, FIN_WAIT....) ngắn hơn bình thường vì những cú đợi này càng kéo dài, lượng memory bị chiếm giữ cho mỗi socket đã hoàn tất càng lâu và tình trạng này sẽ càng ứ đọng nếu DoS kéo dài.

4. thay thế vào việc giảm thiểu thời gian một gói tin ở dạng SYN, tôi gia tăng số lượng SYN được tiếp nhận và được nằm trên connection queue. Tôi muốn số lượng request đi vào được nhưng chưa được xử lý có cơ hội chờ đợi lâu hơn (trước khi chúng bị huỷ); bởi vì tôi không muốn trình duyệt của người dùng hợp lệ phải "retry" quá nhiều để có thể đi vào diễn đàn trong khoảng thời gian server đang bị DoS. Nên biết rằng syn_timeout khác với syn_backlog, phần 2 ứng dụng cho syn_timeout và phần 4 ứng dụng cho syn_backlog (số lượng gói SYN được chờ để xử lý).

Xét lại các bộ phận một lần nữa, tôi cảm thấy hài lòng và tiến hành khởi động database và các dịch vụ cần thiết khác. Mọi thứ chạy ngon lành ngay từ lượt thử đầu tiên. Tôi tạo thêm một console đến HVA server trên màn hình và phóng cái "đuôi" tail thứ nhất để theo dõi snort log, cái thứ nhì để theo dõi thông báo của mod_security và tạm ngưng việc "táy máy" với HVA server để bắt đầu vào công việc ở sở.

Trưa, chiều 3/11:
Suốt bốn giờ vừa qua, hễ lúc nào có dịp là tôi chuyển sang hai cái console ở trên và xem chừng có biến cố gì trên server hay không? Thỉnh thoảng có vài loạt URI ngẫu nhiên đi vào và đều bị cả hai cơ phận snort, mod_security tóm chúng một cách đều đặn sau khi thoả mãn điều kiện connection limit trên firewall (mặc dù lúc này chỉ mới 9 giờ sáng bên VN). Tôi an tâm tiếp tục làm việc.

Mãi đến 3 giờ chiều, số lần các cú DoS đi vào thường xuyên hơn nhưng server load chưa hề lên khỏi mức 1.0. Tôi mở trình duyệt và thử truy cập vào diễn đàn HVA: thông suốt, nhanh chóng. Tôi thử nhấn Ctl-F5 -55- liên tục vài cái: chiếc "đồng hồ chờ đợi" hiện ra lâu hơn. Càng nhấn nhiều Ctl-F5, càng chờ đợi lâu. Lý do tại sao tôi thử nghiệm bằng cách này? Bởi vì lúc này web server của HVA không còn chế độ "keep-alive" nữa, mỗi cú "refresh" trên trình duyệt sẽ tạo dăm ba cái sockets với HVA server để tải nội dung của diễn đàn về trình duyệt. Trong lúc loạt connections của cú nhấn Ctl-F5 đầu tiên vẫn còn tồn tại, nếu tôi tiếp tục nhấn thì sockets mới sẽ được tạo thêm và sẽ bị "vướng" ngay vào quy định connection limit của firewall vì tôi không thể tạo thêm connection vượt quá giới hạn cho phép trong cùng một lúc. Nếu tôi thong thả duyệt từng trang một, mỗi trang tôi dừng lại tối thiểu là vài mươi giây (trong khoảng thời này connection giữa trình duyệt của tôi và HVA server đã kết thúc) thì tôi không gặp bất cứ cản trở nào. Đây chính là tình trạng duyệt web bình thường của một người dùng hợp lệ vậy.

Biết chắc là ấn định connection limit + "no keep-alive" làm việc "hài hoà" với nhau. Tôi an tâm xếp laptop lại chuẩn bị rời sở. Tôi tự nhủ là tối nay sẽ dành một giờ đồng hồ theo dõi chuyện gì xảy ra trên HVA server.

Tối 3/11:
Ăn tối xong, sau khi hoàn tất các chuyện lặt vặt, tôi bắt tay vào việc "thanh tra" HVA server.

8 giờ 30 tối nơi tôi cư ngụ chỉ mới 5 giờ 30 chiều giờ VN nhưng cứ thử xem sao. Tôi mở laptop lên, phóng ngay trình duyệt để vào diễn đàn HVA: khởi tạo trang chủ hơi chậm nhưng sau đó mọi chuyện bình thường và tôi biết lý do tại sao khởi tạo lại chậm, tôi mỉm cười mở ra hai console vào HVA server.

Nhưng thường lệ, tôi xem qua server load:
$ w
bình thường, giá trị server load trung bình là 1.1, tốt!

Tôi xem qua số lượng SYN đang hiện hữu trên server:
$ netstat -nat | grep SYN | wc -l
72

nhiều hơn bình thường nhưng chắc chắn là quá ít so với cơn lũ hôm qua.

Tôi xem qua số lượng GET dùng URI random mà snort đã bắt được từ lúc signature mới được đưa vào từ sáng nay:
# grep -i "random" $SNORT_LOG/alert | wc -l
317476


Kinh nhỉ? Gần 32 ngàn cú trong vòng 12 giờ qua.

Tôi muốn xem số lượng GET dùng URI random mà mod_security đã tóm được từ sáng nay:
grep -i "?&time" $HTTP_LOG/mod_sec.log | wc -l
17749

Nhiều thật! không hẳn server yên tĩnh như tôi nghĩ qua vài lần kiểm tra trong ngày nhưng rõ ràng server load không lên cao từ sáng nay sau lúc tôi điều chỉnh lại cấu hình server cho đến lúc này. 17749 lần ghi nhận trên mod_sec.log tương đương với 17749 cú QUERY đến database server nếu như chúng không được chặn lại từ bên ngoài web server. Nếu quy ra thành giá trị server load, con số này hẳn kinh khủng. Thảo nào đêm qua database serve không chết đứ đừ.

Tôi phóng thử một cái "đuôi" tail đến firewall log để xem tình hình hiện tại ra sao. Lác đác có dăm ba cú URI random đi vào trong vài chục cú request đến server. Tôi thầm nghĩ: "nếu cứ DoS kiểu này thì đến tết Ma-rốc cũng không xước nổi một cái vảy." Chắc còn quá sớm.

Tôi tò mò muốn xem thử có cú x-flash nào thuộc dạng POST đi vào từ khuya hôm qua hay không:
# grep "POST" $SNORT_LOG/alert

Hoàn toàn không có.

Thế x-flash dạng GET?
# grep "GET" $SNORT_LOG/alert | wc -l
34153


Whoa! có lẽ con số này bao gồm các cú GET đến HVA banner lẫn các cú GET với URI ngẫu nhiên.

Táy máy với mấy cái log chừng nửa giờ, tôi đâm chán vì chẳng có gì đáng phải quan tâm. Tôi quyết định đi chơi bóng bàn và sẽ quay lại sau một giờ đồng hồ.

9 giờ 25 phút 3/11:
Tôi trở lại khi hai cái console nối vào HVA server đang ở tình trạng "chảy" cuồn cuộn các thông tin về những cú GET đang hăm hở đổ vào HVA server. Hãy xem vào diễn đàn bằng trình duyệt ra sao. Tôi khởi động trình duyệt vào chọn địa chỉ HVA forum từ bookmark: vẫn hơi chậm lúc đầu nhưng sau khi đã vào được diễn đàn rồi thì lướt các trang thông suốt.

Tôi chuyển qua một trong hai cái console đang in ra hàng tràng log trên màn hình và xem thử có bao nhiêu cú SYN đang ập vào:
# netstat -nat | grep SYN | wc -l
173


Thử lại lần nữa:
176

Thêm lần nữa xem sao:
169

Tôi lẩm nhẩm, với số lượng log đang đổ cuồn cuộn trên màn hình kia mà chỉ có trung bình từ 160 đến 180 cú SYN trong bất cứ lúc nào thì hẳn là giá trị ấn định SYN timeout trên kernel đã có hiệu quả rõ rệt. Điều này là thế nào? Như đã nói ở điểm thứ 2 ở trên, tôi cố tình chỉnh định để SYN timeout ngắn hơn bình thường kiến cho các cú truy cập mới được giải quyết nhanh chóng hơn.

Phải thử "dump" một đoạn các packets xem sao.
Tôi chạy lệnh:
# tcpdump -s0 port 80 -w /tmp/dump-03-11-2004

Trong khi đoạn dump trên đang chạy, tôi muốn xác định có bao nhiêu ESTABLISHED connections hiện đang có trên server:
# netstat -nat | grep ESTABLISHED | wc -l
283



Tôi chạy thêm lệnh này và đưa kết quả và một hồ sơ tạm thời để phân tích kỹ hơn:
# netstat -nat | grep ESTABLISHED | sort > /tmp/conn.txt
Đúng như dự đoán, sau khi các connection được lựa theo đúng thứ tự, cứ mỗi IP chiếm từ 4 đến 8 connections.

Chờ vài phút, tôi dừng cú tcpdump và tải hồ sơ này xuống laptop của tôi để phân tích. Thông tin từ đoạn các packets chỉ rõ một điều:
- cứ mỗi IP lại hình thành trung bình 4 connections, tuy nhiên chúng kết thúc nhanh chóng và nhất là các cú GET với URI random vì ngay khi mod_security phát hiện chúng thuộc diện vi phạm, nó đã báo lỗi ngược về chủ nhân của cú GET này và huỷ bỏ connection.
- có vô số gói tin đi vào thuộc diện vi phạm đã bị snort RST ngay khi nó bắt gặp gói tcp ACK-PSH có chứa thông tin về cú GET dùng URI ngẫu nhiên.
- có những tcp stream nối tiếp nhau từ một IP bao gồm cả các connections chứa cả thông tin truy cập hợp lệ lẫn thông tin thuộc về các cú GET đang tấn công HVA. Điều này chứng tỏ nguồn tấn công và nguồn người dùng cùng đi xuyên qua một IP nào đó (có thể là proxy, có thể là NAT server ở đâu đó) và chúng xảy ra cùng một lúc (hoặc trước sau trong tíc tắc).

Đối với tôi, bấy nhiêu thông tin đã quá đủ để xác định tình hình như sau:
- trận DoS vẫn tiếp diễn đều đặn. Tuy nhiên, chắc chắn những gói tin "tàn phá" kia không còn có cơ hội dùng một ESTABLISHED connection để đẩy các cú GET dồn dập đến HVA server nhưng ngày hôm trước mà phải tuân thủ theo đúng nguyên tắc "xong một request, mở socket mới" và nguyên tắc này được connection limit điều tác triệt để.

- bởi các cú SYN không tồn tại lâu như bình thường nên server có cơ hội và tài nguyên tiếp nhận nhiều SYN hơn bình thường. Mọi connection biến chuyển từ SYN_RECV sang ESTABLISHED và đi đến TIME_WAIT hết sức nhanh chóng. Điều này tạo cơ hội cho người dùng hợp lệ có thể "chen chân" với cơn lũ DoS.

- snort đóng góp rất lớn trong vấn đề hủy bỏ các socket được tạo ra từ những request "tàn phá" kia bằng cách RST chúng. Đối với tôi, đây là cách hữu hiệu trong việc ổn định connection queue của server.

- không hề có bất cứ cú GET dùng URI ngẫu nhiên đi qua khỏi cửa ngỏ mod_security (nếu chúng có đi lọt qua được cửa ngỏ snort) cho nên chúng không hề tạo bất cứ ảnh hưởng nào đến database server.

- server load hoàn toàn bình thường và xê dịch ở mức 0.9 - 2.8 là tối đa.

Tôi nán thêm nửa giờ nữa để theo dõi tình hình trên HVA server. Số lượng SYN có gia tăng nhưng không đủ dồn dập để phương hại đến server. Tuy nhiên, điều tôi lo lắng là số lượng log được tạo ra trong khi trận DoS tiếp diễn. Mặc dù sức chứa trên HVA server có thể chứa hàng chục gigabytes logs nhưng điểm quan trọng là sự hao tổn tài nguyên trong cơ chế I/O. Tôi quyết định điều chỉnh firewall, web server, mod_security và các cơ phận log khác giảm thiểu mức độ log rồi khởi động lại các dịch vụ này.

10 phút trôi qua.

Rồi 15 phút trôi qua.

20 phút trôi qua, khối lượng DoS càng gia tăng qua biểu thị của số lượng SYN_RECV trên netstat. Tôi vẫn có thể nhấn Ctl-F5 và trang web của HVA diễn đàn vẫn tải nhanh chóng. Để xác định được chính xác bao nhiêu cú SYN đi vào trong một giây ngay lúc này, tôi quyết định "dump" thêm một mớ packets. Tôi viết một đoạn script đơn giản để chạy tcpdump và buộc nó phải ngưng lại sau 60 giây. Kết quả cho thấy có đến trên 1300 cú SYN đến HVA server trong một giây nhưng phần lớn bị loại bỏ ở firewall vì quá giới hạn cho phép. Phẩn còn lại bị "time-out" và bị hủy vì phải đợi lâu hơn mức ấn định trên connection queue. Phần còn lại bị snort RST ngay trước khi được firewall quản chế. Các cú SYN thành công (vào được) và thuộc diện "bất hợp lệ" đều bị web server trả lại thông báo lỗi 403.

Tôi gật đầu thoả mãn với kết quả và logoff HVA server.

Những ngày tiếp theo đó, dạng DoS dùng URI ngẫu nhiên vẫn tiếp diễn tuy nhiên chúng thưa dần rồi tắt hẳn.

Mãi đến ngày 13 tháng 11, một lần nữa server lại "bị nạn". Ngày 13/11 tôi không hề vào net. Đến ngày 14/11, không log vào HVA server được, tôi gởi e-mail đến JAL để hỏi thăm tình hình. Sau hôm đó, JAL cho tôi biết là HVA server bị DoS rất kinh khủng tạo sự cố cho card mạng và bị dịch vụ cung cấp đường dây Internet than phiền về khối lượng traffic khổng lồ ra vào HVA server nhưng server hoàn toàn bình thường, không bị sự cố gì cả. Bởi thế, JAL đã phải cho diễn đàn tạm ngưng hoạt động vài ngày để sắp xếp đưòng dây mới tạm thời trước khi tìm một dịch vụ thích hợp. Điều đáng tiếc là JAL đã quên không tạo một cú packet "dump" trong khi HVA bị tấn công lần này, cho nên tôi không đoán nổi là chuyện gì đã xảy ra nhưng tôi tin rằng, đây là một dạng DoS mới nào đó. Dù nó đã không triệt được HVA server nhưng cũng đã tạo không ít phiền toái cho vấn đề sắp xếp dịch vụ cung cấp Internet mới vì khối lượng thông tin tràn ngập đường dẫn.

Cho đến nay, HVA server đã dời sang một đường dẫn "tạm thời" thứ nhì sau biến cố ngày 13/11 và vẫn bị DoS đều đặn (nhưng không kinh khủng) như trước nữa. Bởi vậy tôi mới có thời gian để viết bài phân tích cho các bạn đọc, đồng thời suy nghĩ và phân tích sâu thêm các biến thái của các đợt tấn công có thể xảy ra để điều chỉnh lại server cho thích hợp. Tính từ ngày đầu tiên tôi logon HVA server (xuyên qua SSH) cho đến nay, đã có hơn 30 lần điều chỉnh lớn, bé để thích ứng với hoàn cảnh. Điều tôi muốn nói ở đây là: để bảo vệ máy chủ đến mức độ tối đa trong hoàn cảnh và điều kiện cho phép, điều đầu tiên mình phải hiểu rõ mình đang bảo vệ cái gì, hiểu rõ điểm yếu của mình ở đâu và hiểu rõ dụng ý của đối phương. Không có một công thức kỳ diệu nào có thể dùng để ứng dụng cho mọi trường hợp và càng không thể có một software nào có thể hoàn toàn bảo vệ vững chắc một hệ thống làm việc. Bảo mật là công tác lâu dài và bền bỉ, nó đòi hỏi sự quan tâm thường xuyên, khả năng phán đoán tình hình và phản ứng kịp thời. Để nhận ra được điểm yếu và điểm mạnh của mình không chỉ đòi hỏi kiến thức mà còn đòi hỏi khả năng tưởng tượng nữa. Tôi mong bạn có thể rút tỉa ra được những điều bổ ích và lý thú của loạt "ký sự" này để tự ứng dụng cho môi trường của mình.

Liệu loạt "ký sự" này có tiếp tục hay không? Tôi không rõ. Hy vọng là không nếu không có biến cố gì đáng phân tích.

Chúc bạn một Noel và một năm 2005 vui tươi.

Chú thích:
-55- tôi dùng laptop của công ty và chỉ có thể duyệt web bằng Internet Explorer. Ctl-F5 là để buộc trình duyệt lấy phiên bản mới nhất từ web server thay vì dùng một bản đã được cached ở đâu đó. Tương phản với F5, trình duyệt chỉ dùng bản đã được cached.

Các bạn có thể theo dõi tiếp phần 11 tại http://hvaonline.net/hvaonline/posts/list/212.html
Chiều 2/11:
Hôm nay tôi bận rộn kinh khủng nên không vào HVA. Mãi đến lúc gần tan sở, tôi mới log vào diễn đàn để lướt nhanh qua xem có mục gì mới và hấp dẫn không. Điều đầu tiên tôi nhận ra là truy cập đến diễn đàn HVA cực chậm. Tôi nhận được vài cái PM trong đó có hai cái từ JAL. JAL cho biết là diễn đàn bị DoS liên tục từ khuya hôm qua đến bây giờ, JAL cũng đã nhận định rằng các cú GET ở dạng /forum/?&time=0.13435 có lẽ là các tấn công hiện đang xảy ra trên diễn đàn. Tôi vội log vào HVA server để xem xét tình hình.

Ngay khi tạo cái đuôi tail đầu tiên đến web server log của HVA, tôi choáng váng vì tốc độ dồn dập của loại GET trên. Bởi web server log không có khả năng tường trình các chi tiết cần thiết để đánh giá loạt tấn công hiện đang xảy ra, tôi chạy ngay một phát tcpdump và chọn option ra lệnh cho tcpdump ghi nhận đầy đủ hết tất cả các thông tin hàm chứa trong mọi tầng giao thức -53-. Sau vài phút, tôi hối hả tải mớ "dump" này về laptop, tiện tay sao chép luôn cái log của web server. Sau đó, tôi điều chỉnh cho firewall giảm bớt số lượng connection cho phép để tạm giảm thiểu độ tải của server và phóng ngay ra cửa cho kịp chuyến tàu về nhà.

Trên tàu lửa, tôi mở đoạn dump vừa tạo ra để xem xét sự thể. Dán chặt đôi mắt vào màn hình của laptop, tôi thật sự choáng khi nhìn thấy nội dung của mớ tcpdump vừa lấy được lúc nãy. Tôi tự rủa mình không ngớt vì đã xem nhẹ mấy cái /forum/?&time=0.xxxxx ngày hôm qua nhưng lại tự an ủi là đã thắt chặt connection limit trước khi rời sở. Dẫu HVA server không bị "xụm" đi chăng nữa thì bà con thành viên muốn vào diễn đàn cũng sẽ rất khổ sở vì số lượng GET theo dạng này có con số kinh khủng. Theo tính toán sơ khởi, tôi ước tính có chừng xấp xỉ trên dưới 1200 SYN request mỗi giây đến HVA server và các cú SYN này hoàn toàn hợp lệ vì nó hồi báo bằng cú ACK rồi tiếp tục dùng ASK-PSH để đẩy cú GET đến web server. Điều đáng nói là hơn một nửa request dạng này hoàn toàn không có "x-flash" header và cấu trúc HTTP header được gởi đến rất đơn giản:
Code:
GET /forum/?&time=0.05536 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Host: quangvinh-vn.net
Connection: Keep-Alive

Có những điều đáng nói một cách tổng quát ở đây là:
1. Giá trị /forum/?&time=x.xxxxx hoàn toàn ngẫn nhiên (random). Tôi cho rằng tính random ở đây có dụng ý để đánh lừa những cơ chế detect dựa trên pattern. Nếu một cơ chế cản lọc quá cụ thể cho từng URI như dạng /forum/?&time=0.05535 thì sẽ trở nên vô ích vì nó chẳng "match" gì cả và chúng có thể tự do đi vào.

2. Giá trị Connection: Keep-alive lần này có tác dụng rõ rệt vì nó không cần mở nhiều sockets, nó chỉ cần dùng socket đã được mở và cứ thế mà gởi /forum/?&time=x.xxxxx với giá trị x.xxxxx thay đổi ngẫu nhiên. Điểm ảnh hưởng nặng nề đối với firewall của HVA ở chỗ cứ mỗi IP chỉ cần 1 connection (trong 6 connection cho phép) đã đủ để liên tục gởi GET request. Giới hạn 6 connections ở đây trở nên thừa thãi nếu dựa trên nguyên tắc này. Thật tế cả 6 connection cho phép đã được tận dụng triệt để. Bởi thế mới có trên dưới 1200 SYN xảy ra trong 1 giây. Tôi không rõ giá trị "keep-alive" này được "chủ nhân" của chúng ấn định rõ ràng hay vô tình mà gán cho chúng. Nếu quả thật đây là một dụng ý cụ thể thì phải nói rằng khả năng cân nhắc và chuẩn bị cho việc tấn công HVA lần này khác rất xa những lần trước.

3. Các cú GET này không mang "x-flash" header cho nên nó qua khỏi snort và mod_security dễ dàng. Tôi không rõ là chúng có bị một proxy server nào đứng trước "lột" mất cái header hay không vì không có gì chứng mình điều này. Tuy nhiên, chuyện này rất có thể có vì việc thực hiện "anonymize" -54- của proxy nào đó có thể "lột" các header đến mức độ không còn dấu tích gì (ngay cả dấu tích của chính proxy server thực hiện chuyện "lột").

4. Song song với các cú GET với URI "ngẫu nhiên" như trên, hàng loạt các cú GET đến cái banner swf cũng đồng thời xảy ra và chỉ có GET cái banner ấy mà thôi. Theo tôi, đây là đợt tấn công tổng hợp, liên hoàn, cố tình làm tê liệt mọi tài nguyên của máy chủ HVA: GET HVA banner để tạo load trên bình diện static image và chiếm socket, GET URI "ngẫu nhiên" để tạo load trên máy chủ trên bình diện tác động đến database.

Đối với một shared hosting server bình thường nào đó, chỉ cần 1/3 khối lượng "cơn lũ" này cũng đủ đưa server ấy đi nghỉ mát nếu cơ chế phòng thủ server này không chặt chẽ. Có lẽ bạn vẫn còn thắc mắc tại sao 4 điểm trên lại kinh khủng đến như vậy? Tôi sẽ cố gắng giải thích trong giới hạn cho phép như sau:

1. ảnh hưởng của URI ngẫu nhiên:
Một request ở dạng /forum/?&time=0.05536 sẽ đi qua ba giai đoạn:
- qua FW: passed - bởi vì nó hoàn toàn hợp lệ
- qua snort: passed - bởi vì nó không match cái gì cả
- qua mod_security: passed - bởi vì nó không match gì cả luôn

Khi lên đến tầng web server, có mấy chuyện xảy ra:
- trước tiên web server vui vẻ tiếp nhận vì nó nhận thấy cú request này chẳng có gì sai cả, có lẽ request ở dạng thuộc phần hành php lo. Bởi thế, web server nhận lấy và chuyển nó đến php.
- php được giao cho request từ web server, nó bèn tiếp nhận. Để hoàn tất request này, nó bèn liên hệ database để xem cú GET này nên dùng "skin" nào để hiển thị.
- khi nhận ra là cú request này chẳng ăn nhập vào đâu, nó bèn tạo ra một trang mặc định với tài khoản guest rồi trả lại cho web server.
- bước kế tiếp, web server trả về kết quả cho trình duyệt nào gởi request, đồng thời tường trình access status 200 trong web log, cộng thêm dăm ba cái error 404 nếu như có vài cái gif nào đó không tồn tại (khi dùng một trang mặc định). Một cú GET như thế đi vào sẽ lưu lại trong log của web server như sau:
Code:
xxx.xxx.xxx.xxx - - [02/Nov/2004:06:26:32 -0500] "GET /forum/?&time=0.13435 HTTP/1.0" 200 12933 "-" "Mozilla/4.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7)"

Bạn có thể thấy:
* status 200 trong dòng log ở trên biểu thị web server đã tiếp nhận cú GET.
* biểu thị "-" đứng trước "Mozilla/4.0" cho thấy, đối với web server, cú request này đi trực tiếp từ bên ngoài mà chẳng hề được "refer" từ link của diễn đàn HVA cả.

Kết cục, một GET ngẫu nhiên hoàn toàn thành công trên phương diện tạo load cho máy chủ trên mọi tầng.

Hạn chế rõ rệt của URI ngẫu nhiên này chính là giá trị bất biến đứng trước dấu =. Đối với snort, detect giá trị này khá đơn giản, ở dạng HEX nó có giá trị: 2F 3F 26 74 69 6D 65 và nó thuộc vị trí offset 0040 - 0050 trong gói HTTP chứa cú GET này. Đối với mod_security, một regex (xem chú thích 42) có thể dễ dàng bắt và cản nó trước khi nó có thể đi sâu vào bên trong. Điều cần nêu lên ở đây là sáng kiến tạo ra giá trị ngẫu nhiên cho URI của "tác giả" của các cú GET nhằm phần nào gây khó khăn trong việc cản trở chúng. Nếu web admin chỉ dựa trên web log mà đánh giá sự thể thì sẽ khó lòng nắm bắt vấn đề.

2. ảnh hưởng của giá trị connection: keep-alive:
Giá trị keep-alive có tác dụng trực tiếp hỗ trợ những gì xảy ra ở phần 1 ở trên. Cứ mỗi cú truy cập thành công và dựa vào đòi hỏi "keep-alive" này, nó nắm giữ socket và liên tiếp gởi hết cú GET này đến cú GET khác xuyên qua một ESTABLISHED connection. Bởi lẽ có nhiều cú gởi từ một IP (IP của proxy server nào đó chẳng hạn) đến quá dồn dập, nên không hề có khoảng thời gian gián đoạn, bởi thế "keep-alive" hoàn toàn bền bỉ trong trường hợp này. Từ máy con, trình duyệt không cần phải tạo thêm connection mà vẫn đều đặn đẩy GET đến HVA server. Nếu mỗi connection có khả năng "keep-alive" và liên tục gởi hàng trăm cú GET thì giới hạn 6 connections sẽ cho phép chúng gởi hàng ngàn cú GET nếu mức độ bền bỉ quả thật... bền bỉ (xem chú thích 51). May thay, đường dẫn từ các gateway của các cú GET kia đến HVA server không ở tình trạng tuyệt hảo. Có những cú GET gởi đến, dẫu có ấn định "keep-alive", chúng vẫn bị gián đoạn vì bị nghẽn mạng ở đâu đó. Thời gian gián đoạn này dài hơn thời gian ấn định để "keep-alive" nên chúng phải tạo ra connection mới để tiếp tục đi vào HVA web server và mỗi lần gián đoạn xảy ra, dường như sự gián đoạn này tạo nên ảnh hưởng dây chuyền. Các cú GET khác đang nối đuôi đi vào cũng bị chậm lại và có những trường hợp hoàn toàn bị tan biến (dựa theo thông tin từ các tcp stream lấy được qua tcpdump). Mỗi khi phương tiện "keep-alive" này gián đoạn, chúng lại bị rơi vào vòng quản chế của firewall connection limit vì phải tạo socket mới.

Giả sử các cú GET trên không ấn định giá trị "keep-alive" và đặc biệt HVA web server không hỗ trợ tính chất "keep-alive" thì sao? Thì mỗi cú GET đi vào đều phải được tạo một socket riêng cho nó. Với giới hạn 6 connection limit, mỗi IP dùng để gởi cú HTTP GET này chỉ có thể gởi tối đa 6 cú GET trong bất cứ lúc nào. Tính chất "keep-alive" được hỗ trợ trên web server của HVA trong lúc này không ngoài lý do cải thiện vận tốc truy cập cho người dùng, mỗi cú "bấm" trên trình duyệt sẽ cho phép họ tải về trọn bộ một trang của HVA xuyên qua một socket đã được hình thành. Vì lý do "cải thiện" cho người dùng hợp lệ mà HVA web server phải rơi vào tình trạng "è lưng ra chịu đấm" của cơn DoS.

Hạn chế của ấn định "keep-alive" này ở đâu? Hiển nhiên là phụ thuộc vào sự hỗ trợ của web server. Để giới hạn nhiều cú GET đi xuyên qua một ESTABLISHED connection, "keep-alive" trên web server của HVA phải hoàn toàn tắt bỏ. Chỉ với cách này mới có thể "ép" và điều tác đúng theo quy chế connection limit từ firewall.

3. ảnh hưởng HTTP header không có "x-flash":
Bởi các cú GET ngẫu nhiên này hoàn toàn không có dấu hiệu gì thuộc về "x-flash" (tôi vẫn nghi ngờ đây là chuyện vô tình các x-flash bị proxy server nào đó anonymize), mọi cơ chế cản lọc của HVA hoàn toàn mở ngỏ cho chúng vào. Cái này cũng dễ hiểu vì chúng hoàn toàn hợp lệ trên bình diện giao thức. Điểm ảnh hưởng thứ 3 này hoàn toàn tương thích với hai ảnh hưởng trên. Tôi không thể tìm ra được một bằng cớ nào chứng tỏ các cú GET ở dạng không có "x-flash" header đi vào là cố tình không có header này hay vô ý bị proxy server nào đó "lột" mất. Ngay cả việc truy ngược lại IP gởi cú GET này cũng chỉ có thể tiết lộ các hops nó đã đi xuyên qua và thông tin thu lượm được quá mơ hồ để có thể xác định rõ ràng là nó được tạo ra một cách có chủ định hay không. Cho dù tôi có thể xác định được đường đi đến HVA server đã phải qua ít nhất là một proxy server nhưng để xác định nó có chức năng "anonymize" hay không thì không thể được. Dù gì đi chăng nữa, gần một nửa số lượng GET đi vào với URI ngẫu nhiên hoàn toàn không mang "x-flash" header và hiển nhiên các cơ chế cản trở hiện có trên HVA server không có tác dụng bao nhiêu và hiển nhiên chúng đã đóng góp không ít đến việc làm cho HVA server đứ đừ.

Nói về mặt hạn chế thì các cú GET không có "x-flash" header này ngay trước khi điều chỉnh lại firewall, snort, mod_security và một số cơ chế khác thì chúng không bị hạn chế gì cả. Những cú request này tương tự như các cú request "vô tội" đến từ trình duyệt của người dùng bình thường và mang theo thông tin sai sót trên thanh địa chỉ. Theo đúng nguyên tắc, web server phải tiếp nhận và thông báo đến trình duyệt nếu nó không thoả mãn được request (tường trình một error status nào đó). Kiện toàn được "cơn lũ" này ở hai điểm 1 và 2 ở trên tự nhiên sẽ khắc phục được ảnh hưởng thứ 3 này.

4. ảnh hưởng các cú GET đến HVA banner:
Tôi cho rằng các cú GET đến HVA banner (swf file) khá vô ích trong trường hợp này. Ấn định "keep-alive" này chỉ tạo một socket để lấy swf file và hiển nhiên proxy server nào đứng trước client gởi GET request này sẽ tự động dùng bản có trong cache để cung cấp cho client. Đối với HVA server, số lượng sockets được tạo ra cho cú GET này tạo ảnh hưởng "chen lấn" đến các cú GET với URI ngẫu nhiên ở trên chớ không mang lại một tác dụng gì rõ rệt. Thực tế, chúng còn tạo ảnh hưởng đối nghịch với các cú GET với URI ngẫu nhiên vì chúng làm giảm cơ hội mở thêm socket của các cú GET với URI ngẫu nhiên. Đặc biệt khi phương tiện "keep-alive" không thể duy trì vì đường dẫn xấu hoặc bị gián đoạn vì lý do nào đó. Nói về mặt ảnh hưởng thì các cú GET banner chẳng là gì so với các cú GET với URI ngẫu nhiên. Lý do:
- mỗi cú GET lấy static image đối với server chỉ là một cú request đơn giản: client hỏi, server trả lời, hoàn tất là phủi tay. Nếu client hỏi tiếp, server trả lời tiếp và cũng cùng tấm hình static này sẽ tiếp tục đi xuyên qua socket đang có sẵn. Dịch vụ ở dạng này hoàn toàn static và ở giới hạn đơn tầng.
- mỗi cú GET dùng URI ngẫu nhiên kia không ấn định cụ thể nó cần "lấy" cái gì nhưng lại tạo ra ảnh hưởng đa tầng (như đã phân tích ở phần 1 phiá trên).

Sau khi phân tích khá kỹ lưỡng các điểm lợi hại, tôi quyết định hình thành sẵn các "rules" để đối phó. Tiếc thay, một giờ mười lăm phút trên tàu lửa trôi qua nhanh chóng. Tôi đã đến nhà, đành phải xếp laptop lại và tiếp tục sau bữa tối vậy.

Tối 2/11:
Ăn tối xong, tôi hăm hở mở laptop ra. Tôi đang ở đâu nhỉ? À, phần snort signature dang dở. Phần này tôi không mất quá nhiều thời gian, chỉ phải đưa lên HVA server và chạy thử rồi chỉnh ngay tại chỗ thôi. Tuy nhiên tôi cần hoàn tất nó rồi chỉ cần "cut & paste" lên server cho nhanh. Tôi dành thời gian để hình thành vài cái filters cho mod_security vì theo tôi, đây là cửa ngõ tối hậu sau khi các cú GET có URI ngẫu nhiên đã lọt qua khỏi quy định connection limit của firewall. Rất tiếc tôi không thể đưa các filter này vào bài viết vì tính nhạy cảm của nó. Bạn chỉ cần biết tinh thần cản lọc được áp đặt để tạo hiệu năng cao nhất là đủ.

Chưa hoàn tất điều tôi muốn thì... bíp bíp bíp. Đúng là "phước bất trùng lai, hoạ vô đơn chí", tôi nhận được cú gọi khẩn cấp từ sở vì một server quan trọng ngưng hoạt động. Tôi lẩm nhẩm: "sorry hva, work comes first!". Tôi logoff HVA server, logon VPN của sở trong khi trận DoS vẫn tuôn vào ào ạt. Tôi biết chắc "cơn lũ" này không đủ để "giết chết" HVA server nhưng chắc chắn rất có nhiều người đang không thể vào diễn đàn. Tôi phải giải quyết công việc của sở xong rồi mới quay lại.

Hơn ba giờ đồng hồ trôi qua, rốt cuộc tôi cũng đã hoàn tất công việc ở sở, tìm ra, khắc phục được sự cố và đưa máy chủ bị ngưng hoạt động kia trở lại bình thường. Tôi lẩm bẩm: "mẹ khỉ, ngày mai lại mất cả giờ đồng hồ để viết tường trình nữa rồi."

Tôi vội vã log vào HVA server. Chậm quá! Cực kỳ chậm! sau hai lần thử tôi mới có thể log vào được. Console hiển thị các thông tin chậm như thể nó đang chiếu chậm một đoạn phim nền đen chữ trắng. Tôi cảm thấy mệt mỏi lắm, đã quá nửa đêm sau một ngày làm việc dài dằng dặt từ 7 giờ sáng. Tôi quyết định chỉ tắt bỏ ấn định "keep-alive" trên HVA web server để khắc chế điểm đã phân tích trong phần 2 ở trên. Tái khởi động web server mất hơn ba phút vì có quá nhiều processes và connections còn đang hoạt động. Web server phải đợi cho từng connection hoàn tất mới tắt bỏ và khởi tạo mother process / child processes từ đầu.

Cố gắng nán thêm vài phút để xem server log, tôi hài lòng khi thấy tình hình được cải thiện rõ rệt sau khi "keep-alive" không còn tác dụng nữa. Server load xuống thấy rõ và truy cập vào diễn đàn nhanh hơn. Tôi vương vai, ngáp dài rồi logoff khỏi HVA server. Tôi lẩm bẩm: "phải đi ngủ không thì ngày mai dậy không nổi. Có chuyện gì thì ngày mai tính tiếp."

Các bạn có thể theo dõi tiếp phần 10 tại http://hvaonline.net/hvaonline/posts/list/211.html

Chú thích:
-53- tcpdump cho phép sniff và tường trình các gói tin ra vào ở nhiều chế độ. Chế độ tôi đã dùng để bắt lấy các gói tin lần này là dùng snaplen có giá trị bằng 0 (-s0):
# tcpdump -s0 port 80 -w /tmp/dump
Căn bản mà nói, snaplen là số bytes của dữ liệu của mỗi gói tin. Theo mặc định, snaplen có giá trị là 68 bytes (riêng SunOS có giá trị tối thiểu là 96 bytes). Với giá trị mặc định nhỏ bé này, nếu không xác định đúng snaplen thì gói tin được capture sẽ bị "xén" (truncated). Bởi thế, -s0 ấn định sẽ dùng bất cứ giá trị nào thích hợp để bắt lấy trọn gói tin. Chỉ nên dùng chọn lựa này trong trường hợp cần thiết vì hồ sơ "dump" được tạo với chọn lựa này sẽ rất lớn.

-54- anonymize là "vô danh hoá", xem thêm chú thích 52.
Tối 01/11:
Ăn tối xong, sau khi ra một lô toán cho hai thằng nhóc (con trai tôi) để chúng bớt quấy rầy, tôi pha một ấm trà và mở laptop lên.

Lúc này tôi có đủ thời gian để cẩn thận phân tích từng tcp stream -48- khởi tạo từ mỗi IP có chứa thông tin "x-flash-client" để phân tích các biến thái của chúng (nếu có). Hãy xem thử đoạn HTTP header đã được decode từ một chùm HEX thuộc một tcp stream:
Code:
GET /style_images/1/banner.swf HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74
GET /style_images/1/rs_main_table_bottom.gif HTTP/1.1
Accept: */*
Referer: http://quangvinh-vn.net/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74
GET /style_images/1/trans.gif HTTP/1.1
Accept: */*
Referer: http://quangvinh-vn.net/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74
GET /style_images/1/extended_main_table_bottom.gif HTTP/1.1
Accept: */*
Referer: http://quangvinh-vn.net/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74
GET /style_images/1/footer_expand.gif HTTP/1.1
Accept: */*
Referer: http://quangvinh-vn.net/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt; FunWebProducts)
Host: quangvinh-vn.net
X-Forwarded-For: 222.252.188.74
Connection: Keep-Alive
Cache-Control: bypass-client=222.252.188.74
GET /forum/?&time=0.13435 HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; Hotbar4.5.3.0)
Host: quangvinh-vn.net
X-Forwarded-For: 203.210.194.254
Connection: Keep-Alive
Cache-Control: bypass-client=203.210.194.254

Chúng ta có thể thấy được những gì hiển nhiên ở đây? Đúng rồi:
- "x-flash-version"
- GET methods
- Connection: Keep-Alive
- Cache-control: bypass
- cùng GET các static images

Điều tôi phải tự gật gù cũng như nhếch mép cười khi đi xuyên qua đoạn packet dump bé tí tẹo đó là: chủ định của kẻ tấn công. Tôi muốn tập trung phân tích tính chất loại tấn công này trên tầng web service vì chúng ta vừa đi xuyên qua một số phân tích khá sâu ở tầng này trong các bài trước.

So với lần trước (dùng POST), lần này anh chàng đã tính toán kỹ lưỡng hơn, có cân nhắc hơn và nhất là có sáng tạo hơn. Nếu quả thật anh chàng chịu khó đọc RFC để thay đổi dạng tấn công thì đây là điều đáng mừng (và cũng đáng buồn). Đáng mừng vì chính bản thân anh ta thâu gặt được kiến thức về giao thức HTTP sâu sắc hơn, đáng buồn vì anh chàng dùng năng lực và trí thông minh của mình cho một mục đích không lấy làm hữu dụng. Tại sao tôi tự gật gù và nhếch mép cười?

- thứ nhất, suýt nữa tôi bị cái mớ "x-flash" header kia đánh lạc hướng. Trong một chuỗi có vài trăm tcp stream, các stream có header là "x-flash" chỉ chiếm chừng 1/2 tổng số, 1/2 còn lại có y hệt tính chất nhưng không hề có vướng một mảy "x-flash" trong suốt tcp stream. Điều này cho thấy, kẻ tấn công không đơn thuần "nhắm mắt phang đại" đến HVA mà có theo dõi và định hướng rõ ràng. Nói về mặt phòng thủ thì các HTTP header có mang "x-flash" hay không mang HTTP header "x-flash" dù có vuột khỏi snort cũng vẫn bị giới hạn connection limit của firewall kiềm chế tối đa. Các gói tin này khi lên đến application layer và nếu có mang "x-flash" header, khi đụng phải mod_security vẫn bị rụng lả tả. Tuy nhiên, một nửa các tcp stream khác có y hệt tính chất nhưng không mang "x-flash" header cụ thể thì không còn bị snort và mod_security kiềm chế nữa, chỉ có connection limit trên firewall là còn tác dụng. Nếu tôi chủ quan và phiến diện thì đã để vuột một số lượng đáng kể các gói tin không có x-flash header đi vào mà không có biện pháp thích ứng ngay lập tức.

- thứ nhì, POST method được dùng trước đây có cái lợi là nó tạo ảnh hưởng trực tiếp và nặng nề đến web server, nhưng cũng có cái hại là nó quá cồng kềnh vì phải dùng nhiều gói "continuation" để hoàn tất một lượt gởi. Điểm hạn chế lớn nhất của POST payload dài dằng dặc là sự chậm trễ trong việc chuyển tải các gói tin được xẻ nhỏ ra để hoàn tất lượt gởi. Dụng ý dùng GET method hiển nhiên là để khắc phục "cái hại" trên: hoàn tất mỗi cú gởi càng nhanh càng tốt. Bạn có thể thắc mắc "sao vậy?". Theo tôi, đây là một dạng "flood" để chiếm sockets trên máy chủ, nó khác với SYN FLOOD kiểu truyền thống là nó có đủ "bộ lệ" 3-way hand shakes, ACK-PSH để đẩy gói tin đi đến đích thật nhanh và rồi nó kết thúc bằng FIN. Với lối gởi tin này, firewall không thể xếp hạng nó là SYN-FLOOD kiểu truyền thống -49- để cản nó mà phải mở rộng cửa để đón nó vào như một request hoàn toàn hợp lệ.

- thứ ba, nếu anh chàng tấn công này đã quyết định GET static image mà không "kiện toàn" một chi tiết hết sức quan trọng thì cuộc tấn công của anh ta sẽ đổ vỡ: ra lệnh proxy server lấy bản nguyên thuỷ từ HVA server. Lý do rất đơn giản: nếu anh ta gởi 1000 cái GET trong một giây mà không lo đến phương diện cache thì sao? thì proxy server nào đó đứng trước máy con gởi GET request kia sẽ dùng thông tin có sẵn trong cache để trả lời (thay vì đi đến tận HVA server để lấy một loạt .gif, .swf images nguyên thủy). Nếu chuyện này xảy ra thì sao? Thì hiển nhiên là anh ta đang tự DoS cái proxy server mà anh ta dùng. Theo tôi, tấn công theo dạng này mà không có suy tư và phân tích thì cơ hội bị vướng vào lỗi này rất cao.

Tiếc thay (và cũng may thay cho HVA), directive Cache-Control: bypass-client=xxx.xxx.xxx.xxx được dùng ở đây hoàn toàn vô tác dụng với ý định cần phải bypass cache server. Theo RFC của giao thức HTTP -50-, directive cache-control không hề có chọn lựa "bypass-client". Theo tôi, đây là một dạng ứng dụng non-standard (phi tiêu chuẩn) nào đó cho HTTP header option. Nếu quả thật tác giả của cuộc tấn công này muốn "by pass" các proxy server trên đường đi từ máy của anh ta đến HVA server, anh ta phải dùng directive Cache-Control: no-cache đúng theo ứng dụng cho HTTP/1.1 như trong ví dụ trên. Nếu không, các request tiếp theo cũng cùng đòi hỏi bấy nhiêu static images sẽ "bị" proxy server nào đứng giữa máy anh chàng và HVA server cung cấp cho "bản sao" đã được lưu giữ trong cache của proxy server. Có thể kẻ tấn công HVA đã tính sai? có thể anh chàng cũng không hề tính toán? cũng có thể anh chàng còn "cao cờ" hơn một bậc?

Nếu bạn quay ngược lại phần thứ nhì của bài viết này, bạn sẽ thấy directive cache-control hơi khác hơn lúc này ở chỗ nó có ấn định no-cache và đây là điểm quan trọng nếu mục tiêu là để "đẩy" dữ liệu đến máy chủ HVA. Điểm cao cờ hơn một bậc ở đây là anh chàng "mượn tay" (các) proxy server để tạo socket connection trên HVA server. Cho dù proxy server sẽ cung cấp bản "cache" nó có sẵn nhưng theo đúng thuật toán caching thông dụng (common caching algorithm) thì proxy server vẫn phải liên hệ với server nguyên thủy (HVA server trong trường hợp này) để thử so sánh bản đã cache và bản hiện có trên HVA server xem chúng có khác nhau không. Nếu chúng khác nhau, proxy server tải bản mới nhất về, cung cấp bản mới nhất này cho client nào request (máy của tay tấn công HVA trong trường hợp này) và lưu bản mới nhất này trong cache. Vậy "cao cờ" ở đây là sao? là ở chỗ anh chàng chỉ muốn mở socket dồn dập trên HVA server, dữ liệu thật sự sẽ được proxy server cung cấp (từ bản đã cache) và những request đến HVA server xuyên qua proxy server chỉ là các cú connection nhanh gọn. Gởi request từ máy anh chàng đến proxy server "tiện" và "gần" hơn là gởi trực tiếp đến HVA server (xa và chậm hơn). Anh chàng "sai khiến" proxy server đi đoạn đường xa và lo liệu mớ request thật sự. Nếu quả thật đây là dụng ý của kẻ DoS HVA thì tay này đã tính toán và suy nghĩ rất kỹ lưỡng.

- thứ tư, "keep alive" connection -51-. Theo tôi, anh chàng ứng dụng cái "keep alive" này vừa tác dụng, vừa phản tác dụng. Tác dụng ở chỗ nó giữ nguyên connection hiện có và tiếp tục "đẩy" các GET request để tiếp tục "lấy" các static images qua connection này. Làm như thế thì mỗi cú truy cập để hoàn tất chóng vánh vì nó không đợi cho web server mở thêm connection mới để "đẩy" các static images khác đi đến server. Phản tác dụng ở chỗ, vì nó "keep alive" nên rất ít socket được mở thêm. Dụng đích dùng GET như tôi suy đoán ở trên là tạo một dạng FLOOD để chiếm sockets nhưng anh chàng lại "ra lệnh" cho nó "đẩy" 6 cái GET (ở trên) xuyên qua một socket thì còn gì là "chiếm socket"?. Cho nên, mục đích "chiếm socket" này bị vô tình giới hạn một cách đáng kể, nó chỉ còn phụ thuộc và tốc độ và mật độ gởi GET để tạo ảnh hưởng đến HVA server.

- thứ năm, mọi GET request để lấy các static images như gif files, flash file... đều được thiết kế một cách chính xác và tỉ mỉ đường dẫn. Lý do tại sao đường dẫn lại quan trọng đến thế? bởi vì như đã phân tích ở trên, dụng đích của kẻ tấn công là "đẩy" các GET request này đến HVA server càng nhanh càng tốt. Nếu một trong các đường dẫn đến static image bị sai thì sẽ bị web server báo lỗi ngược lại. Mỗi cú "báo lỗi" này là một cú "oánh ngược" lại nguồn gởi và làm chậm cuộc tấn công. Càng bị báo lỗi nhiều, cuộc tấn công càng mất tác dụng và máy con gởi request càng dồn dập sẽ càng bị "flood" ngược lại. Ngoại trừ nguồn IP dùng để gởi đi là các "spoofed IP" thì không kể vì các đợt báo lỗi sẽ đi về các spoofed IP thay vì về IP của máy gởi request nguyên thủy.

Vậy, với năm điểm làm tôi "gật gù" cũng như "nhếch mép" ở trên, điểm nào có vẻ tạo ảnh hưởng lớn nhất đến HVA server? Câu trả lời quá hiển nhiên bạn nhỉ? Đó là các gói tin mang y hệt tính chất các cú GET "x-flash" nhưng lại hoàn toàn không mang "x-flash" header. Có hai giả thuyết được đặt ra:
1) tay tấn công HVA thiết lập một nửa số lượng GET có "x-flash" header và số còn lại không có "x-flash" header.
2) tay tấn công HVA thiết lập 100% số lượng GET có "x-flash" header nhưng một nửa số này khi đi xuyên qua một vài proxy server nào đó, chúng bị "lột" mất cái header (như dạng anonymous proxy -52-).

Dù cố tình hay ngẫu nhiên, những cú GET đi vào và không được nhận diện như các "x-flash" đã tạo một số ảnh hưởng đáng kể đến máy chủ HVA. Hãy thử phân tích các điểm cốt lõi đã tạo ảnh hưởng.

- giả sử có 1000 cú không mang "x-flash" header đi đến HVA server trong một giây. Sẽ có bao nhiêu cú đi lọt vào? Cái này còn tùy vào một yếu tố chính là các cú GET đến HVA server từ 1 hay nhiều IP address khác nhau.

a. Nếu 1000 cú này đi đến từ một IP thì chỉ có 6 cú có thể đi vào theo nguyên tắc connection limit ở trên. Tôi dùng chữ "có thể" ở đây vì có thể ngay lúc các cú GET được gởi đi cũng có vài người nào đó cũng đang truy cập HVA và cũng dùng chung một proxy server nhưng những người này gởi request trước một tí. Nếu vậy, số phận của 994 cú còn lại ra sao? Chúng có thể được retry, chúng có thể bị timeout và bị huỷ, chúng cũng có thể đi vào đến HVA server. Cái này cũng còn phụ thuộc nhiều yếu tố nhưng yếu tố quan trọng nhất là HVA server tiếp nhận bao nhiêu cú retries, bao nhiêu cú được tiếp nhận và chờ phiên mình. Những chi tiết này phải được điều chỉnh ở kernel level trên firewall của HVA và giá trị thế nào thì... không thể công bố được; bạn chỉ cần nắm khái niệm là thế. Hơn nữa, những giá trị này được điều chỉnh theo nguyên tắc random (ngẫu nhiên) nên cũng khó mà xác định được chính xác để công bố.

b. Nếu 1000 cú này đi đến từ nhiều IP thì số lượng GET đi vào được HVA server sẽ gia tăng dựa trên nguyên tắc connection limit theo IP. Cứ cho 1 IP được dùng 6 connections trong một lúc, vậy, nếu anh chàng này dùng 20 cái proxy servers (20 IP addresses) chẳng hạn thì sao?
20 x 6 = 120 connections
nhưng vì các GET request "ấn định" dùng keep-alive nên mỗi tcp stream chỉ dùng một socket. Bởi thế, 120 connections chiếm 120 sockets.

Về phía máy chủ HVA, để có thể bảo hoà (saturate) socket pool của HVA server nếu như máy chủ HVA đã được ấn định mở và tiếp nhận 32000 sockets (chẳng hạn) thì anh chàng "x-flash" sẽ cần bao nhiêu proxy server?
32000 / 6 = 5333 proxy
Cha chả, nếu anh chàng huy động được trên năm ngàn cái proxy server thì HVA bị nguy to. Tuy nhiên, ngược lại máy con tạo ra dạng DoS này cũng không mấy "êm ấm" nếu số lượng request khổng lồ này được gởi đi và số lượng hồi báo quay trở về chính máy tạo request. Tôi tin chắc máy này sẽ "chết" đứ đừ để tiếp nhận hồi báo. Thật sự hiện tượng hồi báo này hoàn toàn hợp lệ và hiển nhiên: cần nhiều request thì nhận nhiều hồi báo. Nếu đây là một dạng tấn công mượn tay người dùng trình duyệt để gởi GET thì chắc chắn nó sẽ làm chậm hàng loạt người dùng vì số lượng hồi báo.

Tôi đưa ra các con số trên chỉ để minh hoạ dạng DoS GET này cần phải có tầm cỡ nào để có thể dung hại đến HVA server. Thực tế con số sockets HVA tiếp nhận là bao nhiêu thì rất tiếc... không thể trình bày được ở đây. Thực tế để có thể huy động trên 5000 proxy server cũng là điều... không tưởng và nhất là phải huy động các proxy server có số hop ngắn nhất để đi đến HVA server. Nếu không, mục đích flood sockets không còn mấy hiệu quả.

Bạn có thể thắc mắc về giải pháp kiềm chế các cú "GET" mới mẻ này. Như đã phân tích, có hai nhóm "GET" khác nhau đi vào HVA server:
- đối với nhóm GET có x-flash header, tôi chỉ "thắt chặt" bằng cách thêm vào vài cái signatures cho snort, tương tự như sau:
Code:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (flags: PA; msg:"GET Null hex - Flash attack HVA - flash"; flow:to_server; content: "|78 2D 66 6C 61 73 68 2D 76 65 72 73 69 6F 6E|"; offset:60; depth:70; classtype:attempted-NullDataGET; resp:rst_all; resp:rst_all; resp:rst_all; react:block;)
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (flags: PA; msg:"GET Null hex - Flash attack HVA - flash"; flow:to_server; content: "|47 45 54|"; content: "|78 2D 66 6C 61 73 68 2D 76 65 72 73 69 6F 6E|"; offset:60; depth:70; classtype:attempted-NullDataGET; resp:rst_all; resp:rst_all; resp:rst_all; react:block;)

Bạn thử "decode" hai signatures trên để xem nó làm cái gì cho nhộn smilie, tôi sẽ không mở rộng thêm về snort signature ở đây.

- đối với nhóm GET không có "x-flash" header, thật ra không cần phải thay đổi gì thêm cũng không ảnh hưởng nặng nề như POST đến HVA server vì các cú GET này chỉ lấy static images và không hề "đụng" mảy may đến database query nên ảnh hưởng đáng kể là ảnh hưởng trên socket. Đối với web server, con số MaxRequestPerChild cần thay đổi để mỗi child process tiếp nhận nhiều request hơn bình thường (xem bài trước). Mục đích là để tránh trường hợp chúng bị hủy quá nhanh (vì có quá nhiều GET request đi vào) vì mỗi lần bị hủy, mother process phải tạo thêm child process và làm gia tăng server load nếu chúng được tạo quá thường xuyên. Đối với kernel socket, các giá trị như max_orphan, syn_back_log, timeout, tcp_mem, keepalive_time.... cần được điều chỉnh để gia tăng cơ hội nhận SYN và giải quyết SYN. Server load sẽ tăng nhưng đây là việc cần thiết để bảo toàn cơ hội truy cập cho người dùng hợp lệ (ở mức tối đa tài nguyên cho phép). Ngoài các thay đổi này, tôi còn có thêm một giải pháp phòng bị nhưng tôi đã không ứng động nó mà chỉ cài sẵn và để yên đó cho nên miễn bàn thêm giải pháp phòng bị này.

Trong 6 cái GET của ví dụ trên có một cái GET rất đặc biệt:
Code:
GET /forum/?&time=0.13435 HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; Hotbar4.5.3.0)
Host: quangvinh-vn.net
X-Forwarded-For: 203.210.194.254
Connection: Keep-Alive
Cache-Control: bypass-client=203.210.194.254

Trong cùng một tcp stream, đột nhiên xuất hiện "anh chàng" này. Nó chẳng GET static images như các cú GET kia mà lại GET một URI rất... kỳ quái: /forum/?&time=0.13435. Cú GET này thuộc một sequence tiếp nối trong cùng tcp stream nhưng nó lại forward cho máy con có IP là 203.210.194.254 và cũng cùng đi qua gateway có IP là 203.160.1.66. Bởi lẽ nó là một sequence thuộc một tcp stream hợp lệ (và được cho phép vào theo quy chế connection limit) nên cú GET này vẫn đụng đến web server. Chuyện hiển nhiên sẽ xảy ra tiếp theo đó là web server của HVA sẽ báo lỗi "không tìm thấy" vì cú GET này trỏ vào một URI không tồn tại. Cũng như các cú GET khác trong cùng tcp stream, cú GET này có dụng đích không gì khác ngoài việc tạo thêm socket trên HVA server.

Đi xuyên qua các tcp stream đang phân tích, tôi chỉ thấy lác đác chừng một tá các cú GET tương tự. Tôi đã không cho những cú GET này quan trọng nhưng đây là lần đầu tiên tôi phán đoán sai kể từ lúc bắt tay vào phân tích các dạng DoS trên HVA. Từ kết quả phán đoán sai, tôi đã không phòng thủ trước. Trong suốt vài ngày kế tiếp, HVA server bị tấn công chỉ với loại GET có URI "/forum/?&time" này. Tôi đã học bài học không bỏ qua bất cứ một chi tiết đáng ngờ nào vậy mà lần này tôi đã sai phạm nguyên tắc căn bản này để rồi vất vả trong mấy ngày tới.

Sự thể ra sao, mời bạn xem tiếp kỳ sau.

Các bạn có thể theo dõi tiếp phần 9 tại http://hvaonline.net/hvaonline/posts/list/209.html

Chú thích:
-48- "tcp stream", bạn hẳn đã nắm được tcp stream là gì. Tuy nhiên, để tránh nhầm lẫn giữa nhiều khái niệm và thuật ngữ trong bài, tôi quyết định đưa thêm chú thích về "tcp stream" ở đây. tcp stream là một "xuất" giao tiếp giữa client và server. Nó bắt đầu bằng SYN request từ client và kết thúc bằng FIN cũng từ client nếu "xuất" giao tiếp này thực hiện đúng quy cách. "Xuất" giao tiếp này có thể chứa nhiều sequences mang các tcp flags khác nhau trong quá trình trao đổi giữa client và server và mỗi sequence từ mỗi phía (client hoặc server) là một "entry" của tcp stream.

-49- SYN FLOOD là một dạng denial of service rất phổ biến từ giữa đến cuối thập niên 90. Cho đến nay, thỉnh thoảng SYN FLOOD vẫn còn xuất hiện rải rác mặc dù các hệ điều hành, routers, firewall ngày nay đã nâng cao để loại trừ dạng DoS cổ điển này. Tổng quát mà nói, dạng SYN FLOOD "truyền thống" lợi dụng tính chất (và cũng có thể là điểm yếu) của giao thức TCP IPv4 để tấn công. Kẻ tấn công gởi hàng loạt SYN request đến máy chủ của nạn nhân nhưng sau khi nhận được SYN-ACK từ máy chủ, nó không bao giờ gởi về gói ACK để hoàn tất 3-way handshake. Điều này làm cho máy chủ không thể tiếp nhận thêm connection sau một khoảng thời gian ngắn vì connection queue của nó bị đầy ứ do chờ đợi gói ACK hồi đáp từ client. Trong trường hợp SYN FLOOD kéo dài, hệ thống sẽ bị cạn tài nguyên (bộ nhớ) vì phải huy động quá nhiều memory cho socket pool và connection queue.

-50- đọc thêm RFC 2068 và RFC 2616 trên website http://www.rfc.org nếu bạn muốn đi sâu vào chi tiết tính năng và tác dụng của các HTTP headers.

-51- Keep-alive connection theo đúng tiêu chuẩn đưa ra trong RFC là một phương tiện để biến tính "stateless" của giao thức HTTP trở nên hiệu ứng hơn. Đúng theo nguyên tắc, mỗi objects được request đến server và được trả về từ server đều cần phải có connection mới. Ví dụ, trên một trang có 10 bức hình gif, thông thường giữa trình duyệt và web server phải tạo ra 10 connection riêng biệt cho mỗi cú GET để lấy hình (vì mỗi bức hình có href (đường dẫn) riêng và đối với trình duyệt, chúng có URI khác nhau). Tuy nhiên, "keep-alive" đòi hỏi server và client giữ nguyên một connection đã hình thành từ đầu để tiếp tục chuyển gởi các gif files đi thay vì phải mở thêm connection mới. Làm thế này giúp giảm thiểu quy đoạn tạo thêm sockets cho các trang web lớn, có nhiều hình ảnh. Làm thế này cũng có cái hại là với một connection đã thiết lập, client có thể request hàng "tấn" dữ liệu và server phải ngoan ngoãn phục vụ không ngừng nghỉ (tương tự như tình trạng dùng teleport hoặc wget để "rút ruột" một trang web), dẫn đến tình trạng quá tải máy chủ nếu quá trình "rút ruột" này tác động trực tiếp đến các dịch vụ xung quanh web service.

Giá trị "keep-alive" nên được cân nhắc kỹ nếu muốn tối ưu hoá web server vì nó là con dao hai lưỡi.
- Nếu bạn cho phép mở nhiều socket trên server (không dùng quy chế connection limit nào đó) thì không nên dùng "keep-alive" vì nó tạo load theo mức cấp số đến server (vì nhiều sockets + nhiều keep-alive).

- Nếu bạn giới hạn sockets trên server (dùng quy chế connection limit nào đó) thì bạn có thể dùng "keep-alive" nhưng phải tính toán giá trị thời gian thích hợp để "keep-alive" tùy theo nội dung và độ lớn (chữ và hình ảnh) của mỗi trang.
Cách tối ưu hoá hay nhất là tính sao cho mỗi trang duyệt chỉ cần một socket và đủ thời gian "keep-alive" để trình duyệt tải về.

-52- Có hai khái niệm về "anonymous proxy":
- một dạng proxy khi client dùng nó để duyệt web sẽ được "lột" bỏ hết các header cá biệt của trình duyệt mà client (có / dùng) gởi đến proxy server. Các gói tin đi xuyên dạng proxy này sẽ không còn một đặc tính cá biệt nào cả ngoài những gì proxy trang bị cho nó.

- một khái niệm khác về anonymous proxy không thuộc tinh thần "anonymous" đang đề cập trong bài viết. Đó là một dạng proxy khi dùng nó không cần phải khai báo tên người dùng và mật khẩu. Loại proxy này tương phản với "user proxy", nó buộc người dùng phải khai báo. Loại "anonymous proxy" và "user proxy" này đều có thể có tính năng "lột bỏ" các header cá biệt của trình duyệt như dạng ở trên.
Sáng 15/10:

Tối qua tôi quá bận rộn nên không có thời gian log vào HVA server xem tình hình ra sao. Sáng nay, phải vào công ty rất sớm nên tôi có chút thời gian xem xét kết quả thâu lượm được đêm hôm trước. Làm một ly cà fê trong khi đợi máy khởi động. Tôi ngồi xuống ghế và bắt đầu log vào HVA server.

Trên console, tôi phóng ngay lệnh đầu tiên:
Code:
# cat /tmp/load | sort -rn | more

Chà, server load lên cao nhất là 7.20 lúc 23:35pm (giờ server), giá trị này nằm sừng sững ngay trên dòng đầu tiên của console sau khi chạy lệnh trên. Điều này có nghĩa từ 23:27pm đến 23:42pm server phải thao tác đến 108 jobs (tính luôn cả dịch vụ web và những dịch vụ khác trên server trong khoảng thời gian 15 phút để lấy giá trị trung bình):
15 phút x 7.20 = 108 jobs

Tôi tiếp tục rà xuyên qua error log của web server.... không có gì đáng ngại ngoài những cảnh báo vặt vãnh như hồ sơ này không tìm thấy, hồ sơ kia không tồn tại.... Ít ra tôi rất an tâm SIGFAULT không còn là mối quan ngại nữa. Web server hoàn toàn phục vụ các request đúng theo dự định và đúng chất lượng.

Tôi hăm hở rà tiếp xuyên qua access log của web server. Tôi thâu thập giá trị access time -44- của vài chục lượt truy cập trong web server log không theo thứ tự nào cả (nhưng trong khoảng 2 giờ bị "dội" nặng nề nhất) để thử tính giá trị trung bình của access time. Điều tôi cần biết ở đây là web server phục vụ request ở mức độ ra sao. Sau vài phút tính toán, tôi tìm được giá trị trung bình cho access time là 3.25s. Chà! đối với tôi, con số nhỏ bé và dường như vô nghĩa kia lại là câu trả lời cụ thể và đầy đủ hơn bất cứ câu trả lời hoặc giải thích nào. Nói cho cùng, người dùng truy cập đến HVA server không cần biết server đang bị sự cố gì. Công tác của người quản lý và bảo trì máy chủ là phải tối ưu hoá khả năng hoạt động ngoài việc kiện toàn tính bảo mật của nó. Nếu nhìn theo phương diện người dùng thì con số 3.25s chỉ là chuyện nhanh chậm. Nhưng nếu nhìn theo phương diện quy trình hoạt động thì con số 3.25s kia bao gồm cả một chuỗi công việc đa tầng trước khi người dùng nhận được thông tin trên trình duyệt của họ. Tôi cho rằng mức độ access này hoàn toàn chấp nhận được nhất là trong khi server bị "đấm" liên miên.

Trở lại vấn đề server load 7.20. Theo tôi ước tính trong bài trước thì trong khoảng 2 giờ cao điểm, server sẽ phải sản xuất ra chừng 47 child processes nếu dùng giá trị MaxRequestsPerChild là 256. Tuy nhiên, theo tính toán ở trên thì có đến 108 jobs xảy ra trong vòng 15 phút cao điểm nhất dựa trên giá trị server load là 7.2. 108 jobs này có thể bao gồm các công việc mother process tạo thêm child processes, mother process hủy child process... và hệ thống điều tác các dịch vụ khác. Với cường độ DoS trong 2 giờ cao điểm thì có lẽ chủ yếu số child process được tạo thêm nhiều hơn là bị huỷ. Lý do: số lượng requests vào liên tục như thế này sẽ khó có thể có một vài child processes đứng yên và bị huỷ -45-. Cứ tạm cho rằng 40% số lượng jobs ở đây dùng cho web service nói chung; như thế ta có thể áng chừng có khoảng:
108 x 40% = 43 jobs dành cho web service.

Và nếu cho rằng các jobs này đều dùng trong việc điều tác child process thì số lượng job này sẽ tương đương với việc tiếp nhận:
256 requests mỗi child process x 43 = 11008 requests (A)

Nên biết rằng con số 43 jobs ở trên chỉ là một giá trị biểu thị nhất thời của khoảng cao điểm. Có thể trong 15 phút cao điểm này có đến vài chục child process được tạo ra vì số lượng request lên quá cao nhưng sau đó lượng request trở nên dung hoà. Ở tình trạng dung hoà này, có thể chỉ có vài child process được tạo ra trong 15 phút kế tiếp.

Tôi cần phải xác thực con số 11008 requests này. Tôi cần biết có bao nhiêu phần trăm con số này đã dành để phục vụ cho người dùng hợp lệ và tôi cũng cần biết nó có tương ứng với những thông tin snort đã bắt giữ ở tầng thấp hơn hay không.

Hãy xem thử trong giờ thứ 21:00 của ngày 14/10, snort đã phát hiện bao nhiêu quả x-flash:
Code:
# grep "10/14-21:" alert | grep "Flash" | wc - l
44945

Thử tiếp cho giờ thứ 22:00 của ngày 14/10:
Code:
# grep "10/14-22:" alert | grep "Flash" | wc - l
56635

Tổng số:
44945 + 56635 = 101580 cú x-flash trong 2 giờ 21:00 và 22:00.

Thật khinh khủng! Nếu dựa trên ước đoán rằng firewall + snort triệt tiêu chừng 65% - 75% các gói "x-flash", cứ cho 65% của 101580 bị triệt từ tầng dưới:
101580 x 65% = 66027 quả

còn lại cho mod_security lo:
101580 - 66027 = 35553 quả

nếu vậy, trung bình trong 15 phút đã có:
(15 phút x 35553) / 120 phút = 4444 quả x-flash (B)

A ha! đã lộ ra con số tôi cần ước tính: nếu sánh (A)(B) thì thấy kết quả rất có lý. Con số 11008 của (A) là tổng số request được chiết tính từ server load một cách rất chủ quan (vì tôi không thể xác định được chính xác bao nhiêu phần trăm của tổng số jobs server đã làm việc dành riêng cho web service). Con số 4444 của (B) là con số các quả x-flash lọt qua khỏi firewall connection limit và snort reset, đi đến web server và bị mod_security "chộp" được.

Như vậy có:
11008 - 4444 = 6564 requests thuộc diện hợp lệ trong 15 phút.

vậy thì có:
( 6564 x 100 ) / 11008 = 59.629 % request thuộc dạng hợp lệ
100% - 59.629 % = 40.371% request thuộc dạng x-flash

Hãy thử xem con số x-flash tổng quát cho cả ngày hôm qua 14/10:
Code:
# grep "10/14" alert | grep "Flash" | wc -l
141423

Hừm... quả thật hôm qua HVA bị DoS ghê gớm hơn vài ngày trước đây nhưng thực tế các "cú đấm" x-flash này chỉ tập trung một khoảng thời gian nào đó. Số còn lại chỉ lẻ tẻ.
141423 - 101580 = 39843.

39843 quả cho 22 giờ còn lại của cả một ngày quả thật không là gì cả. Theo tôi, các con số trên khá xác thực. Bởi vì các snort signatures dùng để phát hiện "x-flash" được điều chỉnh và tối ưu hoá để nó phát hiện "x-flash" trong khoảng thời gian ngắn nhất có thể được, cho nên con số 141423 được tường trình trong alert log không có gì đáng để nghi vấn.

Vậy, nhìn xuyên qua các con số thu thập được, tôi nên vui hay nên... buồn?. Tất nhiên là nên vui vì:
- trước cuộc tấn công, server load chỉ nằm ở mức 0.5 - 1.2
- trong quá trình tấn công và ở giai đoạn cao điểm, server load lên đến 7.20 là mức tối đa
- trong suốt thời gian tấn công, web server đã không tốn quá nhiều thời gian và tài nguyên để tạo thêm child processes
- 4444 requests được web server tiếp nhận (từ socket level lên đến child process level) nhưng lại bị mod_security loại bỏ. Hãy thử mường tượng 4444 requests đều vào được bên trong và database server phải nhận ít nhất là 4444 "query" trong vòng 15 phút thì server load sẽ lên tới con số bao nhiêu?

Tôi đoán chắc bạn đã... mệt nhoài với hàng tràng phép tính ở trên. Rất tiếc tôi phải "lôi" bạn vào cõi tính toán này bởi vì theo tôi, số liệu có giá trị vững vàng hơn bất cứ một cảm giác mang tính "hình như nhanh, hình như chậm, hình như nhiều, hình như ít...". Thật tình mà nói thì tôi đã đi xuyên qua rất nhiều bài tính (nhiều hơn ít nhất là gấp đôi những gì tôi trình bày ở đây, chủ yếu là để thoả mãn tính tò mò của bản thân tôi).

Rồi sau đó........

Ngày 15/10:
Code:
# grep "10/15" alert | grep "Flash" | wc -l
129773


Ngày 16/10:
Code:
# grep "10/16" alert | grep "Flash" | wc -l
78881


Ngày 17/10:
Code:
# grep "10/17" alert | grep "Flash" | wc -l
12134

Có lẽ ngày này thiên hạ ít lên net?

Ngày 18/10:
Code:
# grep "10/18" alert | grep "Flash" | wc -l
33546


Ngày 19/10:
Code:
# grep "10/19" alert | grep "Flash" | wc -l
13179


Ngày 20/10:
Code:
# grep "10/20" alert | grep "Flash" | wc -l
5437

và cứ thế.... thưa dần rồi tắt hẳn.

Cho đến một chiều đẹp trời ngày đầu tháng 11. Tôi nhận được một PM "khẩn" từ JAL:
"Lão có đó không? Hình như server đang bị DoS!

Lúc ấy là lúc tôi đang chuẩn bị rời sở. Tôi gởi ngay cho JAL một PM:
"OK bồ, để tớ dump một mớ packets xem thử có chuyện gì.
Và tôi log vào HVA server, chạy vài phút tcpdump -46- và copy kết quả về laptop của tôi. Trên tàu lửa, tôi hăm hở phóng ngay Ethereal -47-

Bạn đoán xem chuyện gì xảy ra đây? Sự thể ra sao, mời bạn đón xem phần kế tiếp vậy.

Các bạn có thể theo dõi tiếp phần 8 tại http://hvaonline.net/hvaonline/posts/list/182.html

Chú thích:
-44- access time, thời gian một request truy cập đến server tính theo đơn vị giây. Giá trị này không có sẵn theo chế độ mặc định trên các web server. Để có thông tin cần thiết về access time, điều chỉnh log để tường trình thêm thông tin "access time" (hầu hết các web server đòi hỏi điều chỉnh thêm mới có thông tin này).

-45- chế độ điều tác (tạo child process, hủy child process) của web server (mà HVA dùng) dựa trên thuật toán tổng quát như sau:

- nếu mother process nhận thấy số lượng child process dự bị (chờ sẵn) để tiếp nhận request có xu hướng thiếu cho nhu cầu hiện tại, nó tiếp tục tạo thêm child process để sẵn. Ví dụ, cấu hình hoạt động ứng định có ít nhất là 5 child processes bất cứ lúc nào. Ngay khi child process thứ nhất của 5 child process dự bị bắt đầu tiếp nhận request thứ nhất thì mother sẽ tạo ngay thêm một child process mới để duy trì số lượng 5 child process dự bị. Nếu child process thứ nhì trong số 5 child proces cũng bắt đầu tiếp nhận request đầu tiên, mother process sẽ tiếp tục tạo thêm child process theo đúng logic đã định.

- nếu mother process nhận thấy số lượng child process dự bị có xu hướng bị thừa và cũng dựa trên căn bản 5 child process dự bị, nó sẽ lần lượt hủy bớt các child process bị thừa (đứng yên không phục vụ ai cả) cho đến khi số lượng child process dự bị được duy trì theo đúng ấn định.

Logic trên ứng dụng cho việc điều tác số lượng child process phục vụ được thoả đáng và cân bằng. Nó tránh trường hợp bị thiếu child process để phục vụ, nó cũng tránh trường hợp quá dư child process làm hao phí tài nguyên của máy chủ một cách vô ích.

-46- tcmpdump, một công cụ không thể thiếu cho công tác phân tích gói tin. Không có một tài liệu nào liên quan đến security analysis mà không đề cập đến tcpdump. Có thể tải tcpdump về từ http://www.tcpdump.org/

-47- Ethereal, một công cụ phân tích giao thức mạng, một công cụ không thể thiếu được nếu như đã dùng một sniffer để bắt các gói tin ở dạng binary. Có thể tải Ethereal về từ http://www.ethereal.com/
Trưa 14/10:
Đã đến giờ ăn trưa. Gần bốn giờ ròng rã vùi đầu trong đống công việc, tôi hầu như quên bẵng chuyện HVA. Giờ này chắc JAL đã hồi âm. Tôi hâm nóng mớ thức ăn mang theo cho buổi trưa và log vào diễn đàn HVA (vừa ăn vừa táy máy server). Đúng như dự tưởng, tôi nhận được hai thông điệp từ JAL và một mớ thông điệp khác có dạng "giúp em hack yahoo pass". Tôi lầm bầm "suối ngày cứ yahoo pass, yim pass, không biết chán sao trời" và tôi để chúng qua một bên.

Đại khái trong thông điệp JAL "phán" rằng: "lão cần làm gì thì cứ làm". Vậy thì không có vấn đề gì. Tôi thử xem tình hình server lúc này ra sao bằng một số lệnh thông thường sau khi log vào HVA server. Chà, giờ này bên VN mới có 9 giờ sáng mà đã vào diễn đàn khá đông. Đành phải vậy thôi:
Code:
kill -SIGTERM `cat /var/run/httpd.pid` && rm -f /var/run/httpd.pid && rm -f /var/lock/subsys/httpd

Để cho chắc ăn, tôi phóng tiếp:
Code:
ps -ef | grep httpd

Hèm, sạch sẽ đâu đó, không còn một mảnh httpd "vương vấn". Hai lệnh trên có mục đích gì? Lệnh thứ nhất thật ra là một lệnh tổng hợp ba việc khác nhau. Phần thứ nhất của lệnh này dùng lệnh cat để xác định parent pid (process id) của httpd đang chạy trên máy để lệnh kill có thể kết thúc nó với tín hiệu SIGTERM -38-. Phần thứ nhì và thứ ba của lệnh này chỉ đơn giản xoá bỏ giá trị httpd.pid và httpd trên máy để lần sau httpd mới được khởi tạo, nó không bị "bối rối". Lệnh thứ nhì đi theo chỉ đơn giản dùng để xác nhận không còn process nào thuộc httpd đang chạy.

Tôi thử khởi động httpd mới xuyên qua một init script (xem lại chú thích 24) tôi tạo ra, đặc biệt dùng cho httpd mới và các thư viện cũng như hồ sơ cấu hình nó cần dùng. Ôi chao, không khởi động được, nó càm ràm không tìm thấy ba modules. Tôi nghĩ là tôi kỹ lưỡng đến thế mà vẫn sót lại vài cái modules "thừa hưởng" từ hồ sơ cấu hình cũ. Trong nháy mắt, chúng biến khỏi hồ sơ cấu hình. A lê hấp, khởi động lại xem sao.... thông điệp ngắn gọn và "tròn trĩnh":
Code:
HVA webserver is sucessfully started

hiện ra trên màn hình.

Tôi nôn nóng mở thêm hai console đến HVA server nữa, một dùng cho cái "đuôi" tail đến firewall log, một cho cái "đuôi" tail đến webserver error log, một cái nữa cho "đuôi" tail đến webserver access log và cái cuối cùng dùng để chạy lệnh lai rai như top, ps, netstat dùng để theo dõi tình hình chung. Cái màn hình 21 inches gắn thêm vào laptop bị HVA "lấn chiếm" gần hết (may mà tay xếp hơi bị... mù về unix nên hắn không hề để ý xem mấy cái console này là cho việc công hay việc tư những lúc hắn đi ngang qua bàn làm việc của tôi ).

Bạn đoán thử cái "tail" nào tôi đổ dồn ngay cặp mắt vào trước tiên? Đúng rồi, cái "tail" đến web server error log. Tôi mở trình duyệt trên máy của tôi, trỏ đến HVA forum và... nhấn F5 lia lịa. access log ghi nhận truy cập từ trình duyệt của tôi đều đặn và cần mẫn như một ông thư ký già. Trong khi đó, error log hoàn toàn im ắng. Im ắng thế này là tốt lắm. Bạn có thể thắc mắc chỉ có mấy cái "child exit" do segfault mà làm gì quan trọng đến thế?. Sở dĩ tôi chú trọng đến cái log này vì những lỗi thông báo segfault, theo tôi còn nghiêm trọng hơn những cú "x-flash" đang "đấm thùi thụi" vào HVA server.

Hãy thử mở rộng hơn một chút về tính nghiêm trọng ở đây. Trọn bộ quy trình hệ thống nhận một request từ client đến giai đoạn child process bị SEGFAULT tiêu phí rất nhiều tài nguyên của máy chủ nhưng lại bị hủy đi một cách vô lý vì không thể ấn định memory cho nó (share memory trong trường hợp này vì mmap báo lỗi trong lúc debug), đây là chuyện dễ hiểu. Chuyện đáng đề cập hơn nữa là ảnh hưởng phát tán đến trọn bộ dịch vụ của webserver như sau:
- phí tài nguyên dùng để tường trình lỗi liên tục vào error log (gia tăng công tác input / ouput)
- vì dùng php làm công nghệ bên dưới để tải diễn đàn HVA và php không phải là "thread safe" nên buộc web server phải dùng cơ cấu prefork (xem lại chú thích 35). prefork ở đây có nghĩa là khi server khởi động, nó tạo sẵn một số lượng process để xử lý các truy cập đã được socket đón nhận trên cổng HTTP. Mỗi process này chỉ được tiếp nhận một lượng truy cập nào đó rồi bị huỷ (dựa trên giá trị ấn định MaxRequestsPerChild) và process mới lại được tạo ra để tiếp tục phục vụ. Nếu các truy cập đều chất lượng và không hề bị SEGFAULT thì process ấy chỉ bị hủy khi tới giới hạn đã định và nó sẽ... thọ hơn. Nếu có một SEGFAULT xảy ra và không cần biết là process này đã phục vụ bao nhiêu request, nó cũng bị kết liễu, chết non, yểu mệnh... tuỳ cách bạn gọi. Server buộc phải tạo thêm process để tiếp tục phục vụ và đây là "cái chậm sơ bộ".

Vậy "cái chậm chi tiết" là sao? Trên một hệ thống *nix, việc đóng mở các sockets, tạo process, phân bố tài nguyên là do kernel lo và mỗi hoạt động này phải đi theo một nguyên tắc nhất định. Đặc biệt trên Linux và trên kernel series 2.4.x, vấn đề điều tác ưu tiên cho mỗi process tùy tính chất và quy chế dành cho process này -40-. Khi web server đòi hỏi tạo một process, không phải lúc nào đòi hỏi này cũng được thực hiện ngay lập tức. Kernel phải thực hiện mọi yêu cầu theo đúng trình tự không thì hệ thống sẽ biến thành cái ổ nhện. Thời gian và tài nguyên để máy chủ tạo process với nhịp độ như trên chắc chắn sẽ không còn hiệu quả để phục vụ cho clients. Server load sẽ lên cao, số lượng công việc sẽ dồn đống, tài nguyên dần dần sẽ cạn kiệt và đến một lúc nào đó, không những dịch vụ chết mà cả máy chủ cũng sẽ chết vì quá tải.

Sở dĩ người dùng truy cập HVA server thường xuyên cảm thấy chậm là vì một phần bị những quả "x-flash" kia chen chân, một phần request của họ bị mất tăm theo những cái SEGFAULT. Trong những trường hợp này, trình duyệt lại phải gởi request (retry) và nếu không may thì request lần này cũng có số phận không khác gì lần trước. Nếu tầng IP đã giới hạn mức truy cập và tầng application lại bị SEGFAULT thì cơ hội người dùng hợp lệ truy cập đến HVA ở tình trạng thành công lại càng giảm sút. Lý do: mức giới hạn ở tầng IP dùng để giảm thiểu tầng số xâm nhập của "x-flash" (để bảo tồn tài nguyên cho máy chủ) trực tiếp giảm thiểu tầng số truy cập của người dùng hợp lệ. Bạn có thể hình dung trường hợp một vận động trường mở toang hai cánh cổng cho 100 người vào cùng một lúc gồm cả "người ngay, kẻ gian" và làm như thế thì số lượng người tràn vào nhanh nhưng lại khó kiểm soát. Nếu đóng bớt một cánh cổng thì chỉ còn có 50 người có thể vào cùng một lúc và làm như thế thì dễ kiểm soát hơn nhưng cũng làm ảnh hưởng đến những "người ngay".

Cho đến lúc này, sau gần 30 phút theo dõi sát tình hình các truy cập xảy ra trên máy, trên logs, trên socket status... tôi có thể xác định rằng segfault đã hoàn toàn được loại trừ. Bởi php không "thread-safe" nên mỗi request đi vào, web server phải tạo một process hẳn hòi để phục vụ. Tôi điều chỉnh cho web server khởi tạo sẵn 50 processes để chờ tiếp nhận requests. Lúc này số lượng truy cập đến HVA forum bắt đầu gia tăng (giờ này đã gần 10 giờ sáng giờ VN). Dựa trên số lượng access từ access log của web server, tôi ước chừng cứ mỗi 20 giây có một request đến server. Tôi cho phép 256 "MaxRequestsPerChild", như vậy phải sau 85 phút thì một child process mới bị huỷ. 50 child processes đứng chờ sẵn kia với tình hình này thì quá dư nhưng liệu có đủ đáp ứng trong khoản thời gian cao điểm vào ban đêm? Như đã giải thích ở trên về quy chế tạo process, một request đi vào nếu không có sẵn process để phục vụ ngay thì khả năng trình duyệt tiếp tục gởi request đến (vì bị timeout). Vậy trong hoàn cảnh web server cực kỳ bận rộn vào ban đêm thì cần bao nhiêu process nằm sẵn để "nhận công tác" là thích hợp?

Tôi nhẩm tính trong đầu, vào khoảng thời gian 2 giờ cao điểm ban đêm sẽ có khoảng 12000 x-flash requests như đã phân tích ở bài đầu:
(12000 requests / 120 phút) / 60 giây = 1.6 request mỗi giây

Trong 2 giờ, web server sẽ tiếp nhận requests và tạo ra bao nhiêu processes? Thử xem:
- 1 process được tiếp nhận 256 request rồi bị huỷ
- 12000 requests trong 120 phút (7200 giây) = 1.6 requests cho mỗi giây.
12000 requests / 256 max request per child process = 47 processes

Thử ước tính server load sẽ là bao nhiêu nếu nó phải tạo 47 processes trong 2 giờ?
( 15 phút x 47 processes ) / 120 = 5.8 processes
5.8 / 15 = 0.38
(xem thêm chú thích 43)

Con số process quá lớn nhưng nếu tính tra mức server load trung bình ở mức 0.86 thì nó lại ở mức bình thường. Hơn nữa con số process trên cũng không đáng ngạc nhiên vì số request đến HVA server quá cao do x-flash và những dạng tấn công khác. Ở bước này, điều tôi cần kiến tạo là bảo đảm HVA webserver không bị chậm vì liên tục có quá nhiều request đi vào khiến nó không kịp thời tạo process để phục vụ và sẽ đi đến tình trạng giảm sút hiệu xuất. Điều kế tiếp tôi cần kiến tạo là nắm chắc web service và các modules không bị memory leak. Thật ra, dựa trên logic đã được thiết lập sẵn, web service có khả năng tự điều tác việc tắt bỏ và tái tạo các process hết sức nhịp nhàng và quân bình. Tuy nhiên, đối với một site đang bị DoS nặng nề như HVA thì giá trị mặc định không còn thích hợp nữa. Tôi không muốn server phải bị "chết" vì quá tải, tôi cũng chẳng muốn người dùng hợp lệ phải "khổ sở" với vấn đề truy cập. Nếu tôi có một chuỗi 10 máy chủ (chẳng hạn) thì sự thể đã khác, nhưng tôi phải máy mó trong giới hạn cho phép. Tôi tin rằng các con số này sẽ phải điều chỉnh nhiều lần cho đến khi chúng mang giá trị thích hợp nhất cho HVA server.

Đến đây, tôi hy vọng bạn đã nhận ra được một điểm quan trọng sau khi theo dõi diễn tiến từ đầu câu chuyện đến giai đoạn này: "đỡ" các cú DoS không chỉ ở socket level mà còn phải tối ưu hoá dịch vụ ở mức cao nhất có thể được. Cản lọc ở socket level là phương pháp giảm thiểu biên độ và trường độ của các truy cập đến máy chủ với mục đích bảo tồn tài nguyên và hoạt động của nó. Tuy nhiên, việc nâng cao khả năng phục vụ của chính dịch vụ mình muốn bảo vệ cần được quan tâm không kém gì việc cản lọc. Mối tương quan và sự bình quân của hai vấn đề trên chính là chìa khoá của sự bền bỉ và hiệu xuất của máy chủ.

Bước kế tiếp trong giai đoạn điều chỉnh và kiện toàn web service là bước ứng dụng một bộ phận cản lọc trên tầng ứng dụng (application layer). Hẳn bạn đã nghe đến cái tên mod_security -41-, một module được dùng rộng rãi cho một số web server. Bạn có thể hỏi nhưng mod_security đâu phải là một mod chuyên chống DoS, tại sao lại dùng để chống DoS?. Câu trả lời rất đơn giản: nó dùng để cản cụ thể những gì firewall ở tầng IP không thể cản hết được.

Các cơ chế cản lọc đã được ứng dụng trên HVA server cho đến giai đoạn này là những cản lọc nặng tính hiệu xuất bởi vì chúng loại bỏ những gói tin vi phạm một cách âm thầm, tầng dịch vụ web server không hề biết đến và cũng không cần biết đến. Tuy các cơ chế này có tính hiệu xuất cao nhưng những ứng dụng cản lọc tầng thấp (đã nêu trên) không thể hoàn toàn loại bỏ những gói tin vi phạm đi vào. Dựa trên các thông tin thu thập được từ các log files, cơ chế cản ở IP layer cho đến lúc này có hiệu năng chừng 65-75% (tính theo kiểu khách quan). Vậy có khoảng 30% các gói tin tấn công vẫn có cơ hội đi vào và tiêu phí tài nguyên của máy chủ.

mod_security được chọn làm tấm "bình phong" để cản lọc phần còn lại của các gói tin vi phạm này. Ở đây tôi không tiện giới thiệu cụ thể các filtering rules đã được dùng cho mod_security nhưng điều tổng quát tôi có thể giới thiệu với bạn là mod_security có khả năng kiểm soát các request đến HTTP dựa trên phương pháp regex -42-. Nó có thể bắt gặp và cản trở những request vi phạm trong một biên độ khá rộng và linh động. Biết rằng những công cụ dùng để lọc và cản trở gói tin ở application layers đòi hỏi nhiều tài nguyên của máy chủ nhưng trong trường hợp này:
- mod_security chỉ đảm đương 30% các gói tin vi phạm còn lại
- ước lượng tài nguyên dành cho mod_security để xử lý 30% các gói tin vi phạm này ít hơn rất nhiều số lượng tài nguyên web server và database server phải phục vụ nếu cứ để các gói tin mặc nhiên đi vào.
- mod_security còn loại bỏ hàng loạt các dạng tấn công mang tính nguy hại khác đến web services.

Bởi lẽ mod_security làm "tấm bình phong" cho web service, mọi requests trước khi đi vào tới web service đều bị mod_security chặn lại và xét duyệt. Bước này làm gia tăng thời gian đáp ứng request cho người dùng hợp lệ. Đây là cái giá phải trả để bảo tồn cho tài nguyên và sự an toàn của máy chủ. Tuy nhiên, "chậm" hơn một chút ở bước này hoàn toàn có thể chấp nhận được vì nếu không có nó bảo vệ, hàng loạt requests vào được bên trong web service rồi tiếp tục đụng đến csdl và những thứ nhì nhằng bên trong thì cái chậm ở mức này khó có thể đo lường được nếu máy chủ đang bị tấn công. Sau một khoảng thời gian nào đó, người dùng sẽ không những thấy chậm mà còn có thể đi đến tình trạng không thể truy cập được máy chủ nữa vì nó quá bận rộn.

Mọi chuyện xem như tạm ổn, tôi quyết định tái khởi động web server và để bảo đảm dịch vụ web này ứng hiệu với những điều tôi vừa áp đặt, tôi không dùng graceful restarting mà ép buộc nó hoàn toàn ngưng hoạt động, tắt bỏ trọn bộ các process và khởi động lại từ đầu. Tôi gởi JAL một PM thông báo tình hình. Nhìn đồng hồ, tôi biết hôm nay mình không còn bao nhiêu thời gian để táy máy với HVA server nữa. Điều tôi muốn tìm hiểu nhưng không có thời gian theo dõi là tổng số server load -43- trước, sau và trong khi HVA "bị" tấn công sau khi đã trang bị tất cả những cơ chế thắt chặt từ lúc khởi đầu cho đến bây giờ. Thế nên tôi "whip" ra một đoạn shell script như sau:
Code:
#!/bin/bash
# 60 sec x 180 min
i=10800
while [ ${i} -gt 0 ]; do
w | grep load | awk '{print$1, $10, $11, $12}' >> /tmp/load
sleep 120
let i=$i-120
done

rồi thêm đoạn script này vào cronjob của server để nó chạy từ lúc 7 giờ tối trở đi. Hy vọng sáng hôm sau khi tôi vào server sẽ có sẵn một hồ sơ có tên là load nằm chễm chệ trong /tmp chờ tôi xem xét. Tôi sẽ dùng thông tin trong hồ sơ này để "vẽ" một cái biểu đồ để xem lúc cao điểm vào ban đêm, server load sẽ lên tới bao nhiêu. Tôi cũng muốn xem mức gia tăng của server load có tính chất thế nào (gia tăng đột biến hay gia tăng leo thang...). Từ đó sẽ hình thành các bước thắt chặt và tối ưu khác nếu có thể được. À, bạn thắc mắc đoạn script ở trên làm gì? . Nó làm một chuyện hết sức đơn giản như sau: cứ trước khi script nó ngủ một giấc 120 giây, nó bèn:
- chạy lệnh w (để lấy thông tin server load)
- thông tin này được awk tuyển lọc chỉ lấy cột số 1, 10, 11 và 12
- sau khi lấy được thông tin này, nó bèn chép vào dòng kế tiếp trong hồ sơ load trong thư mục /tmp
- trừ bớt trên bộ đếm i giá trị thời gian mỗi lần nó ngủ 120 giây.
- nó lặp lại y hệt các bước 90 lần trong 3 giờ đồng hồ rồi tự... kết liễu (vì đã hoàn tất vòng lặp).

Tôi lẩm nhẩm "để xem sự thể ra sao!"

Các bạn có thể theo dõi tiếp phần 7 tại http://hvaonline.net/hvaonline/posts/list/181.html

Chú thích:

-38- Tín hiệu gởi đi để xử lý process bằng lệnh kill. Tùy ứng dụng của mỗi *nix flavour. Trên linux nói chung, để biết các tín hiệu có thể dùng được thử lệnh kill -l. Mỗi tín hiệu (signal) này được gởi đi sẽ được hàm signal() của hệ thống điều tác mà xử lý. Xem thêm man kill và các tài liệu liên quan (được đề cập đến trong phần cuối của kill manual).

-39- memory leak, tình trạng rò rỉ bộ nhớ nói theo kiểu nôm na. Tình trạng memory sau khi đã dùng xong không thể lấy lại được để tái dụng cho những hoạt động khác trên hệ thống nói theo kiểu kỹ thuật hơn một chút. Memory được dùng như chỗ chứa thông tin để một chương trình nào đó hoạt động. Có những thông tin chỉ cần chỗ chứa tạm thời và ngắn hạn. Sau khi đã tính toán xong và đã xử dụng xong giá trị tính toán, "chỗ chứa" này không được cần nữa, nội dung trong "chỗ chứa" được xoá bỏ và "chỗ chứa" này được trưng dụng cho những việc khác. Memory leak là tình trạng "chỗ chứa" không còn được dùng nữa nhưng không thể xoá để trưng dụng cho việc khác, nhu liệu bị memory leak cứ tiếp tục đòi thêm "chỗ chứa" nhưng không hề trả lại những "chỗ chứa" cũ không còn cần tới.

-40- process policy hay là quy chế điều tác process. Linux điều tác process dựa trên căn bản "time slice", có nghĩa là các process được đưa vào "queue" (sắp hàng) và tuần tự được đưa vào tình trạng "runable" (có thể được chạy), mỗi process sẽ được cơ hội vào chế độ "runnable". Tình trạng runnable này được "scheduler" (người sắp xếp thứ tự) sắp xếp và quyết định, nó xét mọi process nằm trong queue hiện có và quyết định process nào đáng được ưu tiên nhất thì process này có ưu tiên cao nhất. Thông thường khi một hệ thống có nhiều process (xem như) có cùng ưu tiên như nhau thì process nào đứng đầu trong running queue thường được chọn để chạy. Tuy nhiên, trong khi một processs đang chạy, ưu tiên của các process còn lại trong queue có thể lại được thay đổi tuỳ theo tình hình lúc ấy và rốt cuộc mọi process đều có cơ hội để chạy (còn được biết với thuật ngữ "round-robin"), chỉ có chờ lâu hay không mà thôi.

-41- mod_security ở http://www.modsecurity.org. mod_security là một nhu liệu open source do Ivan Ristic viết. Nó có tính năng gần giống như tổng hợp của một intrusion detection system và một application layer firewall. Dù không đa năng nhưng những nhu liệu chuyên về cản lọc hay phát hiện nhưng mod_security là một nhu liệu tuyệt vời để hỗ trợ thêm vào những cơ chế bảo vệ hiện có trên hệ thống. mod_security làm việc như một tấm bình phong, cản lọc mọi request trước khi thật sự đi vào web server.

-42- regex hay regular expression. Đối với những ai có nhu cầu phải tiếp cận với những vấn đề cần phải dùng "pattern matching" thì regex không có gì là mới mẻ. Tuy nhiên, đối với những ai chưa từng có cơ hội hay nhu cầu phải dùng đến regex thì tôi muốn giới thiệu nó đến bạn như một phương tiện hết sức cần thiết và quan trọng cho phương diện phân tích và ứng dụng bảo mật. Bạn muốn thu thập những thông tin hữu ích nhất và quan trọng nhất theo ý muốn từ hàng "tấn" log files? Đọc thêm về regex, một trang tutorial rất hay ở: http://www.regular-expressions.info/tutorial.html

-43- server load là giá trị trung bình của số lượng công việc đi xuyên qua "job queue" được xử lý trong khoảng 1 phút, 5 phút và 15 phút. Ví dụ, server load có giá trị là 0.5 1.0 0.8 có nghĩa là:
- trong 1 phút có: 0.5 job / 1 phút = 0.5
- trong 5 phút có: 5 jobs / 5 phút = 1.0
- trong 15 phút có: 12 jobs / 15 phút = 0.8
Đây là các con số rất bình thường cho một máy chủ không bận rộn.
Tối 13/10
Tối nay thứ Tư, ngày giữa tuần nên tôi không có cái tiện nghi thời gian để ngồi tẩn mẩn với mấy cái logs hàng giờ đồng hồ. Tuy nhiên, tôi có đủ thời gian để tải về dăm ba đoạn log để kiểm nghiệm ứng dụng dùng snort để "phá" cái state của connection. Tôi log vào HVA server và chạy một đoạn lệnh dùng để lấy chỉ một đoạn log từ khoảng 7 giờ tối đến 9 giờ tối của firewall và web server log. Chà, chỉ có hai giờ đồng hồ mà đoạn log cho firewall hơn 2Mb và đoạn log cho web server hơn 5Mb (?), nhất định phải có rất nhiều thông tin trong này.

Thật là khủng khiếp khi rà xuyên qua đoạn log trên. Ấn tượng xem nhẹ những mảnh "x-flash" bé nhỏ từ từ nhường chỗ cho sự khiếp đảm khi tôi mục kích số lượng gói tin truy cập mang tính vi phạm mà firewall đã ghi nhận và cản trở. Lúc đầu tôi rất ngỡ ngàng và hơi nghi ngờ với kết quả trên. Tôi mở firewall rule ra xem xét lại một lần nữa thật kỹ, phân tích từ dòng trong mỗi function. Tôi cảm thấy an tâm khi các giá trị ứng dụng trong firewall rule đều đúng cả. Không nghi ngờ gì nữa, đúng là firewall đã thực hiện chính xác những gì nó được ấn định. Ấn định giới hạn connection ứng hiệu, ấn định loại trừ invalid packets (do bị snort reset) cũng ứng hiệu. Tôi vẫn thấy các thông tin trong web server log tường trình rải rác cách mảnh "x-flash" vẫn đi đến web server với status 200 -27-. Tôi ngồi yên ngẫm nghĩ và duyệt qua trong đầu từng bộ phận của trọn bộ cơ chế cản lọc đã được hình thành cho đến lúc này. Nói về mặt số liệu thì tôi cảm thấy hài lòng vì các biện pháp rõ ràng có tác dụng, nhưng nói về mặt hiệu xuất tối đa của server cũng như những ảnh hưởng phụ đến người dùng hợp lệ thì tôi không thoả mãn. Điều này cũng dễ hiểu vì có hai chuyện vẫn xảy ra:

- trung bình cứ 4 cú "x-flash" đi vào thì 3 cú bị cản, 1 cú lọt vào trong. 1 cú lọt vào này chiếm một phần tài nguyên của máy chủ một cách vô ích vì máy chủ vẫn phải giải quyết yêu cầu của "x-flash" này mặc dù chính người gởi cú "x-flash" có lẽ cũng chẳng biết anh ta (hay cô ta) đã gởi nó đi.

- và để cản các cú "x-flash" tai quái kia, chắc chắn firewall đã ít nhiều ảnh hưởng đến quá trình truy cập của các người dùng hợp pháp. Bởi lẽ, nói về mặt giao thức thì chính các "x-flash" kia cũng hợp pháp không khác gì các đòi hỏi truy cập đi từ IE, Mozilla, Opera...

Trong quá trình dò xuyên qua firewall log, tôi tìm thấy khá nhiều các gói tin vi phạm bị snort "ra lệnh" huỷ bỏ (có còn nhớ đến giá trị resp:rst_all và react:block trong snort signature trước đây không?) nhưng kèm theo đó là một phản ứng phụ có thể khắc phục được nhưng tạo khó chịu khi phát hiện ra nó. Hãy cùng phân tích một cụm log sau:

Oct 13 21:34:48 hvaonline kernel: INVALID_STATE: IN=eth0 OUT= SRC=203.162.3.193 DST=192.168.1.100 LEN=56 TOS=0x00 PREC=0x00 TTL=248 ID=60756 PROTO=ICMP TYPE=11 CODE=0 [SRC=43.244.42.107 DST=203.210.158.196 LEN=44 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=TCP INCOMPLETE [8 bytes] ]

Oct 13 21:34:49 hvaonline kernel: INVALID_STATE: IN=eth0 OUT= SRC=203.162.3.193 DST=192.168.1.100 LEN=56 TOS=0x00 PREC=0x00 TTL=248 ID=61332 PROTO=ICMP TYPE=11 CODE=0 [SRC=43.244.42.107 DST=222.252.33.143 LEN=44 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=TCP INCOMPLETE [8 bytes] ]

Oct 13 21:34:50 hvaonline kernel: INVALID_STATE: IN=eth0 OUT= SRC=203.162.3.193 DST=192.168.1.100 LEN=56 TOS=0x00 PREC=0x00 TTL=248 ID=62105 PROTO=ICMP TYPE=11 CODE=0 [SRC=43.244.42.107 DST=203.210.150.121 LEN=44 TOS=0x00 PREC=0x00 TTL=1 ID=0 DF PROTO=TCP INCOMPLETE [8 bytes] ]

Có chuyện gì đáng nói ở đây? Cả ba thông báo trên xảy ra liên tiếp mỗi giây và đều có cùng tính chất như nhau. Firewall đã cản và thông báo như sau:
- gói tin ICMP loại 11, code 0 -28- đi từ 203.162.3.193 đến private IP 192.168.1.100 của HVA server bị cản với thông báo "INVALID_STATE"
- phụ chú cho thông báo cản ở trên còn có các thông tin trong ngoặc [] cho biết TCP packet gởi từ public IP của HVA server 43.244.42.107 đến 203.210.158.196 có chiều dài 44 bytes, có ưu tiên dịch vụ ở mức bình thường, nhưng TTL chỉ có giá trị là 1.

Chuyện gì đã xảy ra ở đây? một gói tin có chiều dài 44 bytes được gởi từ public IP của HVA server đến 203.210.158.196 để trả lời một request nào đó đến từ IP này, hoặc cũng có thể là gói tin RST để cắt đứt connection giữa IP và HVA server (như snort cần phải làm khi gặp gói tin vi phạm). Tuy nhiên, với giá trị TTL là 1, sau khi gói tin này hoàn thành có 1 hop -29- thì "router" 203.162.3.193 bèn gởi ngược một gói ICMP ngược về IP của HVA để thông báo là gói tin này không tới đích được vì lý do "time exceeded" (ICMP type 11 code 0). Tương tự cho 2 IP còn lại 222.252.33.143203.210.150.121.

Một thông tin lý thú là: IP của "router" 203.162.3.193 là IP thuộc VNPT. Nếu vậy có nghĩa là gói tin đi từ public IP của HVA vừa qua khỏi router của ISP mà HVA dùng (hop 1) là đụng ngay đến router đi vào VNPT (hop 2) và TTL bị chấm dứt? Gói tin đi ra từ public IP của HVA 43.244.42.107 chắc chắn được modem / router của HVA tạo ra vì nó mang public IP nhưng nó lại tự động ấn định giá trị cho gói tin gởi đi có TTL là 1 thì đây quả là điều buồn cười và thú vị. Nếu vậy, hoá ra mọi gói tin gởi đi từ modem / router của HVA dùng đều mang TTL là 1 sao? Có thế nào như vậy được? Nếu quả thật như vậy thì HVA server muốn trả lời request sẽ không bao giờ đi tới đích và lúc nào cũng nhận hàng loạt ICMP dội ngược lại báo "time exceeded"? Thật phi lý vì mọi người vẫn truy cập và vẫn nhận thông tin hồi báo từ HVA server được. Nếu vậy thì chỉ còn có một trường hợp là gói tin được gởi đi từ modem / router của HVA (đương nhiên là phải xuất xứ từ bên trong web server đi ra) có một đặc điểm gì đó khiến cho modem / router "ngang nhiên" ấn định TTL là 1. Rất tiếc là trong tay tôi chỉ có một nhúm các packets được sniff cho "đường vào" HVA server chớ không sniff cả hai đường ra vào nên tôi không tài nào biết được chuyện gì đã xảy ra.

Từ phân tích trên, tôi rút ra được hai điểm lý thú như sau:
- snort hẳn đã gởi RST ngược về các gói tin vi phạm. Tôi chỉ đoán là vậy vì đoạn thông báo ở trên của firewall chỉ trả ngược về 8 bytes thông điệp ICMP và đoạn thông tin gởi đi có chiều dài 44 bytes hoàn toàn biến mất (biểu thị bằng INCOMPLETE) nên không biết rõ gói tin gởi đi mang TCP flag nào. Tôi biết chắc chính firewall không "thèm" trả lời các gói tin vi phạm cho mất thời gian mà nó chỉ lặng lẽ cho vào thùng rác, cho nên, xác suất việc gói tin gởi đi từ HVA server mang RST do snort tạo ra là rất cao.

- gói tin gởi đi này bị rơi vào tình trạng "đánh gió" vì mới qua 1 hop đã kết thúc (hết TTL) , đúng là hoài của.

- cứ mỗi gói RST gởi đi lại có 8 bytes IMCP trở về và hẳn nhiên những gói ICMP này bị firewall của HVA âm thầm cho vào thùng rác vì nó thuộc tình trạng INVALID_STATE nên ảnh hưởng của "phản ứng phụ" này là zero.

Tại sao tôi lại quan tâm đến những chi tiết xem chừng như "vụn vặt" như thế này? Tôi thắc mắc lý do tại sao lại có dạng "phản ứng phụ" kỳ quái như vậy xảy ra? đây có phải là lỗi của modem / router tiếp diện với Internet của HVA hay không? hay đây là một quy định nào đó rất nhỏ trong cơ chế cản "x-flash" gây nên? Những câu hỏi này được đặt ra như một "đề bài" để tôi phải hoàn tất. Thật sự lý do khiến tôi đưa ra vấn đề này vào bài viết là vì một điểm khác, bạn thử nghĩ xem, nếu firewall của HVA không loại trừ các gói tin mang tính INVALID -30- thì chuyện gì xảy ra? Đúng rồi, HVA server sẽ là nạn nhân của chính nó vì những gói tin gởi đi để RST đầu truy cập bên kia được trả ngược lại với 8 bytes ICMP do gói tin mang TTL = 1. Hãy thử hình dung trường hợp HVA server đang bị "dội" liên tục với "x-flash" mà còn bị "dội" thêm với các gói ICMP vô tình kia thì hậu quả sẽ ra sao? Vài ngày sau tôi đã tìm ra câu trả lời cho lý do tại sao có những gói tin gởi đi với TTL = 1 (chỉ để thoả mãn cho sự tò mò của bản thân tôi). Vấn đề được đặt ra ở đây là: thiết kế một mô hình mạng + bảo mật cần có cái nhìn tổng quát với đường đi (ra vào) của thông tin nhưng cần có sự kiểm duyệt tỉ mỉ cho mỗi cơ phận trong quá trình ứng dụng. Một điều chỉnh nho nhỏ trên một cơ phận nào của trọn bộ cơ cấu mạng + bảo mật cũng có thể tạo ảnh hưởng tiêu cực (hoặc tích cực) đến tính hiệu xuất và tính an toàn.

Tôi không có ý định đào sâu hơn với những phân tích giao thức "tầng thấp" vì nó có thể quá "khô khan" đối với bạn nên chúng ta hãy tiếp tục khai triển các ứng dụng tầng cao hơn. Những áp đặt ở tầng "network" và "transport" đã tạm ổn, các cú "đánh gió" của snort vẫn thỉnh thoảng xảy ra và các cú ICMP vẫn thỉnh thoảng đi ngược về, nhưng... who cares? những cái này hoàn toàn vô hại. Tôi tiếp tục khảo sát đến tiêu điểm của các cuộc tấn công: web service. Mấy hôm nay tôi mó đến các "access log" của web server để xem tính chất truy cập nhưng chưa hề đụng đến "error log". Thử xem có thông tin gì hấp dẫn trong error log. Ôi giời... đập ngay vào mắt tôi là hàng chuỗi thông báo "segmentation fault" -31- trong error log. Tôi quá vô ý, lẽ ra đây là nơi cần xem xét ngay từ đầu để nắm tình hình chung trước khi tập trung vào hai tầng "transport" và "network" nhưng dù sao cũng là sự đã rồi. Tôi chỉ thấy sốt ruột vì một nhu liệu báo quá nhiều segfault như vậy chứng tỏ một điều chắn chắn là nó không hoạt động đúng quy cách hoặc có những giềng mối đến những lỗi về lập trình với chính web server và những modules thêm vào.

Tôi mở một cái "đuôi" tail trên console để theo dõi các errors xảy ra với web server, càng xem tôi càng thêm sốt ruột vì hầu như mỗi giây trôi qua là mỗi segfault hiện lên màn hình. Lý do làm tôi sốt ruột rất đơn giản, nó không chỉ mang dấu hiệu cho tiềm năng đổ vỡ của web service bất cứ lúc nào mà còn là dấu hiệu của mức phục vụ kém hiệu năng của server. Cứ mỗi segfault xảy ra thì chúng ta có thể đoán một process nào đó cần được mở ra để phục vụ nhưng không thành công và kết quả thì... ai cũng có thể đoán được: đúng vậy, request từ trình duyệt hoàn toàn không nhận được kết quả gì cả nếu chính process được mở ra để trả lời bị segfault. Tôi quyết định chỉnh lại log level trở thành "debug" level -32- và tái khởi động web server -33-. Mở ra một cái "đuôi" tail mới trên console, tôi hơi thất vọng vì mình không tìm thêm được bao nhiêu thông tin có ích trong việc tìm nguồn gốc của các segfault. Error log thông báo thông tin tương tự như sau:
Code:
[Thu Oct 13 21:36:26 2004] [notice] child pid 22332 exit signal Segmentation fault (11)
...

Tôi thở dài, đành phải dùng đến biện pháp chạy web server xuyên qua gdb -34- để tìm lỗi vậy. Tôi rất miễn cưỡng khi làm thế này, không phải vì phải động đến gdb mà vì đây là một site đang "sống", đang hoạt động và đang bị... DoS. Nhưng không làm thế thì làm sao tìm lỗi để trị nó? Tôi kiểm tra qua tình hình netstat hiện thời của server, chà! không được, có quá nhiều người dùng đang online ngay lúc này, chắc phải để sáng sớm mai khi chẳng có mấy ai vào HVA forum. Cũng đã khuya, tôi xếp laptop lại.

Sáng 14/10:

Như thường lệ, tôi có mặt ở công ty rất sớm. Làm một ly cà fê, tôi mở máy lên và log vào HVA server. Để xem thử tình hình server ra sao? Tôi gõ w và tiếp theo là netstat -nat. Hèm... tốt, server im ắng lắm, chỉ có lác đác vài mạng thì chắc không sao (lão JAL đã thông báo tôi cứ việc làm những gì tôi cần làm, được "lệnh" rồi mà ). Tôi thử "đì bấc" một child process theo kiểu hú hoạ xem sao vì error log cứ tiếp tục thông báo lỗi mỗi giây. Sáng nay ít người vào nên segfault không được báo ở mức độ đó nhưng ít nhất cũng 30 giây một lỗi. Tôi xem thử có bao nhiêu child process được forked -35-:
Code:
# ps -ef | grep httpd

Chà, mười mấy "đứa con" (child process) đang nằm chờ. Tôi vớ ngay một trong mười mấy đứa, process xxxx và thử xem:
Code:
gdb httpd xxxx

sau khi hàng tá symbols được load đâu đó, rồi nó đứng yên chờ.

Tôi biết debug kiểu này thật không khác gì "chó ngáp nhằm ruồi" vì trong đống child process kia có thể một hoặc nhiều "đứa" bị segfault chớ không phải ngay cái process xxxx tôi đang thử. Hơn nữa, "đứa" tôi đang dùng để thử có thể không có dịp tiếp nhận connection trong khi tôi đang thử thì "đì bấc" cái nỗi gì? Mèn, tôi lẩm nhẩm "việc gì phải e dè, cho cái web server chỉ chạy trên 1 process rồi tha hồ mà xem cái của khỉ gì đang xảy ra". Quyết định vậy xong, tôi thực hiện ngay. Tôi dừng hẳn web server và khởi động từ bên trong gdb -36- với thông số -DONE_PROCESS để buộc server chỉ chạy ở chế độ single process để tiện "đì bấc". Dịch vụ khởi tạo bình thường, thư viện dẫn bình ổn, và ngay sau đó: bang! có ngay một connection mới đi vào, socket mở ra để tiếp nhận. Cha chả, để xem thử cái gì xảy ra.

Trong phút chốc trên gdb console hiện ra hàng loạt thông tin liên quan đến mmap của php và tiếp theo đó là thông tin về việc truy dụng memory (mmap) cho một số các modules khác mà web service đang dùng. Bởi lẽ dịch vụ đang chạy ở chế độ single process, sigfault xảy ra ở đây dẫn đến tình trạng dịch vụ hoàn toàn bị tắt bỏ. Lý do đơn giản là khi dịch vụ chạy ở chế độ multi process thì nếu một "con" nào chết, process "mẹ" sẽ tiếp tục đẻ ra thêm nên dịch vụ vẫn tiếp tục hoạt động. Một cách tổng quát mà nói thì web service không hoạt động ở tình trạng "khoẻ mạnh", tôi cần biết chắc do mmap -37- được gọi để ấn định memory cho các modules và bị segfault là đủ. Rất tiếc tôi đã không lưu giữ chi tiết của kết quả "đì bấc" vì lúc ấy tôi nghĩ rằng các thông tin này không cần thiết, hơn nữa thông tin đì bấc đâu phải là "bằng chứng" của chuyện DoS mình đang điều tra cho nên càng không cần phải giữ lại. Đến nước này chỉ còn một giải pháp là tái biên dịch lại trọn bộ nhu liệu của web server và các modules kèm theo. Lý do phải làm chuyện này vì tôi nghi ngờ web service trên HVA dùng binaries có sẵn và những binaries này dùng các thư viện kèm không tương ứng với những gì đang có trên hệ thống.

Tôi tái khởi động lại web service và để cho nó hoạt động như bình thường. Sau đó, tôi gởi ngay cho JAL một PM để thông báo cần phải biên dịch lại trọn bộ phần mềm của web server. Lúc này còn sớm lắm, Japan lại sau nơi tôi cư ngụ hai giờ đồng hồ (tính theo múi giờ). Tôi quyết định tải các gói mã nguồn cần thiết và bắt tay vào việc biên dịch. Dự định trong đầu tôi rất đơn giản:
- giữ nguyên những gì đang chạy trên hệ thống (để phòng bị).
- biên dịch vài cài dịch vụ web mới ở nơi khác.
- khi phần mềm của web server mới sẵn sàng, chỉ cần tắt bỏ cái cũ, khởi động cái mới.
- nếu có sự cố gì thể quay về cái cũ.

Sẵn dịp, tôi tải luôn một số modules cụ thể trợ giúp cho "công cuộc" chống x-flash. Biên dịch lại quá đơn giản và nhanh chóng, chưa đến mười lăm phút, tôi đã hoàn tất mọi thứ. Tôi chỉ cần copy cái cấu hình của web server hiện dụng và mang qua cho web server mới, điều chỉnh lại các chi tiết cần thiết. Dò xuyên qua mọi thứ một lần cuối, tôi hài lòng và logoff HVA server. Chắc phải vài giờ sau mới có hồi báo từ JAL, bây giờ phải giải quyết công việc ở sở cho xong rồi sẽ quay lại HVA sau.

Các bạn có thể theo dõi tiếp phần 6 tại http://hvaonline.net/hvaonline/posts/list/180.html

Chú thích:
-27- HTTP status code chia làm 5 nhóm: 10x, 20x, 30x, 40x và 50x. Mỗi nhóm biểu thị tình trạng kết nối giữa client và server qua giao thức HTTP. Xem thêm chi tiết ở: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

-28- ICMP hay Internet Control Message Protocol. Một giao thức cần thiết trong TCP/IP chuyên để thông báo tình trạng gói tin. Trong trường hợp trên ICMP type 11, code 0 dùng để biểu thị trình trạng gói tin khi chuyển đi đã bị "hết giờ" trước khi đến đích. Xem thêm thông tin về ICMP ở: http://www.faqs.org/rfcs/rfc792.html

-29- hop đơn vị tính cho mỗi router mà gói tin đi xuyên qua. Giá trị "hop" biểu thị rõ nhất khi dùng traceroute từ một IP này đến một IP kia. Cứ mỗi lần gói tin đi qua một router, giá trị TTL lại bị router ấy trừ đi 1 cho đến khi nào nó tới đích, mỗi lần trừ biểu thị cho 1 hop. Nếu traceroute chưa hoàn tất đường cần phải dò (trace) mà giá trị TTL của packet gởi đi đã chấm dứt (bằng 0) thì router nào "đụng" phải packet ấy phải gởi 1 gói ICMP type 11 code 0 (thông điệp "time exceeded") ngược về host nguyên thuỷ đã gởi gói tin đi để thông báo tình trạng gói tin.

-30- các gói tin mang tính INVALID nói một cách tổng quát là các gói tin không thuộc một xuất truy cập nào, không được firewall điều tác và ghi nhận mà chỉ xuất hiện bất chợt và không đi qua các cơ chế giao thức hợp lệ. Đối với quy định riêng của HVA firewall, và riêng với giao thức ICMP thì chỉ có HVA server mới được quyền khởi tạo các gói tin ICMP và host nào đó nhận được, cần trả lời thì firewall mới mở cửa để nó đi vào với mục đích trả lời mà thôi. Nếu một gói tin ICMP (bất chấp loại nào) được khởi tạo từ bên ngoài và đi đến HVA server đều bị cản. Tính chất gói tin này có thể hoàn toàn hợp lệ về mặt giao thức nhưng bất hợp lệ đối với quy định trên HVA firewall.

-31- segmentation fault hay còn gọi tắt là SEGFAULT. Trường hợp segfault xảy ra khi một nhu liệu nào đó cần truy cập vào vị trí nào đó trên bộ nhớ nhưng không được phép hoặc cách truy cập này không hợp lệ.

-32- Các dịch vụ chạy trên *nix nói chung đều cho phép ấn định mức độ thông tin được log của dịch vụ báo cáo. Ở đây tôi dùng "debug" level có nghĩa là ở mức độ chi tiết nhất có thể được để lấy càng nhiều thông tin càng tốt nhằm mục đích xác định vùng lỗi xảy ra với dịch vụ. Cần nói thêm, "log" là phương tiện, là khởi điểm của quy trình tìm lỗi. Điều rất đáng ngạc nhiên là đa số những admin bình thường ít khi dùng đến nó khi gặp sự cố mà thường chỉ cậy vào thao tác "stop / start" một dịch vụ và hy vọng nó sẽ ổn. Nếu may mắn, dịch vụ ấy tiếp tục hoạt động, nếu không may dịch vụ lại vướng vào đám "lỗi" thì những admin này thường cầu cứu đến các dịch vụ hỗ trợ hoặc hỏi bất cứ nơi nào có thể hỏi được. Theo tôi, đây là một thói quen nên sửa đổi.

-33- Tái khởi động web server ở đây không giống như ngưng nó hoàn toàn rồi tái khởi động; làm thế này sẽ gián đoạn đến các xuất truy cập hiện đang xảy ra trên server. Tái khởi động ở đây chỉ là dạng "graceful", có nghĩa là server được nhận tín hiệu cần tái khởi động để nạp lại thông tin của cấu hình, nó sẽ đợi cho các process có những connection đang diễn tiến xong rồi mới kết thúc chúng. Làm thế này đối với người dùng hoàn toàn "trong suốt" và không có gián đoạn nào.

-34- gdb hay GNU Debugger, một công cụ không thể thiếu được cho những ai cần debug các chương trình được viết bằng C, C++ hay Modular 2. Nó cho phép người dùng "xem" những gì xảy ra trong khi một chương trình đang chạy và nếu chương trình bị treo, báo lỗi hay bất cứ chuyện gì bất thường xảy ra, nó có thể cung cấp những thông tin cần thiết để xác định cụ thể nguyên nhân sự cố nằm ở đâu. gdb có trên các Linux distro (nếu cài thêm bộ development tool) và gần đây trở nên rất phổ biến trên các *nix thương mại như AIX, Solaris, UX-HP và tất nhiên MacOS X. Xem thêm thông tin về gdb ở: http://www.gnu.org

-35- prefork, cách tạo process mới cho mỗi connection. Đây là cách "cổ điển" nhưng vì phiên bản php hiện đang dùng trong trường hợp này không thuộc dạng "thread safe" nên phải dùng đến prefork. Điều này có nghĩa mỗi request đi vào và cần php phục vụ trang động (dynamic page) thì phải "fork" ra một process hoàn toàn mới. Khái niệm tổng quát là như vậy, nếu bạn cần đào sâu thì nên nghiên cứu thêm về cơ chế tạo process và thread cho một system (bài viết này cho môi trường *nix).

-36- đây là một trong những thủ thuật debugging dùng gdb, tôi không đi sâu vào chi tiết vì làm loãng nội dung. Nếu bạn thích thú thì chính tài liệu đi kèm với gdb có đầy đủ các thông tin cho vấn đề này.

-37- mmap hay "map pages of memory", một hàm dùng để xác định một khoảng bộ nhớ cho một process được tạo ra để thực thi một công tác nào đó trên hệ thống. Xem thêm chi tiết về mmap ở: http://www.opengroup.org/onlinepubs/009695...tions/mmap.html
Sáng 13/10: (tiếp theo)
Sau vài giờ giải quyết công việc ở sở, tôi quay lại với HVA server để xem xét tình hình kỹ lưỡng hơn. Tôi dán chặt vào màn hình như bị thôi miên, có quá nhiều "OVERCONNLIMIT" từ nhiều IP khác nhau trong mỗi giây. Tôi "ngắt" ngay một đoạn của firewall log và webserver log để so sánh xem sao. À ha, có một đoạn "x-flash" vẫn đi vào HVA server được:
Code:
203.160.1.66 - - [13/Oct/2004:10:34:22 -0400] "POST /forum/ HTTP/1.1" 200 8538 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:22 -0400] "POST /forum/ HTTP/1.1" 200 8538 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:24 -0400] "POST /forum/ HTTP/1.1" 200 8538 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:25 -0400] "POST /forum/ HTTP/1.1" 200 8537 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:27 -0400] "POST /forum/ HTTP/1.1" 200 8539 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:27 -0400] "POST /forum/ HTTP/1.1" 200 8539 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:34:28 -0400] "POST /forum/ HTTP/1.1" 200 8536 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"

Trong khi đó, firewall log lại ghi nhận:
Code:
Oct 13 10:34:23 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=38899 PROTO=TCP SPT=16634 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:34:25 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=39129 PROTO=TCP SPT=57986 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:34:26 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=43098 PROTO=TCP SPT=25311 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:34:28 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=43253 PROTO=TCP SPT=43128 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:34:31 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=44716 PROTO=TCP SPT=12221 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0

Hai đoạn log trên chứng tỏ điều gì? Nếu bạn so sánh tỉ mỉ thời gian ghi nhận giữa hai đoạn log trên bạn sẽ thấy cái thú vị của nó.
- Lúc 10:34:22, IP 203.160.1.66 gởi thành công 1 cái POST đến HVA server và webserver của HVA ghi nhận điều này.
- Cũng trong lúc này, 10:34:22, nó gởi tiếp cái POST kế tiếp cũng thành công. Ở bước này, với chiều dài của HTTP POST cỡ trên 2000 bytes thì trình duyệt dùng để gởi đến HVA server hẳn đã mở ra thêm ít nhất là vài connection. Cả hai cú POST trên chắc chắn đã đụng đến giới hạn cho phép.
- 1 giây sau, lúc 10:34:23 firewall thông báo đã cản SYN request từ 203.160.1.66 vì tình trạng quá giới hạn đã xảy ra.
- Lúc 10:34:24, IP này lại gởi thành công thêm 1 POST khác vì chắc hẳn 2 cái POST đi trước đã trả lại vài connections và "connection pool" lúc này đã trống chỗ đủ để 203.160.1.66 gởi SYN và đi vào.
- Lúc 10:34:25, IP này tiếp tục gởi thêm 1 POST khác thành công nhưng đồng thời ngay lúc này firewall cũng đã cản một SYN packet của nó. Điều này có lẽ packetlength quá lớn nên nó phải mở thêm connection để đẩy tiếp payload. Tuy nhiên, đoạn đi sau đã bị cản.
- Lúc 10:34:26, chắc hẳn connection pool vẫn chưa trống chỗ nên nó lại bị firewall cản thêm lần nữa.
- Đến 10:34:27, lúc này hẳn connection pool đã trống vì các cú POST trên đã lần lượt hoàn tất nên nó lại POST thành công hai cái POST.
- Đến 10:34:28, hẳn IP này lại gởi một phần của gói POST dài thậm thượt kia và bị firewall cản ngay vì 2 cú POST trên chiếm hết chỗ của connection pool.

Qua đoạn trên, ta thấy rõ một điều, cứ trung bình sau 2 cú POST thành công lại có một cú cản và tiếp theo sau đó là một cú POST nữa nhưng bị cản phần "continuation". Như vậy, tạm hình dung là cứ 3 POST gởi đi thì bị cản 1 POST rưỡi. Nếu quả thật là vậy thì có ít nhất 50% các gói POST bị "huỷ" sau khi firewall ứng dụng giới hạn connection. Nếu tính theo số liệu ghi nhận được trước đây là có đến 12000 connections trong 2 giờ thì có đến 6000 "chú" bị rụng (?). Chà chà, thông tin này có vẻ khá phấn khởi đây. Không phấn khởi sao được khi 6000 "quả" x-flash nhường chỗ cho các truy cập hợp lệ?

Tôi tiếp tục theo dõi và phân tích mối tương quan giữa web server log và firewall log. Giờ này không phải là lúc cao điểm của các chú "x-flash" nên lâu lắm mới thấy một chùm vài chục "quả" đi vào. Tuy nhiên, logic "3 và 1 1/2" ở trên vẫn áp dụng đều đặn. Tôi nảy ra ý định giảm lượng "connection" cho phép từ một IP trong bất cứ lúc nào để xem firewall "xử lý" các chú "x-flash" tham lam ra sao. Hơn nữa, diễn đàn lúc này còn vắng lắm. Tôi chỉnh lại giá trị giới hạn connection từ 8 thành 6 và tái khởi động lại firewall (tất nhiên là vẫn thao tác mọi chuyện qua SSH).

Voila! phóng lại cái "đuôi" tail để xem firewall log. Im ắng quá nhỉ? trong log của web server thỉnh thoảng ghi nhận vài truy cập, firewall log thì thông báo nhiều hơn. Nào là những "quả" FIN đi sau SYN rồi lại RST đi sau SYN -19- đều bị firewall tóm cổ và cho vào /dev/null, nào là những cú truy cập thiếu bình thường như "NEW" connection nhưng không mang flag SYN -20- v..v... Những thông tin trên chỉ để minh hoạ sơ qua một số trách nhiệm khác của firewall và chắc chắn không có liên quan gì đến những chú "x-flash" ở đây vì "x-flash" có mục đích rõ ràng lắm. Nếu "x-flash" thay đổi thái độ gởi gói tin thì hẳn đã bị firewall cản ngay vòng ngoài vì bị xếp dạng vô giá trị, vả lại "x-flash" nằm ở tầng application, công cụ cho phép tạo ra nó chắc đã không cho chọn những thứ tỉ mỉ ở transport layer (như chọn flag nào cho gói tin TCP ở giai đoạn nào, các TCP options ra sao....) để có thể thay đổi thái độ được. Nói cho cùng "x-flash" là một phương tiện phục vụ cho multimedia, nó không phải là phương tiện dùng để thực hành các mục đích mờ ám trong lĩnh vực bảo mật. Bởi vậy, phải công nhận một điều là tác giả mấy con "flash" này rất sáng tạo. May thay, x-flash để lại quá nhiều dấu vết đặc thù và chính nó không phải là công cụ "thứ thiệt" để tạo packets, cho nên việc nhận diện và loại bỏ nó không quá phức tạp.

Trở lại với giới hạn 6 connections, tôi thấy có những chùm cản trên firewall tương ứng với những thông báo trên web server log:
Code:
203.160.1.66 - - [13/Oct/2004:10:59:34 -0400] "POST /forum/ HTTP/1.1" 200 8537 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:59:41 -0400] "POST /forum/ HTTP/1.1" 200 8537 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
203.160.1.66 - - [13/Oct/2004:10:59:45 -0400] "POST /forum/ HTTP/1.1" 200 8539 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"

Và firewall log lại ghi nhận:
Code:
Oct 13 10:59:35 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=49830 PROTO=TCP SPT=32841 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:59:36 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=49852 PROTO=TCP SPT=32842 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:59:42 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=49933 PROTO=TCP SPT=32853 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:59:43 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=49954 PROTO=TCP SPT=32858 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Oct 13 10:59:46 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.160.1.66 DST=192.168.1.100 LEN=48 TOS=0x00 PREC=0x00 TTL=56 ID=50235 PROTO=TCP SPT=32865 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0

Với hai đoạn logs trên, chúng ta thấy ngay sự khác biệt giữa số lượng gói tin "được vào" và số lượng "bị cản" so với lần trước (dùng giới hạn 8 connections):
- Lúc 10:59:34, 203.160.1.66 gởi thành công một POST đến HVA server.
- Sau đó, trên firewall log tường trình 203.160.1.66 bị cản lúc 10:59:35, có thể đây là cú POST tiếp theo vì giới hạn 6 connections vẫn có thể vừa khít cho cú POST đầu.
- Tiếp theo sau đó, lúc 10:59:36, firewall lại tường trình cản 203.160.1.66, có lẽ đây là đoạn "continuation" của cú POST ngay ở trên và vì quá giới hạn nên bị cản.
- Lúc 10:59:41, 203.160.1.66 lại gởi thành công một POST khác nhưng tiếp theo sau đó lúc 10:59:42 và 10:59:43, firewall lại liên tiếp báo nó đã cản 2 "cú" từ 203.160.1.66
- Đến 10:59:45, 203.160.1.66 gởi thành công thêm một cái POST nhưng lại tiếp tục bị firewall cản vào 10:59:46 và các gói tiếp theo diễn tiến y hệt chu trình trên.

Điều này cho thấy, cứ 3 "cú" 203.160.1.66 dội vào thì có hết 2 "cú" bị cản một cách khá đều đặn. Nếu vậy, thì với 12000 "cú" trong 2 giờ thì có 8000 cú bị cản (?). Không tệ lắm. Lúc này HVA server không bận rộn lắm nên khó có thể đoán giới hạn 6 connection có tạo ảnh hưởng "xấu" đến các thành viên muốn truy cập một cách hợp pháp. Tuy nhiên, cũng với lượng truy cập khá tương tự trước khi khởi động lại server và kernel cũ, mức "load" của server lúc này giảm xuống chỉ còn 1/3 lúc trước (từ 1.5 - 1.6 load xuống còn 0.4 - 0.5 load). Đây là dấu hiệu tốt.

Thôi, vậy là tạm đủ với firewall log lúc này. Tôi phải tiếp tục bước kế tiếp. Để tối nay, khi đợt "tấn công" hàng đêm lên cao điểm, tôi sẽ theo dõi sau.

Mục tiêu kế tiếp tôi đã hình thành (trong đầu) là xét phần IDS của server. Qua vài phút dò xét, tôi khám phá snort -21- đã được cài sẵn. Phiên bản không được cập nhật lắm nhưng cũng thuộc diện "new generation", đặc biệt các signature -22- thì mới toanh. Nhóm signatures của snort trên server này được điều chỉnh để tự động cập nhật các signature mới nhất trong ngày. Kèm theo đó là tiện ích dùng để đọc và lý giải log của snort cho mỗi giờ, kết quả lý giải này có thể xem ở dạng "web". Quả là tiện dụng. Tuy nhiên, snort chỉ dừng lại ở cấp độ theo dõi và tường trình các gói tin "trùng" với signature mà không có phản ứng trực tiếp gì đến các gói tin vi phạm. Tôi quyết định tải phiên bản mới nhất của snort và tái biên dịch nó để đưa vào một số chức năng "phản ứng trực tiếp" để đáp ứng với kế hoạch tôi ngầm định sẵn.

Phần biên dịch snort không có gì lý thú ngoài việc phải chuẩn bị một số thư viện "cấp thấp" cần thiết để snort có thể sniff và việc chỉnh định thêm chọn lựa "--enable-flexresp" để cho phép snort ứng động đến các packet vi phạm. Gói mã nguồn của snort khá nhỏ nên thời gian biên dịch chỉ mất có vài phút là xong. Hồ sơ cấu hình của snort -23- đã có sẵn, init của snort -24- đã có sẵn, tôi chỉ cần điều chỉnh một số chi tiết cần thiết để buộc binary mới của snort chạy trên hệ thống và dùng hồ sơ cấu hình có sẵn.

Bước kế tiếp là bước tôi cho là lý thú nhất vì nó trực tiếp ứng dụng những gì tôi đã phân tích trong phần đầu của bài. Đúng vậy! chính là "x-flash" POST payload và những thông tin hết sức đặc thù của chúng. Tôi hình thành "signature" đầu tiên cho HVA server như sau:
Code:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (flags: PA; msg:"POST Null hex - Flash attack HVA"; flow:to_server; content: "|50 4F 53 54|"; content:"|78 2D 66 6C 61 73 68|"; offset:30; depth:80; classtype:attempted-NullDataPOST; resp:rst_all; resp:rst_all; resp:rst_all; react:block;)

Tôi không có dự định phân tích và giả thích kỹ lưỡng signature ở trên trong bài viết này, nếu bạn thật sự thích thú với snort thì trên website của snort có đầy đủ các thông tin chi tiết để có thể hiểu nó. Tuy nhiên, tôi muốn nêu ra vài chi tiết quan trọng (và lý thú) về signature. Signature là "kim chỉ nam" cho snort làm việc, cho nên chúng rất đa dạng và phức tạp. Trong trường hợp này, tôi muốn snort làm cách nào ít tốn thời gian và tài nguyên nhất để phản ứng kịp thời đến các packets có tính chất như tôi đưa ra trong signature trên:
- flags: PA: tôi nắm chắc là các gói tin "x-flash" có TCP flag là ACK-PSH nên chỉ định snort tập trung vào các gói mang flag PA (PSH ACK) thay vì mất thời gian và tài nguyên với mọi gói tin đi vào.
- flow:to_server: tôi muốn snort chỉ kiểm tra các gói tin đi vào server và không mất thời gian với gói tin đi ra vì HVA sever không dùng "x-flash" để "chơi" ai cả
- content: "|50 4f 53 54|"; content:"|78 2d 66 6c 61 73 68|";: tôi muốn snort chỉ kiểm tra các gói tin có nội dung như đã chỉ định trong "content" này, và nếu quả thật chúng là như vậy thì mới có thêm phản ứng.
- offset:30; depth:80;: tôi muốn thâu hẹp phạm vi tìm kiếm dấu hiệu đặc thù để snort không mất thời gian đi lục tìm trong suốt một payload dài thậm thượt.
- resp:rst_all và react:block: tôi muốn snort phải có phản ứng đến các gói tin có tính chất như trên. Phản ứng bằng cách là liên tiếp gởi 3 gói RST đến cả hai đầu truy cập (giữa máy chạy "x-flash" và HVA servers) để tắt ngang đường lưu thông và sau đó, cản luôn gói tin nào tiếp tục đi tới từ nguồn mang gói tin vi phạm này.

Vậy, điều lý thú là ở đâu? theo tôi, đó là ở chi tiết hình thành một signature sao cho snort có thể ứng hoạt ở mức độ nhanh nhất có thể được. Chi tiết content ở trên có thể không cần thiết phải mang giá trị HEX mà có thể ở dạng ASCII bình thường (bạn thử đổi giá trị HEX trong ví dụ trên xem nó là gì). Tuy nhiên, làm như vậy là làm cho snort chậm thêm một tí vì nó phải chuyển đổi từ ASCII thành HEX rồi mới xem gói tin có dấu hiệu trùng với đã ấn định hay không. Chi tiết offset cũng hết sức lý thú vì nếu thiếu chi tiết này, snort sẽ đi suốt một dải thông tin của cả gói tin để tìm xem có cái gì trùng hay không, làm thế thì rất mất thời gian. Tuy nhiên, điểm tối quan trọng ở đây là để giúp snort phản ứng kịp thời đến gói tin vi phạm (thực thi resp:rst_all và react:block) trước khi nó đã đi vào đến tận web server thành công.

Chúng ta có thể điều chỉnh snort để nó "gọi" firewall và cản hẳn IP nào vi phạm, nhưng làm như thế thì quá nguy hiểm vì nếu có nhiều người dùng vô tội cùng chia xẻ IP đó thì sẽ bị cản chung ---> mục đích tạo "denial of service" đã thành công. Nói cho cùng, nạn "x-flash" xảy ra với HVA thuộc dạng "slash-dot effect" -25- vì các "x-flash" chỉ đơn thuần tạo ra quá nhiều requests, và những request này hoàn toàn hợp lệ (mặc dù chủ đích lại đen tối). Thay vì dùng phương pháp cản IP, bất cứ phương pháp nào cụ thể loại bỏ các gói tin có tính đặc thù như "x-flash" (và tương tự) đều là giải pháp khả thi. Bởi lẽ, cản IP là cản những cá nhân vi phạm lẫn những người vô can. Hơn nữa, chiến thuật cài "x-flash" vào một trang nào đó để người dùng duyệt trang ấy sẽ "vô tình" gởi requests đến HVA là chiến thuật dùng tay những kẻ vô can để thực hiện ý định. Đây chính là lý do càng không nên cản IP.

Dùng snort signature ở trên, tôi có hai mục đích chính (và rất cụ thể):
1. Bất cứ khi nào snort thấy một packet có tính chất như đã phân tích ở những phần trên --> reset nó, kết liễu nó, kết liễu cả đường nối giữa HVA và nó. Điểm này đơn giản và dễ hiểu.

2. Nếu một chùm gói tin đi vào thuộc dạng vi phạm mà snort không cản được thì ít nhất cũng tạo điều kiện cho firewall cản. Điều này có nghĩa, một stream được tạo ra một cách hợp pháp, đến lúc nào đó sẽ thuộc tình trạng "ESTABLISHED", firewall sẽ không cản trở các packets ra vào nếu chúng đã thuộc một xuất truy cập thuộc tình trạng này. Tuy nhiên, nếu một (và chỉ một packet) trong stream này bị chuyển thành tình trạng nào khác (do snort can thiệp) thì sẽ bị firewall cản trọn bộ các gói tin còn lại của stream vi phạm.

Hãy thử đào sâu một chút khía cạnh này, giả sử một request đi từ IP xxx.xxx.xxx.xxx đến HVA server:
- mở đầu bằng SYN --> OK, hoàn toàn hợp lệ, chưa có dấu hiệu gì về đặc tính "x-flash", snort sẽ không có phản ứng gì cả.
- tiếp theo HVA server trả lời request này bằng SYN-ACK --> OK, hoàn toàn hợp lệ, HVA server chỉ tiếp nhận và cho đầu bên kia biết là nó đã tiếp nhận truy cập, snort sẽ không can thiệp vì signature ở trên ấn định rất rõ là nó chỉ kiểm tra nguồn đi vào máy chủ (flow:to_server) và không cần phải làm gì với gói tin đi ra.
- packet kế tiếp đi vào hẳn là ACK-PSH và bắt đầu có chứa payload --> có chuyện xảy ra vì snort đã kiểm tra. Ngay lúc nó nhận đủ thông tin và nhận diện được gói tin này vi phạm, snort sẽ tạo báo động đến log, thực thi các lệnh đã ấn định. Chuyện gì xảy ra ở đây? Có hai trường hợp:
a) gói tin vi phạm này lọt vào thành công vì đến khi snort thực thi xong các lệnh trên thì gói tin đã hoàn tất. Snort bị rơi vào tình trạng "đánh gió" .

b) gói tin vi phạm bị snort "reset", theo những tôi theo dõi trước đây, snort vẫn có thể thực thi lệnh kịp thời và gói tin này bị cắt đứt giữa đường. Khi snort gởi lệnh rst_all nó thông báo cùng một lúc đến máy từ nguồn xxx.xxx.xxx.xxx và HVA server rằng: "xong, chấm dứt, kết thúc, không còn gì để tiếp tục" và hai đầu truy cập bị ngắt. Chuyện gì xảy ra ở giai đoạn này? socket trên HVA server đóng xuất truy cập này và đối với hệ thống cũng như firewall, xuất truy cập này không còn nữa. Nếu từ phía xxx.xxx.xxx.xxx vẫn tiếp tục gởi gói tin còn lại của stream đến HVA server, chắc chắn nó sẽ bị huỷ bỏ vì HVA firewall sẽ thấy gói tin này hoàn toàn mới, không thuộc xuất truy cập nào hết nhưng lại mang flag ACK-PSH (không phải là SYN để khởi tạo một xuất mới). Lý do rất đơn giản: HVA firewall là stateful firewall, nó theo dõi tình trạng mỗi gói tin ra vào. Nói theo thuật ngữ firewall thì gói tin tiếp tục đi vào này bị xếp vào dạng "lost state" hay "invalid state" nên không được tiếp nhận theo đúng quy định của firewall.

- nếu gói tin ở trên đi qua được vì trường hợp a) xảy ra thì gói tin kế tiếp sẽ tiếp tục được gởi (ở dạng continuation nếu gói tin trên quá lớn). Cũng như trên snort tiếp tục theo dõi, nếu có thêm một signature bổ sung cho signature trên thì nó sẽ ứng động và xử lý gói tin tiếp theo này và một trong 2 trường hợp a) hoặc b) sẽ xảy ra. Một trong những signature đi theo mà tôi đã hình thành để xử lý các gói "continuation" có dạng tương tự như sau:
Code:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (flags: PA; msg:"POST Null frag1 - Flash attack HVA"; flow:to_server; content:"|68 6F 74 6C 69 6E 6B 73 3D 4F 66 66 69 63 61 6C|"; offset:30; depth:40; classtype:attempted-FragDataPOST; resp:rst_all; resp:rst_all; resp:rst_all; react:block;)

Signature này chỉ định cho snort tiếp tục theo dõi và phản ứng đến các gói tin mang tính chất như trên. Nếu thích thú thì bạn thử chuyển đổi giá trị HEX -26- ở trên để xem giá trị ASCII là gì (?)

Vậy ngoài giới hạn connection đã bàn ở trên, snort có thể gián tiếp giúp cho công tác cản trở thêm các gói tin vi phạm. Nếu chủ quan thì có thể cho rằng có cơ hội 50/50 cho mỗi gói tin vi phạm bị cản theo phương thức trên. Nếu dè dặt thì có thể cho rằng ít ra cũng có 1/3 cơ hội gói tin vi phạm bị cản theo cách này. Như vậy, trong 12000 "quả" đi vào thì có 6000 "quả" bị cản nếu dùng phương thức giới hạn 8 connections ở trên, cộng thêm 1/3 số lượng các "quả" bị snort cản với số 6000 còn lại thì tổng số lên đến:
Code:
( 12000 - 6000 ) + ( 6000 / 3 ) = 8000

Sau khi tái biên dịch snort, chỉnh sửa các hồ sơ cấu hình và thêm vào các signature cần thiết (có nhiều hơn 2 signatures cho x-flash vì có những biến đổi trong các gói tin vi phạm này), tôi tái khởi động snort và dành vài phút để điều theo dõi log của snort, sau đây là một đoạn ngắn mà snort (phiên bản mới) đã "báo cáo" sau khi được tải thêm những signature cụ thể cho "x-flash":
Code:
10/13-11:02:22.000189 [**] [1:0:0] POST Null hex - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 43.244.38.14:2387 -> 192.168.1.100:80
10/13-11:02:22.000189 [**] [1:0:0] POST Null frag1 - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 43.244.38.14:2387 -> 192.168.1.100:80
10/13-11:02:23.696940 [**] [1:0:0] POST Null hex - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 220.72.203.16:1768 -> 192.168.1.100:80
10/13-11:02:23.696940 [**] [1:0:0] POST Null frag1 - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 220.72.203.16:1768 -> 192.168.1.100:80
10/13-11:02:26.305662 [**] [1:0:0] POST Null hex - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 203.210.249.241:64004 -> 192.168.1.100:80
10/13-11:02:26.305662 [**] [1:0:0] POST Null frag1 - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 203.210.249.241:64004 -> 192.168.1.100:80
10/13-11:02:27.246717 [**] [1:0:0] POST Null frag2 - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 203.210.249.241:64008 -> 192.168.1.100:80
10/13-11:02:27.246717 [**] [1:0:0] POST Null hex - Flash attack HVA[**] [Classification: using POST to DoS by flash] [Priority: 1] {TCP} 203.210.249.241:64008 -> 192.168.1.100:80

Chuyện gì xảy ra với cơn lũ "x-flash" hàng đêm? Bạn muốn biết tiếp à? vậy thì đón xem bài kế tiếp vậy.

Chú thích:
-19- FIN đi sau SYN và RST đi sau SYN có nghĩa là máy con gởi SYN để truy cập đến server, server trả lại SYN-ACK và thay vì máy con tiếp tục gởi ACK để tiếp nối 3-way handshaking thì nó lại gởi RST hoặc FIN ở bước này để kết thúc xuất truy cập với server. Đây là kỹ thuật tấn công SYN-FIN hoặc SYN-RST nhằm tạo ra hàng "tấn" "TIME_WAIT" sockets trên server (để tiêu hao memory của server).

-20- Đối với giao thức TCP, một xuất truy cập mới toanh phải bắt đầu từ gói tin mang flag SYN (để đi qua 3 bước bắt tay). Nếu xuất truy cập mà bắt đầu bằng flag nào khác thì có thể là chủ nhân của nó không có thiện ý hoặc cũng có trường hợp gói SYN đã gởi trước đó 10 phút chẳng hạn và bị time-out vì lý do gì đó, mãi sau 10 phút sau khi server đã trả lời SYN-ACK nó mới "lồm cồm" đi ngược lại và hồi đáp với gói tin ACK để tiếp tục xuất truy cập. Lúc này, nếu server được chỉnh để "time-out" sớm hơn 10 phút thì gói tin hồi đáp trên trở nên vô nghĩa đối với firewall. Firewall sẽ cho rằng đây là gói tin hoàn toàn mới nhưng lại mang flag ACK. Trên thực tế, loại packets này chỉ thấy ở một số phiên bản cũ của MS (như Windows 9x) hoặc chỉ thấy khi chủ nhân của nó cố tình gởi gói tin loại này với mục đích không chính đáng cho lắm.

-21- một "open source" NIDS (Network Intrusion Detection System) được phát triển rất mạnh. Hiện snort đã được ứng dụng trong rất nhiều sản phẩm bảo mật hạng nặng. Xem thêm chi tiết ở: http://www.snort.org

-22- snort là một loại IDS dùng signature. Signature là một dạng rule được khảo sát và hình thành từ những bằng chứng và dấu hiệu thâu thập được từ các gói tin có tính dung hại và có tính đặc thù. Dựa vào signature, snort sẽ báo động (hoặc ứng tác nếu chỉnh định cho nó) nếu nó tìm thấy gói tin được "sniff" mang tính thất trùng hợp với signature có sẵn.

-23- có nhiều cách chạy "snort" nhưng cách biến nó thành một daemon (một dịch vụ của hệ thống) thì nên dùng một hồ sơ cấu hình hoàn chỉnh vì có quá nhiều chi tiết cần chỉnh định để snort có thể hoạt động như một IDS... thứ thiệt.

-24- để khởi động snort như một daemon khi máy chủ khởi động, cần phải có init script để nó được khởi động đúng run level (cho các hệ thống *nix thuộc nhánh SysV). Vấn đề này thuộc phạm trù chuẩn bị hệ thống. Để biết thêm chi tiết, bạn nên tham khảo về "run level of SysV).

-25- "slashdot effect" là thành ngữ ám chỉ hiện tượng một website quá sức phổ biến và được ưa thích nên lượng truy cập cao hơn mức hệ thống có thể đảm đương. Điều này dẫn đến kết quả người dùng vào website này đều bị trì trệ như nhau. Cụm "slashdot effect" đi từ hiện tượng các trang liên mạng của nhóm "slashdot" trở nên quá phổ biến trước đây do có nhiều đường dẫn từ nhiều site khác dùng để đi ngược lại site của slashdot, dẫn đến tình trạng webserver của slashdot bị quá tải. Tình trạng quá tải này không phải do bị DoS vì các truy cập đa số đều ở dạng hợp lệ và tình trạng này không xảy ra do một hoặc nhiều người cố tình tạo ra.

-26- hex convertor, công cụ dùng để chuyển đổi giá trị từ HEX thành ASCII; một thứ đồ nghề không thể thiếu được nếu bạn thật sự muốn chuyên sâu trong lãnh vực phân tích bảo mật (security analysis). Tính chất gói tin là nền tảng của kỹ thuật phân tích bảo mật và từ kết quả phân tích này, các biện pháp khắc phục sẽ được hình thành. Có rất nhiều hex convertor cho mọi hệ điều hành. Một trong những hex convertor tôi thường dùng trên hệ điều hành Windows là HEXwrite, một freeware gọn nhẹ do David De Groot viết. Có thể tìm thấy HEXwrite ở http://bluefive.pair.com. Trên *nix tôi dùng "heme" có thể tải từ http://heme.sourceforge.net/, heme dùng thư viện curses cho việc hiển thị và nhập dữ liệu cho nên muốn dùng nó, bạn cần thư viện curses trên hệ thống. Có thêm một công cụ chuyển đổi hex rất hay viết bằng Java gọi là DataWorkshop, bạn có thể download từ http://www.dataworkshop.de/

Các bạn có thể theo dõi tiếp phần 5 tại http://hvaonline.net/hvaonline/posts/list/179.html


Điều chỉnh:
- 17/11/2004: điều chỉnh chi tiết snort là NIDS (theo yêu cầu của ngoluoc)
Sáng 12/10
Sáng nay công việc có phần thư thả hơn mọi ngày, tôi quyết định log vào server HVA để bắt đầu xem xét cẩn thận cấu hình kernel / firewall / web server xem thử cần phải làm gì để "trị" căn bệnh x-flash này. Tôi quên bẵng là firewall / proxy của công ty không cho phép đi thẳng đến cổng 22 -12-, bây giờ mới đớ người ra vì không vào HVA server được. Tôi đã "bị" kẹt vụ này đã lâu cho nên phải biến cổng SSH trên firewall riêng ở nhà từ 22 thành 443 vì firewall của hãng chỉ cho truy cập đến cổng 80 và 443 (xuyên qua proxy dùng HTTP CONNECT), nhưng đây là chuyện khác, không khéo tôi lại lạc đề ở đây. Sau vài phút trầm ngâm, tôi nảy ra ý tạo tunnel từ máy của mình đến firewall riêng ở nhà rồi mới tạo ssh connection từ máy của mình đến HVA server xuyên qua tunnel này. Biết rằng "tunnel trong tunnel" -13- chắc là chuối lắm vì chậm, nhưng không còn cách nào khác.

Sau một phút thử nghiệm, tôi thử:
Code:
$ ssh localhost -p 25250

(localhost của tôi lắng nghe trên cổng 25250 và forward thông tin đến firewall riêng của tôi ở nhà, từ đó nó mới đi đến HVA server). Ái chà, nó chạy! Hơi chậm một tí nhưng không sao cả. Tôi mở thêm một console khác cũng xuyên qua tunnel này. Tốt rồi, hai cái shell là đủ làm việc.

Tôi tìm hồ sơ mà tôi đã hí hoáy ghi xuống chằng chịt ngày hôm trước rồi rà xuyên qua nó. Đây rồi Hơn 15 ngàn request đến HVA server mỗi ngày. Tập trung khoảng 8 giờ đến 10 giờ tối VN, cao điểm là 9 giờ. Từ 8 giờ đến 10 giờ tối có độ chừng 10 ngàn đến 12 ngàn x-flash requests. Có khoảng 1 truy cập hợp lệ cho mỗi 30 giây (HTTP GET, HTTP POST) của các thành viên duyệt diễn đàn khi diễn đàn đông nhất. Cứ cho là trong 2 giờ cao điểm này có 12 ngàn x-flash requests đến HVA server, số "lẻ tẻ" còn lại không đáng kể.

(12000 requests / 120 phút) / 60 giây = 1.6 request mỗi giây

Nói về mặt tần số truy cập thì đây là một con số khá cao. Dựa trên số liệu thành viên truy nhập diễn đàn và gởi / xem bài một cách hợp thức và bình thường (lấy từ log của web server) xấp xỉ:

(200 thành viên sign-in mỗi giờ / 60 phút) / 60 giây = 0.05 request mỗi giây

So sánh hai con số trên thì tần số "truy cập" bất hợp lệ (x-flash) gấp 32 lần tần số truy cập hợp lệ. Kinh nhể?
Câu hỏi cũng như câu trả lời ở giai đoạn này trở nên quá hiển nhiên:
- hỏi: vô hiệu hoá các truy cập bất hợp lệ ra sao đây? trả lời: giới hạn các truy cập bất hợp lệ.
- hỏi: vậy giới hạn là giới hạn thế nào? trả lời: hèm... cái này thì đang tính toán đây.

Phải hình thành một công thức để tạo giá trị trung bình của một kết nối bình thường và từ đó mới có thể hình thành giới hạn hợp lý được. Vì HTTP là một giao thức có tính stateless -14- cho nên, thông tin giữa client (trình duyệt) và server (web server) thường được kết thúc càng nhanh càng tốt và connection này sẽ được tắt bỏ sau khi quy trình chuyển gởi thông tin hoàn tất. Tuy nhiên, trong quá trình chuyển đổi, giữa client và server sẽ mở thêm các connection nếu dữ liệu được truyền quá lớn hoặc cần chuyển tải thông tin nhanh chóng. Mục đích là để đẩy thông tin đi đến client (hoặc server) càng nhanh càng tốt (HTTP GET và HTTP POST). Hãy xem thử một x-flash stream xem sao. Tôi điều chỉnh hai console đã được kết nối vào HVA server cho chúng nằm song song. Trên console thứ nhất tôi "tail" web server log của HVA, trên console thứ nhì tôi chạy netstat. À ha, có vài chú x-flash đang đi vào, tôi lấy ngay IP đang hiển thị trên console theo dõi log của web server và chuyển sang console có chứa netstat. Hãy thử IP 221.132.39.253 xem sao:
Code:
[root@hvaonline httpd]# netstat -nat | grep 221.132.39.253
tcp 0 0 192.168.1.100:80 221.132.39.253:4548 SYN_RECV
tcp 0 1 192.168.1.100:80 221.132.39.253:4544 LAST_ACK
tcp 0 723 192.168.1.100:80 221.132.39.253:4545 ESTABLISHED
tcp 0 723 192.168.1.100:80 221.132.39.253:4546 ESTABLISHED
tcp 0 723 192.168.1.100:80 221.132.39.253:4547 ESTABLISHED
tcp 0 0 192.168.1.100:80 221.132.39.253:4523 TIME_WAIT
tcp 0 0 192.168.1.100:80 221.132.39.253:4526 CLOSE_WAIT
tcp 0 0 192.168.1.100:80 221.132.39.253:4527 CLOSE_WAIT
tcp 0 0 192.168.1.100:80 221.132.39.253:4494 TIME_WAIT
tcp 0 0 192.168.1.100:80 221.132.39.253:4504 TIME_WAIT
tcp 0 0 192.168.1.100:80 221.132.39.253:4505 TIME_WAIT

Cha chả, chú 221.132.39.253 này tham lam quá nhỉ? một mình chú đã có đến những 3 cái "ESTABLISHED", lại thêm 1 cái "SYN_RECV" và một mớ "CLOSE_WAIT", "TIME_WAIT". Dựa trên thông tin của hình minh hoạ ở trên thì "thái độ" tham lam này hoàn toàn phù hợp, bởi lẽ, một HTTP POST có payload đến trên 2 ngàn bytes thì nó phải đòi mở thêm connection để "đẩy" dữ kiện đến HVA server càng nhanh càng tốt mà (bạn có để ý đến chi tiết ACK-PSH của TCP segment chứa HTTP POST đã nói trong bài trước không?). Tôi tiếp tục theo dõi thì thấy chú 221.132.39.253 có đến những tám cái "ESTABLISHED" cả thảy trong suốt quá trình chú hối hả POST lên server của HVA, điều này có nghĩa là có ít nhất 8 cái SYN đã gởi đến HVA server và vì nó là legitimate request (yêu cầu truy cập hợp pháp) cho nên HVA server không hề cản mà cho chúng đi xuyên qua các bước TCP handshake rồi đi đến tình trạng "ESTABLISHED". Có thể 8 cái "ESTABLISHED" này không dành riêng cho một stream mà có ai đó cũng dùng chung cái IP này để truy cập HVA server. Có lẽ đường dẫn giữa IP này và HVA server hơi chuối, cũng có lẽ chính chú bị nghẽn vì đồng đội của chú cũng đang hối hả flood HVA, cho nên, chú phải đòi mở nhiều connection đến HVA server đến như vậy. Như vậy, tổng số socket cần mở ra cho chú 221.132.39.253 và đồng đội của chú (từ nhiều IP khác) cho tất cả các stream sẽ lớn lắm đây. Cứ cho rằng mỗi stream chứa HTTP POST mở ra 6 connections, chúng ta có:
Code:
( 12000 requests tạo ) 12000 streams x 8 sockets = 72000 connections (cho mỗi giờ).
( 72000 connection / 120 ) / 60 = 10 connections cho mỗi giây.

Ôi giời ơi, sao mà kinh thế? Cho dù SYN state thoát ra rất nhanh, cho dù ESTABLISHED state chỉ chiếm vài giây nhưng hậu quả của mớ "TIME_WAIT" và "CLOSE_WAIT" sau khi "ESTABLISHED" tắt bỏ thật sự mới khinh khủng.

Tôi càng tin tưởng vào ý định dùng giới hạn connection thay vì giới hạn packet rate -15-. Lý do hết sức đơn giản: người dùng bình thường chỉ cần 4 connections là nhiều (tôi phỏng đoán với nội dung thông thường của 1 trang trên HVA forum). Chỉ có những chú "x-flash" tham lam kia mới cần hơn 4 connections vì HTTP POST chứa payload quá lớn.

Để bảo đảm, tôi dùng chính trình duyệt của mình để thử truy cập vào một trang trên diễn đàn HVA. Hèm, hãy thử netstat trên một console xem sao:
Code:
[root@hvaonline root]# netstat -nat | grep xxx.xx.xxx.98
tcp 0 0 192.168.1.100:80 grep xxx.xx.xxx.98:9322 SYN_RECV
tcp 0 1 192.168.1.100:80 grep xxx.xx.xxx.98:9313 LAST_ACK
tcp 0 198 192.168.1.100:80 grep xxx.xx.xxx.98:9307 ESTABLISHED
tcp 0 198 192.168.1.100:80 grep xxx.xx.xxx.98:9306 ESTABLISHED
tcp 0 0 192.168.1.100:80 grep xxx.xx.xxx.98:9303 TIME_WAIT
tcp 0 0 192.168.1.100:80 grep xxx.xx.xxx.98:9288 CLOSE_WAIT
tcp 0 0 192.168.1.100:80 grep xxx.xx.xxx.98:9292 TIME_WAIT

Rất tiếc tôi phải xoá cái IP của mình và thay thế bằng xxx.xx.xxx.98 vì IP này là IP toàn thời (tôi muốn ăn ngon, ngủ yên nên không thể tiết lộ IP của mình). Trở lại câu chuyện chính, bất chấp tôi vào trang nào, bất chấp trang ấy có nhiều hay ít thông tin, tôi không hề thấy có hơn 4 connection hiện diện cho mỗi lần. Tôi cũng thử lệnh netstat ngay trên máy con của mình và xác nhận được điều này. Phần lớn là 3 connections cho mỗi lần, ngoại trừ trang nào lớn lắm thì mới thấy có 4 connections nhưng tỉ lệ này chỉ 1/100 (xấp xỉ 100 lần duyệt mới có một lần). Một chi tiết đáng nêu ra nữa là: thời gian một socket nằm ở vị trí "ESTABLISHED" chưa bao giờ lâu hơn 2 giây, phần lớn chỉ 1/2 giây hoặc 1 giây là tối đa. Điều này giúp chúng ta rút ra vài điều rất lý thú:
- mỗi trình duyệt cần tối đa 4 connection để duyệt 1 trang.
- 4 connections này không ở tình trạng "ESTABLISHED" cùng 1 lúc, chỉ tối đa 2 sockets ở tình trạng "ESTABLISHED" cho mỗi lần.

Giả sử 200 thành viên của HVA đang có mặt trên diễn đàn và cho rằng có 1/10 số lượng người đang bấm vào một số trang nào đó (đây là trường hợp cực đoan vì theo thông tin của web server log, thì trung bình mỗi 30 giây có một "GET" trong khoảng thời gian server bận rộn), và số lượng 1/10 này ít nhất là dùng 5 IP (5 proxy khác nhau) để truy cập HVA server:
(( 200 / 10) x 2 "ESTABLISHED"smilie / 1 giây = 40 "ESTABLISHED"
40 "ESTABLISHED" / 5 IP = 8 "ESTABLISHED" connections là số connection hợp lệ cho mỗi IP tại bất kì thời điểm nào.

8 "ESTABLISHED" connections tối đa cho mỗi IP một lần, con số này trông rất vừa phải. Nếu quy định cho firewall chỉ cho phép tiếp nhận tối đa 8 connections đến web server một lần thì nó đã dư sức phục vụ cho 200 thành viên có mặt trên diễn đàn cùng một lúc. Đó là chưa kể trường hợp khi một thành viên thứ nhất cần duyệt 1 trang nào đó, nếu nó bị xếp vào dạng quá connection thì trình duyệt của thành viên ấy sẽ tiếp tục gởi request đến HVA server để "thử lại", cơ hội "thử lại" lần thứ nhì này tạo connection trong phạm vi giới hạn 8 connections rất cao. Đối với người dùng bình thường, sự chậm trễ do "thử lại" này chỉ là một chậm trễ rất nhỏ. Tại sao tôi chọn tình trạng TCP "ESTABLISHED" để biểu thị cho "connection"? -16- lý do rất đơn giản là một kết nối đã đi đến tình trạng "ESTABLISHED" thì kết nối đó đã thành công, đã có thông tin qua lại giữa 2 đầu. Phải đi qua được giai đoạn TCP handshake thành công thì mới đến tình trạng "ESTABLISHED".

Cũng nên đào sâu thêm một tí về giới hạn 8 connections đã nêu ra ở trên về mặt logic. Giả sử chúng ta đã hình thành chế độ firewall được ấn định cho phép truy cập đến HVA web server từ bất cứ nơi đâu, miễn sao mỗi IP chỉ được phép dùng tối đa là 8 connections. 8 connections này có dạng na ná như một loại connection pools. Ví dụ, IP 203.162.5.100 là IP của một proxy server nào đó, đằng sau IP này có 10 người đang dùng để truy cập HVA server:
- người dùng thứ nhất chiếm 3 connections (nếu truy cập bình thường như tôi đã thử từ trình duyệt của tôi ở trên) --> "pool" còn lại 5 connections
- người dùng thứ hai chiếm 3 connections --> trong khi đó, người dùng thứ nhất đã trả lại 2 connection --> (5 + 2) - 3 = "pool" còn lại 4 connections
- ngay khi người thứ ba chiếm 3 connection nữa thì 3 connections của người dùng thứ nhất đã hoàn thành và đã trả lại 1, người dùng thứ hai trả lại 2 --> (4 + 2 + 1) - 3 = "pool" còn 4 connections

Và cứ thế mà xoay tròn. Đây là nói theo tình trạng truy cập sequential (theo chu trình) hết người này đến người khác, còn nếu tình trạng truy cập đồng thời thì sao? Cũng 10 người dùng proxy trên để truy cập HVA server:
- hai người 1 và 2 cùng truy cập một lúc, chiếm 6 connections --> "pool" còn 2 connections
- người thứ 3 và 4 kế tiếp cùng truy cập, chiếm 6 connections --> 1 và 2 ở trên trả lại ít nhất 4 connections --> (4 + 2) - 6 = "pool" còn 0 connection
- người thứ 5 và 6 cùng truy cập, chiếm 6 connections --> 1 và 2 trả lại hết các connection còn lại (2), 3 và 4 trả lại ít nhất 4 connections --> (2 + 4) - 6 = "pool" còn 0 connection
Theo phân tích trên, ngay cả trường hợp 2 người dùng cùng truy cập một lượt và dùng chung 1 IP (1 proxy server) để truy cập thì vẫn không bị ảnh hưởng gì từ chế độ cản của firewall (với ấn định tối đa 8 connections).

Nếu như kế tiếp có người thứ 7, 8 và 9 cùng truy cập thì sao? Chắc chắn là thiếu 2 connection. Tuy nhiên, anh chàng nào hơi chậm chân một tí thì trình duyệt sẽ "retry" ngay sau đó và khi "retry" packet này đụng đến server thì cơ hội có connection để vào rất cao vì khi ấy người thứ 3, 4, 5, 6 đã trả lại một loạt connection rồi. Đối với người dùng bình thường, đây là một "delay" rất nhỏ và có thể tiếp nhận được. Trên thực tế, chuyện này hiếm xảy ra. Theo thông tin đã thâu thập được từ log của web server thì cứ 30 giây mới có một xuất truy cập mới. Quy định 8 connections một lúc cho mỗi IP thật sự còn quá thư giãn so với hoàn cảnh thực tế. Tuy nhiên, cứ tạm dùng con số này làm điểm khởi đầu rồi chỉnh sửa sau vậy.

Vậy nếu HVA server bị "flood" liên tục và chiếm hết connections, làm cho người dùng bình thường không vào được thì sao? Đây là điểm đòi hỏi phải chỉnh sửa các thông số tcp/ip trên kernel để điều tiết cho thích hợp hơn. Nếu các giá trị ấn định cho tcp/ip cho phép "backlog" -17- thì vẫn giải quyết được trường hợp bị "flood". Tất nhiên là máy con truy cập sẽ bị chậm hơn nhưng vẫn còn tốt hơn là hoàn toàn bị "từ chối". Một ưu điểm rất lớn mà tôi tìm thấy được qua nhiều lần "táy máy" là trong trường hợp bị "flood", backlog queue này còn giúp cho IDS (Intrusion Detection System) kịp thời gởi gói tin xử lý đến những gói tin vi phạm với hiệu quả cao hơn-18-.

Dựa trên những điểm đã phân tích ở trên, tôi thấy rõ phương pháp dùng "connection pool" ở trên có hai điểm ưu việt hơn dùng phương pháp packet rates:
- giới hạn connection tính theo biên độ và trường độ truy cập cho phép người dùng có thể truy cập với băng thông tối đa và loại bỏ những truy cập "tham lam", không thực tế.
- với giới hạn này, nó giúp giới hạn tài nguyên cho máy chủ (và những bộ phận gắn liền với máy chủ), ví dụ như backend database chẳng hạn. Connection limit bảo đảm tối đa chỉ có 8 xuất query đến database một lần nếu những connection này đụng chạm đến database server (nên nhớ: truy nhập và lấy dữ kiện từ database tốn tài nguyên hơn bất cứ giai đoạn nào khác trên hệ thống).

Trong khi đó, packet rate giới hạn số packets trong một đơn vị thời gian nào đó, cái này chỉ làm chậm mọi quy trình lại nhưng không áp đặt một giới hạn nào rõ ràng. Nếu dùng packet rate, số xuất truy cập vào database có thể lên đến số lượng đã áp đặt trên chính cấu hình database mà thôi và đây là điều rất kẹt vì rất tốn kém tài nguyên của máy chủ. Đến một mức độ nào đó, đường truyền sẽ bị dung hoà (saturated) và các client hợp pháp sẽ vào được nhưng cực kỳ chậm nhưng để đạt tới mức độ này, ít nhất đường truyền dùng để tấn công phải hơn đường truyền của máy chủ HVA ít nhất là 3 lần. Giới hạn connection bảo đảm một điều tối quan trọng, cho dù máy chủ bị "flood" cỡ nào cũng không thể "giết" được nó.

Được rồi, hãy quyết định khai triển hướng giới hạn connection trước để cắt bỏ phần lớn khối 20 connections / 1 giây của các con bọ "x-flash" kia trước rồi tiếp tục khai triển bước "triệt tiêu" chúng hoàn toàn sau.

Chuyển sang console thứ nhất đã được kết nối vào HVA server, tôi chạy một loạt lệnh để kiểm tra:
Code:
# lsmod

Hèm... không thấy mấy cái modules mình muốn, hẳn là như vậy vì module mình muốn đâu nằm trong "base modules" của kernel.
Code:
# ls /proc/sys/net/ipv4/netfilter

Hèm... quả thật mấy cái modules mình muốn chưa hề có trong kernel, cũng nên xác định cho rõ.
Code:
# sysctl -a | grep net

Whoa... đa số là giá trị mặc định, chi tiết này phải ghi xuống để chỉnh lại sau, không thì quên nữa.
Code:
# iptables -L -v | more

Nhìn ok nhưng... còn thắt lại được nhiều lắm.

Chà chà, lão JAL và mấy lão BQT "hiền" quá, mấy cái rules này của firewall không dễ để "đột phá" nhưng nó có quá ít ảnh hưởng đến mớ x-flash quái đản kia. "Packet rate" cũng đã áp đặt nhưng với tần số 1.6 request / 1 giây thì.... bó tay, hơn nữa, áp đặt này chỉ làm cho bà con thành viên truy cập vào diễn đàn chậm hơn. Kernel hiện tại cần thiết lập vài modules quan trọng để thực sự giới hạn truy cập. Tôi chưa muốn xem xét các tầng cao hơn vì kế hoạch mà tôi đã hình thành trong đầu là: thắt từ dưới lên và hiện nay tôi đang ở tầng dưới cùng trong các tầng giao thức, những tầng kia sẽ xét sau.

Tôi gởi ngay cho JAL một PM về việc tái biên dịch kernel để thêm vài modules quan trọng cho kernel cũng như loại bỏ nhiều modules không cần thiết. Mười lăm phút trôi qua, rồi một giờ trôi qua. Chà, sao không thấy tăm hơi lão JAL đâu nhỉ? Tôi quyết định bắt tay vào thực hiện ý định của mình rồi sẽ thông báo để lão tái khởi động máy sau vậy.

Tôi dùng wget, tiện ích tôi rất ưa thích để lấy mã nguồn của kernel và các bản vá cần thiết. Trong khi wget tải những thứ lỉnh kỉnh kia về, tôi vi ngay hồ sơ cấu hình biên dịch của kernel (tiết kiệm thời gian mà lị). Hèm.... mười lăm phút đầy những Y, N và M trên một hồ sơ cấu hình biên dịch của kernel, hơi oải... nhưng biết sao hơn? Băng thông khá tốt nên mới sau vài phút thì những thứ tôi cần đã được tải hết về máy. Tôi xả nén mã nguồn kernel, vá và bắt tay vào chuyện biên dịch.

Tôi rà kỹ qua hồ sơ cấu hình biên dịch kernel một lần cuối... ok, mọi chuyện đâu vào đó. Một, hai, ba... chạy. Hơn ba mươi phút trôi qua với hàng loạt thông điệp chạy vi vút trên màn hình. Kinh khủng, kinh khủng, kernel được biên dịch xong dưới ba mươi lăm phút, đúng là dual CPU có khác, đây là không kể đến hoàn cảnh server hiện nay đang phải dùng sức để đối phó với đám loạn quân "x-flash" kia. Kernel đã xong nhưng vẫn chưa thấy tăm hơi lão JAL đâu. Thôi vậy, để xem thêm thử có gì khác cần phải làm nhưng chắc để lúc khác, đã đến lúc phải giải quyết vài công chuyện ở sở không thì bê trễ cả ra.

Sáng 13/10
Đang trên tàu lửa trên đường đi làm, tôi trầm ngâm lượt qua các chi tiết đã phân tích hôm qua. Vẫn chưa thấy JAL hồi đáp, cha chả, lão này đi chơi đâu mà bặt vô âm tín vậy nhỉ? Tôi chợt nhớ là kernel đã tái biên dịch xong nhưng firewall rules mới chưa hề có một mảnh. Tôi mở laptop lên, phóng ngay chú "vim" lên màn hình và bắt đầu gõ.

Tôi khá chắc là HVA cần dùng bấy nhiêu dịch vụ nên tôi quyết định dùng kiểu block function (hàm theo nhóm) để hình thành các phần logic của firewall rules. Ba mươi lăm phút trôi qua, chà tôi phải đổi sang chuyến tàu thứ nhì (tôi cần phải đổi tàu 2 lần mới đến sở làm). Nhìn xuyên qua đoạn script, tôi khá hài lòng vì nó đã gần như hoàn tất, chỉ cần điểm xuyết thêm, thắt chặt dăm ba điểm và tạo một số thông điệp thông báo khi chạy firewall script (để lão nào chạy nó thì còn biết chuyện gì xảy ra). Rất tiếc tôi không thể trình bày chi tiết firewall rules này có những gì ở đây vì lý do... bảo mật.

Lên chuyến tàu thứ nhì, tôi mở laptop ra và tiếp tục hoàn tất những thứ đã dự định trong đầu. Tôi ngẩng lên nhìn đồng hồ, chà! còn đến 15 phút nữa mới đến sở. Tôi quyết định rà lại từng dòng một trên cái firewall script. Mèn... tưởng đã hoàn chỉnh, hoá ra rà qua lại "nẻ" ra lỗi, rà lại cũng "nẻ" ra lỗi. Còn 10 phút... tôi nảy ra ý định tạo thêm một lớp safe-guard (bảo kê) cho mỗi truy cập đến dịch vụ đã được cho phép. Xong xuôi, tôi khá hài lòng vì sáu mươi phút đồng hồ trôi qua khá bổ ích. Thôi được, thử upload cái script này lên và chạy thử trên HVA server xem sao. Nếu có gì kẹt thì "đì bấc" tại chỗ chớ làm sao hơn được?

Sau mấy giờ đồng hồ liên tục làm việc, tôi đã hoàn tất cả đống công việc. Giờ này lão JAL bên Nhật chắc cũng đã có mặt ở sở, để xem lão có hồi báo gì không. Tôi log vào diễn đàn, khè khè "Bạn có 3 PM", chắc là của lão JAL chớ không ai vào đây. Quả thật, lão JAL "mê" chơi đâu quá nên tối hôm qua về trễ. Tôi upload cái firewall script lên HVA server, xem xét mọi thứ một lần nữa. Rồi, gởi cho JAL một cái PM thông báo chuyện khởi động lại server.

Lão JAL hồi đáp trong tích tắc. Lão cho biết sẽ khởi động server lúc "vắng vẻ" một tí. Mèn.... sau vài phút cái SSH console của tôi chợt báo "socket error", lão JAL này nói "đợi khi nào server vắng vẻ một tí rồi restart" vậy mà làm liền vậy sao cà? Quả thật lão "làm liền". Chưa đầy 2 phút sau, tôi hối hả thử log vào HVA server, vào được ngay! Tôi phóng ngay mấy cái lệnh:
Code:
# less /var/log/boot
# lsmod
# /usr/local/sbin/iptables -L -v | more
# tail -f /var/log/messages

"I can't believe it", tôi thốt lên một mình. "First hit wonder!" tôi lẩm nhẩm tiếp. Firewall chạy như ý muốn ngay lần đầu tiên. Mọi chuyện đều ổn từ kernel lên tới firewall và các dịch vụ khác (Vậy mà ngày hôm ấy lão thần bài phát hiện ngay ra một lỗi, lỗi gì vậy lão thần bài? ). Nhìn cái "đuôi"
Code:
# tail -f /var/log/messages

tôi muốn ngộp thở:
Code:
Oct 13 07:12:44 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=221.132.49.131 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=113 ID=22369 DF PROTO=TCP SPT=50257 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:44 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=221.132.49.131 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=113 ID=22379 DF PROTO=TCP SPT=50258 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:44 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.113.160.94 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=111 ID=7049 DF PROTO=TCP SPT=2370 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:44 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=221.132.49.131 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=113 ID=22381 DF PROTO=TCP SPT=50257 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:45 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=221.132.49.131 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=113 ID=22382 DF PROTO=TCP SPT=50258 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:45 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.113.160.94 DST=192.168.1.100 LEN=48 TOS=0x00
PREC=0x00 TTL=111 ID=7070 DF PROTO=TCP SPT=2370 DPT=80 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 13 07:12:45 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.113.135.196 DST=192.168.1.100 LEN=48 TOS=0x0
0 PREC=0x00 TTL=110 ID=43299 PROTO=TCP SPT=42913 DPT=80 WINDOW=16384 RES=0x00 SYN URGP=0
Oct 13 07:12:45 hvaonline kernel: OVERCONNLIMIT: IN=eth0 OUT= SRC=203.113.135.196 DST=192.168.1.100 LEN=48 TOS=0x0
0 PREC=0x00 TTL=110 ID=43764 PROTO=TCP SPT=42913 DPT=80 WINDOW=16384 RES=0x00 SYN URGP=0

Vâng vâng và vâng vâng..... Chuyện gì đây? Hồi sau sẽ rõ smilie

Các bạn có thể theo dõi tiếp phần 4 tại http://hvaonline.net/hvaonline/posts/list/178.html

Chú thích:
-13- Bạn có thể tạo secure tunnel (đường ống) từ máy của mình đến một máy chủ nào đó bằng cách dùng SSH. Bên trong tunnel này, các thông tin chuyển lưu hoàn toàn được mã hoá. Tuy chậm nhưng khá an toàn nếu dùng SSH2. Nếu thích bạn nên thử đọc tài liệu và tải software từ openssh ở http://www.openssh.org.

-14- HTTP là một giao thức stateless, sau khi thông tin giữa hai đầu server và client hoàn tất, connection này được tắt bỏ.

-15- Giới hạn connection là giới hạn bao nhiêu sockets được mở ra để phục vụ một IP nào đó. Ví dụ, tối đa 4 connections từ một IP nào đó. Nếu IP này "đòi" mở thêm 1 connection thứ 5 thì connection này bị loại bỏ.
Giới hạn packet rates là giới hạn số packet được truyền tải trong một đơn vị thời gian nào đó. Ví dụ: giới hạn 100 packets / 1 giây từ một IP nào đó chỉ cho phép server nhận tối đa là 100 packets 1 giây, packet thứ 101 trở đi sẽ bị loại bỏ.

-16-Tôi dùng thuật ngữ "connection" ở đây là để chỉ chung cho các giai đoạn: SYN từ client, SYN-ACK từ HVA server, ACK-ACK từ hai đầu client và HVA server và sau đó là ACK-PSH hay bất cứ gì khác từ client cho đến khi "ESTABLISHED" trở thành "TIME_WAIT". Giới hạn connection ở đây thật sự là giới hạn SYN. ESTABLISHED chỉ dùng để biểu thị connection đã hình thành một cách hợp lệ và đúng quy định mà thôi. Nếu truy cập từ cùng một IP mà quá giới hạn 8 "connections", có nghĩa là SYN vẫn được gởi nhưng nếu hiện đã có 8 ESTABLISHED connections thì SYN đứng đó chờ hoặc SYN bị huỷ. ESTABLISHED dùng để đo lường số connection hiệu hữu và SYN dùng để cản (hoặc cho phép) các truy cập tiếp theo dựa trên số connection đã hiện hữu

-17- "backog" là số lượng công việc bị dồn ứ lại. Với TCP connections, ví dụ nếu chỉ định 100 "backlog" chẳng hạn thì gói SYN thứ 101 trở đi sẽ bị hủy bỏ, dẫn đến tình trạng người dùng không truy cập được. Nếu chỉnh định 10000 "backlog" thì vẫn tạo cơ hội cho các truy cập đang đợi có thể vào thay vì bị huỷ.

-18- Hầu hết các IDS hiện đại đều có khả năng tác ứng đến các gói tin mang tính vi phạm. Riêng trong trường hợp này, tôi dùng snort vì nó miễn phí. Nó có thể gởi nhiều gói RST đến cả client lẫn server cùng một lúc để "xé" ngang đường nối hiện hữu giữa client và server.

Cập nhật:
10/11/2004: chỉnh sửa các chi tiết tính toán bị sai lẫn do mrro tìm thấy trong bài tường trình và thêm chi tiết giải thích cho khái niệm "connection".

Phân tích (tiếp theo)

Tối 11/10
Tôi gởi PM cho lão JAL để "hít" thêm ít gói tin, lần này tôi nắm chắc phải có vài megabytes packets để nghịch. Không lâu sau đó, tôi nhận được hồi đáp từ JAL thông báo các mảnh packets đã có sẵn trên server. Tôi log vào HVA server và tải chúng xuống. Hăm hở mở đoạn "hit" thứ nhất, tôi rà xuyên qua trọn bộ các gói tin bắt được trong nhóm thứ nhất để tìm một dấu hiệu nổi bật và những dấu hiệu nào có liên quan đến đoạn payload của HTTP POST ở trên. Quá nhiều! có quá nhiều "stream" -7- từ nhiều nguồn khác nhau như mang cùng một đặc tính. Thử xem một "stream" do client IP là 203.210.233.28, dùng proxy server là 203.162.3.148 để "POST" vào server của HVA:
Code:
POST /forum/ HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Content-Type: application/x-www-form-urlencoded
Content-Length: 2387
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Cookie: session_id=433ab8bcc276414badb0e83891bbb9a6
Host: www.quangvinhonline.info
X-Forwarded-For: 203.210.233.28
Connection: Keep-Alive
Cache-Control: no-cache, bypass-client=203.210.233.28
hotlinks=Offical%2Ecom&comdoss=attack&port=80&url1=http%3A%2F%2Fwww%2Ehvaonline%2Enet%2Fforum%2F&url2=http%3A%2F%2Fwww%2Ehvaonline%2Enet%2Fforum
%2F&http%3A%2F%2Fwww%2Exxx%2Ecom%2FForum%2Findex%2Ephp=&act=Reg&code=02&coppa%5Fuser=0&PassWord=123456&PassWord%5FCheck=123456&agree=1&imie=Only
+U&nazwisko=Frem\
&kraj=AG&adres1=Hien+kem&adres2=&miasto=Hiam+city&kod=51451&HT=Hacker%5FVietNam&EM=gianghomang%40yahoo%2Ecom&PW=123456&rPW=123456
&DangKy=nananaBD&telefon%5Fa=574&telefon=52415487&mail1=jand%40yahoo%2Ecom&mail2=jand%40yahoo%2Ecom&pass1=jand%40yahoo%2Ecom&pass2=jand%40yahoo
%2Ecom&ret=0&question=jand%40yahoo%2Ecom&answer=jand%40&s=&do=addmember&url=http%3A%2F%2F64%2E207%2E189%2E5&password%5Fmd5=&passwordconfirm%5Fmd5
=&passwordconfirm=123456&referrername=Nokia&timezoneoffset=0&dst=2&options%5Badminemail%5D=1&options%5Bshowemail%5D=1%24%23%24%40%24%5E%24%40%23
%21%40%23%24%21%40%23%24%40%21&1+42A3KCT%2ENET%2E+%0D%0A2+BAODIENTUVN%2ECOM%2E+%0D%0A3+CANDYKID%2ENET%2E+%0D%0A4+CVK3N%2ECOM%2E+%0D%0A5+CVK3N%2ENET
%2E+%0D%0A6+DIEMTUYENSINH%2ECOM%2E+%0D%0A7+DNSTBVN%2ENET%2E+%0D%0A8+HACKER4A%2ECOM%2E+%0D%0A9+HOAIANH%2ECOM%2E+%0D%0A10+LAMHONGHUYEN%2ECOM%2E+%0D
%0A11+LAMHONGHUYEN%2EINFO%2E+%0D%0A12+LAMHONGHUYEN%2ENET%2E+%0D%0A13+MUSIC4VN%2ECOM%2E+%0D%0A14+NVBH7%2ECOM%2E+%0D%0A15+THANGKCT%2ENET%2E+%0D
%0A16+TINHBANVIETNAM%2EORG%2E+%0D%0A17+TUOITRE%2EINFO%2E+%0D%0A18+VIETSTAR%2EINFO%2E+%0D%0A=%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0D
%0A1+4RTRITHUC%2ECOM%2E+%0D%0A2+ANHEMCLUB%2EORG%2E+%0D%0A3+r u crazy???%2ECOM%2E+%0D%0A4+BARIA%2DCLUB%2ECOM%2E+%0D%0A5+CANHHAO%2ECOM\
%2E+%0D%0A6+DONGTRANG
%2ECOM%2E+%0D%0A7+HOAHOCBKHN%2ECOM%2E+%0D%0A8+INTELNEW%2ECOM%2E+%0D%0A9+KHUCTINHCA%2ECOM%2E+%0D%0A10+LAONHAO%2ENET%2E+%0D%0A11+LYSOCHANTHUYEN%2EORG
%2E+%0D%0A12+NHANVAN%2EORG%2E+%0D%0A13+NHIPDIEUVN%2ECOM%2E+%0D%0A14+NHUNGANHSAOBANG%2ECOM%2E+%0D%0A15+NTQUOCKHAI%2ECOM%2E+%0D%0A16+PHAMLUYEN%2ENET
%2E+%0D%0A17+RADUONG%2ENET%2E+%0D%0A18+SAIGONMARK%2ECOM%2E+%0D%0A19+TEMP4YOU%2ENET%2E+%0D%0A20+THANHKY%2ENET%2E+%0D%0A21+TINHCAVN%2ECOM%2E+%0D
%0A22+TRUCXANHVN%2ENET%2E+%0D%0A23+TUOITRETAIHOA%2ECOM%2E+%0D%0A24+TUTHIENONLINE%2ECOM%2E+%0D%0A25+VUIVOINET%2ECOM%2E+%0D%0A26+XLUKE%2ENET%2E+%0D
%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D&UserName=782313927&EmailAddress=112156084%40&EmailAddress%5Ftwo=112156084\
%40&user=782313927&Email=112156084
%40&emailconfirm=112156084%40&timeonl=2847

Uh oh! Cái gì đây? Thử decode xem nó chứa gì, mấy cái %2, %3 xem chỉ tổ... mù mắt:
Code:
POST /forum/ HTTP/1.1
Accept: */*
x-flash-version: 7,0,19,0
Content-Type: application/x-www-form-urlencoded
Content-Length: 2387
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Cookie: session_id=433ab8bcc276414badb0e83891bbb9a6
Host: www.quangvinhonline.info
X-Forwarded-For: 203.210.233.28
Connection: Keep-Alive
Cache-Control: no-cache, bypass-client=203.210.233.28
hotlinks=Offical.com&comdoss=attack&port=80&url1=/forum/&url2=/forum/
&http://www.xxx.com/Forum/index.php=&act=Reg&code=02&coppa_user=0&PassWord=123456&PassWord_Check=123456&agree=1&imie=Only U&nazwisko=Frem\
&kraj=AG&adres1=Hien kem&adres2=&miasto=Hiam city&kod=51451&HT=Hacker_VietNam&EM=gianghomang@yahoo.com&PW=123456&rPW=123456&DangKy=nananaBD\
&telefon_a=574&telefon=52415487
&mail1=jand@yahoo.com&mail2=jand@yahoo.com&pass1=jand@yahoo.com&pass2=jand@yahoo.com&ret=0&question=jand@yahoo.com&answer=jand@
&s=&do=addmember&url=http://64.207.189.5&password_md5=&passwordconfirm_md5=&passwordconfirm=123456&referrername=Nokia&timezoneoffset=0
&dst=2&options[adminemail]=1&options[showemail]=1$#$@$^$@#!@#$!@#$@!&1 42A3KCT.NET. 2 BAODIENTUVN.COM. 3 CANDYKID.NET. 4 CVK3N.COM. \
5 CVK3N.NET. 6 DIEMTUYENSINH.COM. 7 DNSTBVN.NET. 8 HACKER4A.COM. 9 HOAIANH.COM. 10 LAMHONGHUYEN.COM. 11 LAMHONGHUYEN.INFO. 12 LAMHONGHUYEN.NET. \
13 MUSIC4VN.COM. 14 NVBH7.COM. 15 THANGKCT.NET. 16 TINHBANVIETNAM.ORG. 17 TUOITRE.INFO. 18 VIETSTAR.INFO. ==================1 4RTRITHUC.COM. \
2 ANHEMCLUB.ORG. 3 r u crazy???.COM. 4 BARIA-CLUB.COM. 5 CANHHAO.COM. 6 DONGTRANG.COM. 7 HOAHOCBKHN.COM. 8 INTELNEW.COM. 9 KHUCTINHCA.COM. \
10 LAONHAO.NET. 11 LYSOCHANTHUYEN.ORG. 12 NHANVAN.ORG. 13 NHIPDIEUVN.COM. 14 NHUNGANHSAOBANG.COM. 15 NTQUOCKHAI.COM. 16 PHAMLUYEN.NET. \
17 RADUONG.NET. 18 SAIGONMARK.COM. 19 TEMP4YOU.NET. 20 THANHKY.NET. 21 TINHCAVN.COM. 22 TRUCXANHVN.NET. 23 TUOITRETAIHOA.COM. 24 TUTHIENONLINE.COM. \
25 VUIVOINET.COM. 26 XLUKE.NET. ====================&UserName=782313927&EmailAddress=112156084@
&EmailAddress_two=112156084@&user=782313927&Email=112156084@&emailconfirm=112156084@&timeonl=2847

Cái gì nổi bật trong hai đoạn trên? Đúng rồi: x-flash. Tại sao lại có chuyện dùng flash để "duyệt" HVA forum? Ngoài x-flash còn có những gì nổi bật? Có quá nhiều điểm nổi bật trong payload ở trên. Tuy nhiên, ứng dụng ra sao là yếu tố quyết định phải chọn những gì và ở đâu trong payload.

Hãy thử "dựng" lại các gói tin thuộc một "stream" tương tự để xét xem chúng có gì đặc biệt về mặt chuyển gởi và chuyển nhận gói tin:


Những điểm được khoanh lại ở trên là những điểm được xem là "bắt mắt" nhất. Trước tiên chúng ta thấy các packets này xử dụng đúng TCP sequence, gởi SYN, rồi gởi ACK, sau đó tiếp tục gởi tới ACK,PSH có encapsulated -8- HTTP trong đó. Sở dĩ chúng ta có 2 mảnh "continuation" vì content-length có chiều dài đến 2205 bytes, quá lớn để khít vào một MTU -9- và nó phải gói trong gói tin tcp ACK,PSH vì nó muốn 2 mảng thông tin này đến HVA server càng nhanh càng tốt (càng nhanh thì HVA server càng mau chết). Sau cùng là cái đuôi RST (hiển thị trên hình là [TCP ZeroWindow].

Nhìn xuyên qua thì mọi sự có vẻ như hợp lệ nhưng xét cho kỹ thì tại sao cái "stream" này lại kết thúc bằng RST thay vì FIN? Hơn nữa, sau khi hoàn tất mảng "continuation" thứ nhì thuộc sequence 240 (xem cột trong cùng bên tay trái), mãi đến sequence thứ 1154 mới gởi RST packet đến HVA server? Điều này có nghĩa HVA server phải "ngóng chờ" cho đến khi nguồn tin từ IP này tiếp tục ra hiệu, nếu không thì server sẽ đợi cho đến khi "time out". Đợi đến lúc "time out" hay đợi đến sau gần 1000 sequence khác rồi mới gởi 1 cái RST thì cũng không khác gì nhiều cho lắm (đặc biệt kernel trên HVA server được chỉnh sẵn TCP time out khá ngắn). Đây có thể là ứng dụng flash "chuối chiên" vì tôi không tin rằng người tạo flash có thể ấn định khi nào nên gởi FIN hay nên khởi RST? Cũng có thể nguồn nguyên thủy (máy nào đó) chạy cái flash này xuyên qua đường dẫn khá tệ nên các TCP sequences cách nhau khá xa? Có thể kẻ đã tạo ra mấy cái flash này cũng chẳng thèm để ý đến những "phương hại" tinh vi thế này, miễn sao dội HVA server càng nhiều, càng tốt thôi.

Sau khi xem xét hàng loạt các stream có lồng mảng "HTTP POST" và hình thành các số liệu thống kê, tôi ghi lại các giá trị HEX -10- của một số chi tiết nổi bật, bất biến và vị trí offset (khung màu đỏ trên hình) của chúng từ TCP "stream" ở trên để dành cho bước ngăn chặn sau này. Tôi không dành quá nhiều thời gian để tẳn mẳng nội dung của các POST payload ở trên nhưng nhìn sơ qua thì thấy "chủ nhân" của mớ x-flash này để lộ quá nhiều chi tiết có thể giúp truy danh tánh. Đây lại là một chuyện khác, tôi thật sự không hứng thú tìm hiểu "chủ nhân" mớ x-flash này là ai.

Tôi log vào HVA server lần nữa và "grep" -11- xuyên qua vài cái log cũ của web server chạy trên HVA. Ái chà, "bệnh" x-flash này đã xảy ra cũng đã nhiều ngày nhưng HVA không "chết" nổi, chỉ chậm lại ở những lúc cao điểm, chứng tỏ chiến thuật x-flash này không mấy hữu hiệu? Hay vì "chủ nhân" của mớ x-flash này chỉ cài chúng đâu đó rồi.... "sống chết mặc bây"? Tôi tiếp tục đào sâu trong mớ log đã cũ của HVA để hình thành vài con số thống kê. Sau hơn một giờ "chọc ngoáy" các log files và ghi chú thành một trang notepad chi chít chi tiết, tôi hình thành được khá nhiều thông tin hết sức lý thú, Những thông tin này khá phức tạp và tế nhị nên không thể công bố rộng rãi cho độc giả. Tôi đành phải tạm tóm lược như sau:
- căn bệnh x-flash này đã xảy ra nhiều tháng.
- trung bình mỗi ngày có khoảng +- 15,000 requests dùng x-flash vào HVA forum.
- các request này thường tập trung từ khoảng 6 giờ chiều cho đến khuya giờ VN.
- cao điểm các request này "đụng" vào HVA là khoảng 9 giờ tối.

Có thể rút tỉa được điều gì thuộc phương diện kỹ thuật từ những thông tin trên nhỉ?
- đám "x-flash" này có thể được xếp loại vào dạng DDoS vì chúng đến từ nhiều nguồn (IP) khác nhau cùng một lúc.
- chúng có cùng đặc tính (nói về mặt giao thức, kích thước và thái độ).
- có một số "stream" đi vào có cùng tính chất như các x-flash phá hoại này nhưng không hề mang "x-flash" trong header của HTTP POST, có lẽ chúng được một proxy server nào đó "lột" mất cái header?
- chúng hoàn toàn hợp lệ về mặt giao thức cho nên cấu hình server của HVA tiếp nhận chúng với "vòng tay rộng mở".
- và dường như chúng được gởi đến từ các máy con trong thời điểm duyệt Internet cao độ trong ngày.

Với những nhận định trên, tôi tin rằng các "con" x-flash kia không được chủ nhân điều tác theo kiểu master / zombies thông thường mà đây có thể là cách cài các "x-flash" trên những diễn đàn tương tự như HVA. Khi người dùng duyệt đúng trang web nào đó có gắn những "x-flash" này, chúng được dùng làm phương tiện để gởi request đến HVA server. Số lượng người truy cập các diễn đàn ấy càng nhiều thì số lượng request gởi đến HVA càng cao. Vậy, HVA phải đối phó ra sao?
- cản? cản ai? cản những gì? nếu phải cản thì chỉ có thể cản một mớ IP của các gateway hoặc các proxy server đi từ VN (là chủ yếu) và nếu vậy thì chuyện gì xảy ra? Đúng vậy! "x-flash" đã "deny service" thành công vì nó buộc HVA phải cản luôn những "kẻ vô can" trong cuộc chơi quái dị này.
- không cản? thì "căn bệnh" này cứ đeo đuổi mãi sao? và nếu cứ để như vậy thì chuyện gì xảy ra? tất nhiên là HVA server không thể "chết" nổi nhưng ảnh hưởng đến các thành viên (và khách) truy cập đến diễn đàn HVA là ảnh hưởng tiêu cực (chậm, đứt quãng, phí tài nguyên, phí băng thông...).

Có khá đầy đủ các dữ kiện cần thiết, tôi bắt đầu hình thành chiến thuật "trị" nhưng "trị" thế nào thì xin độc giả đón xem phần kế tiếp.

Các bạn có thể theo dõi tiếp phần 3 tại http://hvaonline.net/hvaonline/posts/list/177.html

Chú thích:
-7- stream là một chuỗi tin khởi đầu từ SYN và kết thúc ở FIN theo đúng quy trình. Một stream chứa các gói tin ra / vào từ khi mở connection đến khi connection được tắt bỏ (vì lý do gì đó).
-8- encapsulated là "lồng" gói tin thuộc tầng trên vào gói tin thuộc tầng dưới (HTTP là giao thức tầng application và được lồng vào TCP là giao thức tầng transport)
-9- MTU là Maximum Transmission Unit, giá trị quy định tối đa có bao nhiêu bytes được chứa trong một mảng tin bao gồm header, thông tin trải từ link layer trở lên. Nếu gói tin quá giới hạn MTU thì nó phải được bẻ nhỏ ra thành nhiều mảng (fragmentation). Ethernet có MTU là 1500 bytes tối đa cho mỗi mảng, IEEE 802.2/802.3 có MTU là 1492 tối đa cho mỗi mảng, FDDI (optic fibre) có MTU là 4352 và tối đa MTU có thể đạt được là 65535 cho Hyperchannel. Xem thêm chi tiết từ một cuốn sách chuyên về TCP/IP.
-10- HEX là viết tắt của hexadecimal.
-11- grep là một lệnh hết sức phổ biến trên *nix dùng để tìm một đoạn chữ có dạng mẫu nào đó trong một hồ sơ nào đó (chú thích này dành cho những ai chưa hề dùng *nix).
Dấu hiệu
Mấy tuần lễ gần đây, đột nhiên lượng tải trên máy chủ HVA tăng vọt trong khi số lượng thành viên chính thức truy nhập diễn đàn vẫn ở mức bình thường. DoS? hay DDoS? Lượng tải này tăng vọt khá đều đặn vài giờ trong mỗi ngày. Lượng thành viên gia tăng nên có quá nhiều người cùng truy cập? không phải. HVA đang có đề tài gì hấp dẫn nên thiên hạ ùn ùn kéo vào? cũng không phải.

Dấu vết
Tôi nhận công tác điều tra và xử lý tình trạng bất bình thường này, trong đầu đã phần nào đoán sự thể do DoS. Khuya ngày 10 tháng 10, tôi log vào server của HVA và tạo ra vài console, mở ra vài cái đuôi -1-, làm một ấm trà và ngồi đó nhâm nhi... một mình. Không cần phải đợi lâu, hàng loạt thông tin từ log của web server hiện lên màn hình với một số chi tiết rất lý thú:
Code:
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
80.170.198.46 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1617 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)"
81.66.147.0 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1615 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1614 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
24.17.150.114 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1504 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1614 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
81.66.147.0 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1615 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
80.170.198.46 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1617 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1614 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
24.17.150.114 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1504 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3"
81.66.147.0 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1615 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1614 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
80.170.198.46 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1617 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 1.0.3705)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
211.199.192.157 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; iebar)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1619 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
203.162.3.148 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1614 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"
81.66.147.0 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.1" 200 1615 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
210.245.31.246 - - [10/Oct/2004:06:57:19 -0400] "POST /forum/ HTTP/1.0" 200 1618 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
24.17.150.114 - - [10/Oct/2004:06:57:20 -0400] "POST /forum/ HTTP/1.1" 200 1504 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3"

Chà, chẳng lẽ thành viên "hối hả" kéo vào diễn đàn và "POST" bài nhiều đến vậy sao? hai mươi lăm cái "POST" trong một giây từ một vài IP? Cứ cho là hợp lệ vì thành viên ở VN đi ra Internet, qua cùng một cửa ngõ -2- là chuyện bình thường. Nhưng, hẵng đã, vừa rồi lại có một chùm đến hơn năm mươi cái "POST" đi đến trong một giây, cũng từ các IP như trên. Bất thường hay bất tường?

Tôi để yên mấy "cái đuôi" chạy trên mấy console và mở trình duyệt của mình lên, thử log vào HVA bằng nickname và password của tôi để xem thử "thái độ" POST từ máy của tôi có tương tự như những cái POST tôi nhận được vài chục giây trước đây (xác thực là bạn của nghề phân tích). Cha chả, cái POST của tôi nhìn hợp lệ hơn nhiều:
Code:
xxx.xx.xxx.98 - - [10/Oct/2004:07:11:25 +0900] "POST /forum/act_Login_CODE_01.html HTTP/1.0" 200 7405 "/forum/act_Login_CODE_00.html" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510"

Tôi thử mở "cái đuôi" của firewall log trên server xem có gì hấp dẫn không. Chà, log của web server vẫn "POST" vào ầm ầm nhưng firewall log thì vẫn im ắng như đỉnh Himalaya. Thôi rồi, chắc đây là một "kiểu chơi" rất hợp lệ nên firewall cho phép chúng vào thả cửa. Tôi gởi nhanh một PM đến JAL, nhờ lão phóng cái sniffer lên để "hít" -3- một ít gói tin và lưu lại một nơi thích hợp dùm tôi. Đêm đã khuya, tôi phải đi ngủ để mai còn đi làm. Sáng mai sẽ copy mớ gói tin đã được lưu và sẽ phân tích xem sự thể ra sao.

Phân tích

Ngày 11/10
Trên tàu lửa đến sở làm, tôi hăm hở mở laptop ra và bắt tay vào xem xét thông tin "bắt" được tối hôm qua. Chuyện đầu tiên đập vào mắt tôi là kích thước hồ sơ đã sniff, chà, sao nó bé tí tẹo vậy nhỉ? Sáng nay lúc tôi log vào HVA server để copy hồ sơ này, tôi đã không để ý đến kích thước (vì cứ nghĩ nó phải ít nhất là vài megabytes), tôi chỉ chạy lệnh scp và bỏ đó rồi đi thay đồ đi làm. Lúc này mới nhận ra là nó bé tí tẹo, không biết có gì trong này.

Tôi dùng Ethereal mở hồ sơ này ra, và.... đúng như dự phỏng, Ethereal phàn nàn "stream not completed". Tôi bật cười và tự nhủ: "chà, chắc lão JAL sợ nó sniff lâu quá thành một hồ sơ khổng tượng nên chỉ sniff một, hai giây rồi tắt liền". Thông tin "bắt" được từ sniffer quá ít, chỉ vỏn vẹn hơn mười dòng, trong đó có được một cái SYN -4-, một cái ACK,PSH từ một segment khác, một cái HTTP (POST) cộng thêm vài cái "continuation" từ các segment trước và sau cái SYN ở trên không thấy gì đi theo.

Xếp laptop lại, tôi trầm ngâm vài phút, có vài chi tiết cần xem lại trong mớ packets ngắn ngủi mà lão JAL đã cung cấp. Tôi lại mở laptop ra và đi xuyên qua mười mấy mảnh packets rời rạc. Không thể "gom" các packets này thành một stream hoàn chỉnh, tôi đành xem xét từng mảnh một lần nữa. Điểm lý thú đập ngay vào mắt tôi khi dò đến http packet chứa mảng đầu của phần "POST". Cha chả, POST cái gì mà lắm thế?
- payload -5- của "POST" có đến 2205 bytes?
- đoạn đầu của mảnh "POST" này có thông tin:
Code:
hotlinks=Offical%2Ecom&comdoss=attack&port=80&url1=http%3A%2F%2Fhvaonline%2Enet%3A80&url2=http%3A%2F%2Fhvaonline%2Enet%3A80%2Fforum%2F&http%3A%2F%2Fwww%2Exxx%2Ecom%2FForum%2Findex%2Ephp=&act=Reg&CODE=02&coppa%5Fuser=0&PassWo

Lý thú nhỉ, lý thú nhưng cũng chưa có gì rõ ràng cho lắm. Tôi hơi ngạc nhiên là tại sao mấy lão trên HVA lại để yên những http header và payload có dính ngổn ngang các "chú" ampersand -6-. Có lẽ mấy lão cho phép vì đây là phần cần thiết cho forum? Tôi chưa nắm được bao nhiêu các phần tố ngổn ngang giữa "Invision Board" và web server đứng trước, cái này phải điều tra kỹ mới được.

Thiếu các mảnh tiếp theo của đoạn POST trên, tôi đành thở dài và dừng lại vì chẳng đi tới đâu. Thôi vậy, đành phải sniff lại vì mớ thông tin này chẳng giúp được bao nhiêu.

Chú thích:
-1- "tail", một lệnh dùng để liên tục chuyển thông tin của log lên console để theo dõi.
-2- "gateway", cửa ngõ đi ra / đi vào giữa 2 network.
-3- "sniff", động tác hít nói theo tính sinh hoá, động tác "bắt lấy" các gói tin đi xuyên qua đường dẫn nói theo tinh thần điện toán.
-4- "SYN, ACK, PSH...." là các tcp flags được dùng trong giao thức TCP.
-5- payload là dữ liệu trong gói tin (nói trên bình diện "mạng").
-6- ampersand (&) là dấu "và" trên keyboard.
 
Go to Page:  First Page Page 3 4 5 6

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|