Bảo mật web server Apache với mod Security - Phần 3

Bảo mật web server Apache với mod Security - Phần 3

Đăng vào ngày 3 Tháng Mười 2011 lúc 14:42 bởi Duy Khánh Mục: IT, Security, Unix/Linux, Web Design  ||  Tags: , , , , , ,    Bình luận (1)

PHẦN 3. NGĂN CHẶN MỘT SỐ HÌNH THỨC TẤN CÔNG THƯỜNG GẶP VỚI MODSECURITY

Chương này sẽ trình bày một số hình thức tấn công phổ biến nhất vào web application và web server. Tiếp theo là ngăn chặn các hình thức tấn công đó với ModSecurity. Để thực hiện ngăn chặn được, đầu tiên chúng ta phải hiểu rõ đặc điểm của các hình thức tấn công này.

Web application có thể bị tấn công từ nhiều góc độ khác nhau, vì vậy việc ngăn chặn các cuộc tấn công dưới phương diện web application không hề dễ dàng.

Đối với web server, việc phục vụ các request cũng rất dễ bị khai thác, ngay trong cả web server Apache – một trình web server được đánh giá là bảo mật. Ban đầu, web server chỉ phục vụ yêu cầu các trang HTML. Theo thời gian, các ngôn ngữ khác ra đời như JavaScript, PHP… đi kèm theo các nguy cơ bảo mật. Chẳng hạn như mod_php được sử dụng để chạy các script PHP, có thể bị lỗ hổng bảo mật ở chính ngôn ngữ PHP.


3.1. HTTP FINGERPRINTING

Chỉ có những hacker nghiệp dư mới thực hiện tấn công một server mà không biết server đó có hoạt động hay không. Phức tạp hơn, hacker sẽ thu thập càng nhiều thông tin càng tốt về kiến trúc mạng và phần mềm đang chạy trên server. Cụ thể với web server, phương thức tìm kiếm thông tin này gọi là HTTP Fingerprinting (dấu vân tay HTTP).

HTTP Fingerprinting hoạt động bằng cách kiểm tra các đặc tính riêng của web server bằng các response khi được thăm dò và lấy “dấu vân tay” của server từ những thông tin thu thập được. Sau đó dấu vân tay này được so sánh với một cơ sở dữ liệu về “dấu vân tay” cho các web server được biết đến để xác định tên web server và phiên bản mà nó đang chạy.

Trong bài viết này sử dụng công cụ HTTP Fingerprinting là httprecon. Phiên bản đầu tiên của phần mềm này được phát hành vào năm 2007. Chạy trên hệ điều hành Windows.
Thực hiện thăm dò một server đang chạy Apache 2.2.3 với httprecon, ta thấy kết quả trả về chính xác.

Hình 3.1 Phần mềm httprecon


3.1.1. Cách thức HTTP Fingerprinting hoạt động

Có nhiều cách để các phần mềm HTTP Fingerprinting có thể phát hiện phiên bản của web server đang chạy trên hệ thống. Chúng ta sẽ xem xét một số phương pháp phổ biến sau:

3.1.1.1. Server banner

Server banner là một chuỗi được trả về bởi server trong response header (ví dụ: Apache/1.3.3(Unix) (Red Hat/ Linux)) mang thông tin của phần mềm chạy web server cũng như hệ điều hành của web server đó.

Giả sử một hacker muốn tấn công web server của chúng ta, bước đầu tiên của hacker sẽ là gì? Câu trả lời là tìm hiểu hệ điều hành và phần mềm web server đang chạy trên hệ điều hành đó. Vì vậy, ta có thể tạo ra các thông tin “giả” về web server để cho hacker tự do thăm dò.

Để thay đổi được server banner là điều rất khó. Apache không cung cấp lệnh để thay đổi thông tin về về server banner (trừ khi chúng ta thay đổi mã nguồn và biên dịch Apache ngay từ đầu).

Đề thay đổi, chúng ta phải sử dụng ModSecurity. Khi sử dụng ModSecurity, chúng ta có thể thay đổi hoàn toàn thông tin về máy chủ. Ví dụ như Apache 2.2 thành Microsoft-IIS/5.0. Tuy nhiên, để thú vị hơn thì chúng ta nên thay đổi nó thành thông tin của một máy chủ phiên bản cũ có nhiều lỗi bảo mật.

Đầu tiên, chúng ta cần phải “nói” cho Apache để Apache gởi thông tin đầy đủ phiên bản của máy chủ trong response header. Sau đó ModSecurity có thể nhận ra và thay đổi thiết lập.

Đơn giản là trong httpd.conf, thêm vào dòng

# Goi full server signature de ModSecurity co the thay doi no 
 ServerTokens Full

Sau đó, thêm dòng sau vào file cấu hình của ModSecurity (ở đây đặt là modsecurity.conf). Khởi động lại apache khi hoàn thành.

# Thay doi web server signature goi boi Apache 
 SecServerSignature "Apache 1.3.24"

Apache 1.3.24 là phiên bản củ của Apache với rất nhiều lỗ hổng bảo mật. Thấy vậy các hacker rất thích thú và bỏ rất nhiều thời gian và công sức để khai thác các lỗ hổng bảo mật của phiên bản này.. Hy vọng sẽ làm nản chí các đối tượng muốn khai thác hệ thống của chúng ta (nhưng đối với các hacker kinh nghiệm, sẽ có các biện pháp để phát hiện phiên bản thật của máy chủ web).

Bây giờ, chúng ta kiểm tra kết quả của các bước trước đã cấu hình.

Hình 3.2 Kết quả thay đổi server banner với ModSecurity

3.1.1.2. Các response của giao thức HTTP

Để lấy được thông tin web server, có thể sử dụng các request phi tiêu chuẩn (non-standard) hoặc request bất thường để web server gởi về các response kèm theo thông tin về server cần thu thập.
Các request có thể sử dụng để lấy thông tin từ web server:

Request HTTP DELETE không hợp lệ

Như phần 2.3.2 của chương 2 đã trình bày, HTTP DELETE dùng để xoá dữ liệu từ web server. Lệnh này chủ yếu được thực hiện với người dùng đã được chứng thực. Vì vậy đối với người dùng chưa được chứng thực, thông báo lỗi sẽ được trả về. Trong thông báo lỗi có thể có các thông tin về web server.

Ví dụ ở đây sử dụng Netcat để gởi request DELETE đến web server Apache:

c:\nc>nc ptnd.com 80
 DELETE /HTTP/1.0
 ............
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>405 Method Not Allowed</title>
 </head><body>
 <h1>Method Not Allowed</h1>
 <p>The requested method GET is not allowed for the URL /HTTP/1.0.</p>
 <p>Additionally, a 404 Not Found
 error was encountered while trying to use an ErrorDocument to handle the reques.</p>
 <hr>
 <address>Apache 1.3.24 PHP/5.1.6 mod_python/3.2.8 Python/2.4.3 mod_perl/2.0.4 Prl/v5.8.8 Server at ptnd.com Port 80</address>
 </body></html>

Kết quả trả về lỗi 405 Method Not Allowed. Lỗi trên cho thấy phương thức request DELETE không cho phép request các URL /index.html. Thông báo lỗi này kèm theo thông tin về máy chủ Apache 1.3.24 PHP/5.1.6 mod_python/3.2.8 Python/2.4.3 mod_perl/2.0.4 Prl/v5.8.8.

Request sai phiên bản HTTP

Thực hiện ví dụ tương tự như phần trên bằng cách gởi request GET đế web server với thông số phiên bản của giao thức HTTP không đúng.

Dưới đây là kết quả thực hiện GET với phiên bản HTTP là 5.0

c:\nc>nc ptnd.com 80
 GET /HTTP/5.0
 ...........
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>404 Not Found</title>
 </head><body>
 <h1>Not Found</h1>
 <p>The requested URL /HTTP/5.0 was not found on this server.</p>
 <p>Additionally, a 404 Not Found
 error was encountered while trying to use an ErrorDocument to handle the request
 .</p>
 <hr>
 <address>Apache 1.3.24 PHP/5.1.6 mod_python/3.2.8 Python/2.4.3 mod_perl/2.0.4 Perl/v5.8.8 Server at ptnd.com Port 80</address>
 </body></html>

Request sai giao thức

Ví dụ dưới đây thực hiện GET với tên giao thức không phải là HTTP mà là VIETHANIT. Kết quả báo lỗi tương tự.

c:\nc>nc ptnd.com 80
 GET /VIETHANIT/1.0
 ..........
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>404 Not Found</title>
 </head><body>
 <h1>Not Found</h1>
 <p>The requested URL /VIETHANIT/1.0 was not found on this server.</p>
 <p>Additionally, a 404 Not Found
 error was encountered while trying to use an ErrorDocument to handle the request
 .</p>
 <hr>
 <address>Apache 1.3.24 PHP/5.1.6 mod_python/3.2.8 Python/2.4.3 mod_perl/2.0.4 Perl/v5.8.8 Server at ptnd.com Port 80</address>
 </body></html>

Giới thiệu về ETag HTTP header

Chúng ta có thể quen thuộc với thông số HTTP Last-Modified trong response header. Thông số này cho phép trình duyệt xác định có tải về nội dung web hay sử dụng bộ nhớ cache để hiển thị cho người dùng (chẳng hạn như các file hình ảnh..) để tránh tải về các nội dung không thay đổi kể từ lần truy cập cuối. Các Etag header (viết tắt của "Entity Tag") hoạt động theo cách tương tự, nhưng sử dụng thêm thông tin về tập tin là số inode (inode là số đại điện cho mỗi tập tin trong hệ thống tập tin Unix, số này chỉ thay đổi khi tập tin mà nó đại điện thay đổi thuộc tính như người sở hữu, kiểu tệp, quyền truy cập…).

Etag header cũng được các phần mềm Fingerprinting dùng để xác định cấu hình web server. Ngoài ra, nếu sử dụng Etags có thể làm giảm hiệu suất hoạt động của web server.

Ví dụ: Nếu chúng ta đang chạy nhiều web server để cân bằng tải và cấu hình Apache cho phép response Etag (mặc định Apache cho phép), các web server khác nhau sẽ trả về giá trị ETag khác nhau ngay cả khi thuộc tính của tập tin không thay đổi (do số inode trên các server khác nhau sẽ khác nhau). Điều này sẽ làm cho trình duyệt tải về các nội dung không cần thiết ngay cả khi thuộc tính của tập tin không thay đổi từ lần truy cập trước.

Vô hiệu hoá ETag trong response của Apache sẽ có lợi cho hiệu năng của web server và làm cho HTTP Fingerprinting khó khăn hơn trong việc thăm dò. Để vô hiệu hoá ETag, trong file cấu hình httpd.conf thực hiện thêm vào dòng

 

 

Header unset ETag

Lưu ý: Nếu web server đang chạy WebDAV với mod_dav_fs, chúng ta không nên vô hiệu hoá ETag vì mod_dav_fs sử dụng nó để xác định các tập tin đã thay đổi.

3.1.2. Sử dụng ModSecurity để ngăn chặn HTTP Fingerprinting

Chúng ta sẽ cung cấp đầy đủ các thông tin cho hacker tìm hiểu, nhưng không phải là thông tin chính xác. ModSecurity cho phép chúng ta tuỳ chỉnh và đánh lừa các công cụ HTTP Fingerprinting. Ví dụ cụ thể:

-    Chỉ cho phép các phương thức GET, HEAD, và POST
-    Chặn tất cả các request với các giao thức ngoại trừ giao thức HTTP 1.0 và 1.1
-    Chặn các request không chứa Host header
-    Chặn tất cả các request không chứa Accept header
-    Đặt chữ ký là Microsoft-IIS/6.0
-    Thêm X-Powered-By: ASP.NET 2.0 header
-    Gỡ bỏ Etag header

Dưới đây là các rule để thực hiện

# Thay doi chu ky server
 SecServerSignature "Microsoft-IIS/6.0"
 # Tu choi cac request khong chua host header
 SecRule &REQUEST_HEADERS:Host "@eq 0" "phase:1,deny"
 # Tu choi cac request khong chua request header
 SecRule &REQUEST_HEADERS:Accept "@eq 0" "phase:1,deny"
 # Chi cho phep GET HEAD va POST
 SecRule REQUEST_METHOD !^(get|head|post)$ "phase:1,t:lowerCase,deny"
 # Chi cho phep HTTP phien ban 1.0 va 1.1
 SecRule REQUEST_PROTOCOL !^http/1\.(0|1)$ "phase:1,t:lowercase,deny"
 # Them X-Powered-By header
 Header set X-Powered-By "ASP.NET 2.0"
 # Go bo ETag header
 Header unset ETag

Và đây là kết quả của phần mèm Acunetix khi thực hiện scan:

 

Hình 3.3 Kết quả dùng Acunetix khi scan

3.2. NGĂN CHẶN CÁC REQUEST TỪ PROXY SERVER

Các request từ proxy server thường không tốt đối với một số website. Ví dụ nếu chúng ta đang chạy một diễn đàn thảo luận VBB hoặc PHPBB… Hacker thường sử dụng các proxy làm trung gian để ẩn dấu vết của mình và thực hiện các hành động như spam các bài viết lên diễn đàn, thực hiện các cuộc tấn công từ chối dịch vụ Ddos.. Do đó, chúng ta có thể chặn những người truy cập từ các proxy này.

Đặc điểm nhận dạng của các proxy khi request vào web server là có sự hiện diện của chuỗi X-Forwarded-For trong request header, chúng ta có thể dựa vào đặc điểm này để viết rule ngăn chặn.
Rule được viết như sau:

SecRule &REQUEST_HEADERS:X-Forwarded-For "@gt 0" deny

Lưu ý: Phải xem xét kỹ lưỡng trước khi quyết định chặn các proxy truy cập vào server. Bởi không phải tất cả website đều không nên cho proxy server truy cập vào.

3.3. CROSS-SITE SCRIPTING
3.3.1. Định nghĩa

Cross-Site Scripting hay còn được gọi tắt là XSS (thay vì gọi tắt là CSS để tránh nhầm lẫn với CSS-Cascading Style Sheet của HTML) là một kĩ thuật tấn công bằng cách chèn vào các website động (ASP, PHP, CGI, JSP ...) những thẻ HTML hay những đoạn mã script nguy hiểm có thể gây nguy hại cho những người sử dụng khác. Trong đó, những đoạn mã nguy hiểm được chèn vào hầu hết được viết bằng các Client-Site Script như JavaScript, JScript, DHTML và cũng có thể là cả các thẻ HTML.
Kĩ thuật tấn công XSS đã nhanh chóng trở thành một trong những lỗi phổ biến nhất của Web Applications và mối đe doạ của chúng đối với người sử dụng ngày càng lớn.

4.3.2. Hoạt động của XSS

Về cơ bản XSS cũng như SQL Injection hay Source Injection (sẽ được giới thiệu ở phần sau), nó cũng là các request được gửi từ các máy client tới server nhằm chèn vào đó các thông tin vượt quá tầm kiểm soát của server. Nó có thể là một request được gửi từ các form dữ liệu hoặc cũng có nằm trong request URI, ví dụ:

http://www.example.com/search.cgi?query=<script>alert('XSS was found !');</script>

Nếu truy cập vào địa chỉ trên, rất có thể trình duyệt sẽ hiện lên một thông báo XSS was found !. Các đoạn mã trong thẻ <script> không hề bị giới hạn bởi chúng hoàn toàn có thể thay thế bằng một file nguồn trên một server khác thông qua thuộc tính src của thẻ <script>. Cũng chính vì lẽ đó mà chúng ta chưa thể lường hết được độ nguy hiểm của các lỗi XSS.

Nhưng nếu như các kĩ thuật tấn công khác có thể làm thay đổi được dữ liệu nguồn của web server (mã nguồn, cấu trúc, cơ sở dữ liệu) thì XSS chỉ gây tổn hại đối với website ở phía client mà nạn nhân trực tiếp là những người khách duyệt site đó. Tất nhiên đôi khi các hacker cũng sử dụng kĩ thuật này đề chiếm quyền điều khiển các website nhưng đó vẫn chỉ tấn công vào bề mặt của website. Thật vậy, XSS là những Client-Side Script, những đoạn mã này sẽ chỉ chạy bởi trình duyệt phía client do đó XSS không làm ảnh hưởng đến hệ thống website nằm trên server.

Mục tiêu tấn công của XSS không ai khác chính là những người sử dụng khác của website, khi họ vô tình vào các trang có chứa các đoạn mã nguy hiểm do các hacker để lại, họ có thể bị chuyển tới các website khác, đặt lại homepage, hay nặng hơn là mất mật khẩu, mất cookie thậm chí máy tính người truy cập có thể sẽ bị cài các loại virus, backdoor, worm ..

3.3.3. Ngăn chặn tấn công XSS

Đề ngăn chặn tấn công XSS, chúng ta phải đảm bảo tất cả dữ liệu mà người dùng gởi lên đều được cản lọc. Cụ thể, chúng ta có thể thay thế hoặc loại bỏ các ký tự, các chuỗi thường được dùng trong tấn công XSS như đấu ngoặc góc (< và >), script...
Dưới đây là danh sách các ký tự nên mã hoá khi được client cung cấp để lưu vào cơ sở dữ liệu.

 

Bảng 3.1 Các ký tự nên mã hoá để ngăn chặn tấn công XSS

Nếu chúng ta muốn ngăn chặn tấn công với ModSecurity, dưới đây là các đoạn script XSS phổ biến và các biểu thức chính quy để ngăn chặn người dùng request chứa các chuỗi này.

Bảng 3.2 Các script XSS và biểu thức chính quy

Dưới đây là ví dụ về một rule dùng để chặn XSS đã được trình bày ở phần 2.4.5

 

SecRule ARGS "<script" "deny,t:lowercase"

 

 

3.4. TẤN CÔNG THỰC THI CÁC LỆNH SHELL

Như chúng ta đã biết, chấp nhận dữ liệu đầu vào từ client mà không cản lọc có thể gây ra nguy hiểm cho ứng dụng web. Cụ thể của việc này là người dùng gởi các request trái phép đến server để hiển thị hoặc thực thi một tập tin nào đó mà người dùng không có quyền.

Hacker thường kết hợp nhiều yếu tố để đạt được hiệu quả tối đa. Các ứng dụng web rất ít sử dụng các lệnh shell bởi nó thực hiện gọi exec() đến hệ thống. Tuy nhiên, chúng ta hãy xem xét quy trình sau đây:

Quy trình trên là sự kết hợp giữa khai thác lỗi SQL injection để tạo ra các file PHP với việc thực thi các lệnh shell. Nếu việc cản lọc dữ liệu đầu vào của web server không thành công, hacker sẽ thực thi scripts thucthi.php và toàn bộ dữ liệu trên thư mục gốc của web server sẽ bị xoá.

Điều này cho thấy, cản lọc thực thi các lệnh shell là công việc hết sức cần thiết đối với người làm bảo mật web server.
Dưới đây là một số lệnh, tên chương trình và đường dẫn thông thường của hệ thống Unix có thể chặn để tránh tấn công thực thi lệnh shell:

-    rm
-    ls
-    kill
-    mail
-    sendmail
-    cat
-    echo
-    /bin/
-    /etc/
-    /tmp/

Để chặn các request với đối số là các chuỗi trên, ta có rule sau:

SecRule ARGS “rm|ls|kill(send)?mail|cat|echo|/bin/|/etc/|/tmp/)” “deny”

3.5. TẤN CÔNG NULL BYTE

Kiểu tấn công null byte (byte rỗng) thực sự bắt nguồn từ ngôn ngữ lập trình C (và các ngôn ngữ liên quan), sử dụng một byte rỗng (0x00) để biểu thị kết thúc một chuỗi. Ví dụ về cách lưu trữ chuỗi viethanit trong bộ nhớ của ngôn ngữ C:

 

Với các ngôn ngữ lập trình khác như Java, các chuỗi được lưu trữ trong mảng, và giá trị tổng chiều dài của chuỗi (total length) được lưu trữ ở một vị trí riêng biệt. Vì vậy hoàn toàn có thể lưu trữ được các byte rỗng ở giữa chuỗi.
Lợi dụng sự khác biệt trong việc lưu trữ và xử lý chuỗi giữa các ngôn ngữ lập trình, hacker có thể thực hiện tấn công khai thác lỗi null byte bằng cách đánh lừa các phần của hệ thống để phần này nghĩ rằng chuỗi đã kết thúc (vì gặp byte rỗng) và phần kia của hệ thống lại nghĩ rằng chuỗi được nhập đầy đủ.

Xét trang JSP đơn giản được viết để hiển thị nội dung tập tin văn bản cho client truy cập bằng cách sử dụng tên tập tin làm tham số:

><%
   String filename = request.getParameter("file");
   if (filename.endsWith(".txt")) {
     // Include text file in output page
   }
 %>

 

Với ví dụ trên, website sẽ đảm bảo tên tập tin yêu cầu hiển thị cho người truy cập phải có phần mở rộng là .txt . Tuy nhiên, nếu hacker sử dụng hình thức tấn công là null byte, hacker sẽ nhập vào đối số tên tập tin là /etc/passwd%00.txt .

Mặt khác, Java lại có khả năng chứa các byte rỗng trong chuỗi, vì vậy yêu cập hiển thị nội dung tập tin trên là hợp lệ và sẽ vượt qua được hàm kiểm tra filename.endsWith(".txt"). Khi yêu cầu hiển thị tập tin được chuyển vào cho hệ thống, chức năng mở tập tin sẽ hoạt động. Một vấn đề phát sinh nếu chức năng đọc tên tập tin của hệ thống dừng khi gặp byte rỗng, hệ điều hành sẽ không mở tập tin /etc/passwd%00.txt mà thay vào đó sẽ mở tập tin /etc/passwd (tập tin hệ thống chứa thông tin về người dùng của các hệ thống Unix). Và nội dung của tập tin này sẽ được hiển thị trên trình duyệt của hacker.

ModSecurity có hai chức năng chuyển đổi đề đối phó với các byte rỗng được gởi lên từ người truy cập đó là replaceNulls removeNulls. Với replaceNulls, khi thực thi sẽ thay thế byte rỗng bằng khoảng trắng, trong khi đó removeNulls lại thực hiện loại bỏ hoàn toàn byte rỗng. Byte rỗng rất hiếm khi cần thiết cho dữ liệu nhập vào của website, vì vậy có thể thiết lập chuyển đổi byte rỗng trong SecDefaultAction:

SecDefaultAction "phase:2,deny,log,status:403,t:removeNulls"

 

Rule trên từ chối các request boby có chứa byte rỗng. Nếu chúng ta muốn cho phép các request này, thực hiện dùng chức năng chuyển đổi để gỡ bỏ hoặc thay thế byte rỗng với rule:

SecRule ARGS:data "pass,t:-removeNulls"

3.6. TẤN CÔNG DIRECTORY TRAVERSAL

Thông thường, web server sẽ từ chối client truy cập vào các tài nguyên không nằm trong thư mục gốc của web server.

Ví dụ: Nếu thư mục gốc của web server là /home/www, client yêu cầu truy cập vào tài nguyên /etc/passwd thì sẽ bị web server từ chối vì tài nguyên trên không nằm trong /home/www. Tuy nhiên, có một hình thức tấn công có thể truy cập vào tài nguyên này mà không cần sử dụng một công cụ nào, chỉ đơn thuần thao tác với các biến với ../ (dot-dot-slash) để thực hiện liên kết mềm (symbolic) truy cập đến các file nằm trong thư mục cha của thư mục hiện hành. Đó là tấn công Directory Traversal.

Dưới đây là một ví dụ cụ thể về loại hình tấn công này.

http://example.com/getpage.php?page=../../../etc/passwd

Như ta thấy trên URI, thực hiện chèn biến ../ ba lần để liên kết mềm về thư mục gốc / . Sau đó thêm vào etc/passwd để tạo thành request đến thư mục /etc/passwd. Nếu không cấu hình cản lọc để request này, nội dung của file /etc/passwd sẽ được hiển thị trên trình duyệt của hacker.
Hacker có thể không chèn trực tiếp biến ../ mà thực hiện chèn các biến đã được mã hoá như %2e%2e%2f, khi giải mã thì nội dung vẫn là ../

Dưới dây là danh sách các chuỗi chúng ta cần chặn:

-    ../
-    ..%2f
-    %2e%2e/
-    %2e%2e%2f
-    %2e./

Với ModSecurity, chỉ cần sử dụng chức năng chuyển đổi t:urlDecode để chuyển tất cả chuỗi được mã hoá thành giá trị nguyên thuỷ của nó. Dưới đây là rule để chặn hình thức tấn công này:

SecRule REQUEST_URI "../" "t:urlDecode,deny"

3.7. TẤN CÔNG SQL INJECTION
3.7.1. Giới thiệu

Các cuộc tấn công SQL injection có thể xảy ra nếu hacker cung cấp dữ liệu cho ứng dụng web mà các dữ liệu này không được cản lọc, làm sai lệch các câu lệnh SQL khi thực thi. Điển hình là nhập vào các chuỗi đặc biệt để bỏ qua bước kiểm tra mật khẩu của người dùng và làm cho đăng nhập hợp lệ:

Ví dụ, chúng ta xét câu lệnh truy vấn khi thực hiện đăng nhập dưới đây:

 

 

SELECT * FROM user WHERE username = '%s' AND password = '%s';

 

Với truy vấn trên, nếu hacker muốn đăng nhập vào với tài khoản admin mà chưa biết mật khẩu, hacker sẽ thực hiện nhập tên đăng nhập là admin và mật khẩu là ‘ OR ‘1’ = ‘1 -- Khi thực hiện truy vấn, thông tin đăng nhập được đưa vào sẽ trở thành:

SELECT * FROM user WHERE username = 'admin' AND password = '’ OR ‘1’ = ‘1’;

Câu lệnh trên có nghĩa: Truy vấn lấy thông tin tất cả các trường từ bảng user với điều kiện trường username có giá trị là admin và mật khẩu là trống ‘’ hoặc 1 = 1. Mà 1 = 1 là luôn đúng nên mặc dù mật khẩu không đúng, câu lệnh trên vẫn được thực thi và truy vấn lấy thông tin user admin thành công. Đăng nhập sẽ được chấp nhận.

3.7.2. Các hình thức tấn công SQL injection thông thường
3.7.2.1. Lấy dữ liệu từ nhiều bảng với UNION

Câu lệnh SQL UNION có thể được sử dụng để lấy dữ liệu từ hai bảng khác nhau. Ví dụ: Nếu có một bảng có tên cooking_recipes và bảng khác có tên ser_credentials, lệnh SQL sau sẽ lấy dữ liệu từ cả hai bảng:

SELECT dish_name FROM cooking_recipe UNION SELECT username, password FROM user_credentials;

Một câu lệnh SQL tương tự là UNION ALL, hoạt động gần giống như UNION. Sự khác biệt duy nhất là UNION ALL sẽ không loại bỏ các dòng bị trùng lặp trong kết quả trả về.

3.7.2.2. Nhiều truy vấn trong một lời gọi

Nếu SQL engine cho phép nhiều câu lệnh SQL trong một truy vấn SQL đơn, ta sẽ thấy nguy cơ bảo mật xuất hiện. Ví dụ sau có thể giải thích nguy cơ này.

 

SELECT * FROM products WHERE id = %d;

Nếu hacker cung cấp ID bằng một đoạn lệnh 1;DROP TABLE products; câu lệnh SQL sẽ trở thành:

SELECT * FROM products WHERE id = 1; DROP TABLE products;

 

Khi câu lệnh này được thực hiện, đầu tiên nó sẽ truy vấn tất cả các trường trong bảng products có id bằng 1, sau đó bảng products sẽ bị xoá.

3.7.2.3. Đọc nội dung của một file

MySQL có thể được sử dụng để đọc nội dung của một file trên hệ thống bằng cách sử dụng hàm LOAD_FILE(). Ví dụ:

SELECT LOAD_FILE(“/etc/passwd”);

Lệnh sẽ trả về nội dung của file /etc/passwd nếu tiến trình MySQL có quyền truy cập.

3.7.2.4. Ghi dữ liệu vào tập tin

MySQL cũng hỗ trợ lệnh ghi dữ liệu vào tập tin với OUTFILE. Rất nguy hiểm nếu hacker lợi dụng và khai thác được lệnh này, bởi thực thi OUTFILE không những ảnh hưởng đến cơ sở dữ liệu mà còn ảnh gây hưởng đến tập tin hệ thống.

Dưới đây là một ví dụ đơn giản sử dụng MySQL để ghi dữ liệu vào file text.txt

SELECT "vi du ghi du lieu" INTO OUTFILE "test.txt";

3.7.3. Ngăn chặn tấn công SQL injection

Có ba bước quan trọng để ngăn chặn tấn công SQL injection:

1. Làm “trong sáng” câu lệnh SQL trong ứng dụng web.
2. Lọc dữ liệu người dùng đưa lên.
3. Sử dụng ModSecurity để chặn mã SQL injection khi hacker khai thác lỗi ứng dụng web.

Trong ba bước trên, quan trọng nhất vẫn là bước đầu tiên. Sử dụng các câu lệnh SQL “trong sáng” nghĩa là sử dụng các câu lệnh chuẩn, không không gây ra lỗ hổng SQL injection cho ứng dụng web.
Bước thứ hai là đảm bảo tất cả dữ liệu người dùng cung cấp cho truy vấn SQL đểu được cản lọc, tránh bị chèn vào các đoạn mã nguy hiểm như dấu ngoặc đơn, dấu nháy đơn… Nếu ứng dụng web viết bằng PHP, có thể sử dụng các mysql_real_escape_string() để cản lọc.

Và cuối cùng, sử dụng ModSecurity để ngăn chặn triệt để tấn công SQL injection.

Dưới đây là bảng liệt kê danh sách các lệnh thường được sử dụng trong tấn công SQL injection cùng với các biểu thức chính quy dùng để ngăn chặn

Bảng 3.3 Các lệnh thường được sử dụng trong tấn công SQL injection

Ví dụ về rule để chặn tấn công SQL injection ghi dữ liệu vào tập tin.

SecRule ARGS "into\s+outfile" "t:lowercase,deny,msg:'SQL Injection'"

Cú pháp \s+ cho phép phát hiện tất các hình thức nhập vào của ký tự trắng (space) ví dụ như INTO%20%20OUTFILE.

 

3.8. TẤN CÔNG BRUTE FORCE

Với tấn công Brute Force, hacker thực hiện đoán các thông tin đăng nhập như tên người dùng, mật khẩu, email… và thực hiện đăng nhập liên tục đến khi nào thông tin đăng nhập là đúng. Hầu hết người dùng đều sử dụng thông tin đăng nhập giống nhau trên tất cả các website mà họ thường đăng nhập, dẫn đến tài khoản của họ bị xâm nhập trên hàng loạt các website khi thông tin đăng nhập bị lộ bởi một website khác.

Cách tốt nhất để ngăn chặn hình thức tấn công này là giới hạn số lần đăng nhập không đúng. Ví dụ nếu người sử dụng đăng nhập không đúng quá 3 lần, thực hiện khoá đăng nhập của người này trong 5 phút.

Dưới đây là các rule của ModSecurity cho phép chúng ta thực hiện điều này

# Khoa dang nhap sau 3 lan dang nhap khong thanh cong
 #
 <LocationMatch ^/login>
 # Khoi tao collection ip
 SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"
 # Phat hien dang nhap khong thanh cong
 SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:
 ip.failed_logins=+1,expirevar:ip.failed_logins=300"
 # Khoa dang nhap khi so lan dang nhap khong thanh cong bang 3
 SecRule IP:FAILED_LOGINS "@gt 3" deny
 </Location>

Các rule trên dựa vào đặt điểm trả về của website khi người truy cập đăng nhập không thành công: Username does not exist

Các rule trên sẽ khởi tạo collection IP và tăng giá trị biến ip.failed_login lên một đơn vị sau mỗi lần đăng nhập không thành công. Action expirevar sẽ thiết lập biến ip.failed_login về 0 sau 5 phút. Vì vậy, khi biến ip.failed lớn hơn hoặc bằng 3, rule cuối sẽ khoá đăng nhập của người dùng trong 5 phút.

Hoặc chúng ta có thể thực hiện trì hoãn (hay dừng) request của người dùng khi số lần đăng nhập sai vượt quá quy định. Do đó, không cần phải từ chối truy cập như các rule được nêu ở trên. Sau đây là rule thực hiện điều trên:

# tri hoan request 3 giay sau 3 lan dang nhap khong thanh cong
 <LocationMatch ^/login>
 SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"
 SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:
 ip.failed_logins=+1,expirevar:ip.failed_logins=10"
 SecRule IP:FAILED_LOGINS "@gt 3" "phase:4,allow,pause:3000"
 </Location>

Thời gian trì hoãn được tính bằng mili giây, các rule trên sẽ trì hoãn response trong 3 giây khi số lần truy cập không thành công lớn hơn hoặc bằng 3.

3.9. DIRECTORY INDEXING

Khi người sử dụng request đến URL như http://example.com, URL này không request cụ thể đến một tập tin nào trên web server (ví dụ http://example.com/page.html request cụ thể đến page.html), vì vậy Apache sẽ tìm đọc tập tin theo cấu hình DirectoryIndex (thường là index.html, index.php …). Nếu không có tập tin nào có trong danh sách tập tin đã được cấu hình trong DirectoryIndex., Apache xem xét tuỳ chọn Indexes có được kích hoạt hay không. Tuỳ chọn này có thể được kích hoạt theo cách sau

<Directory /home/www/rangdong1>
 Options +Indexes
 </Directory>

Nếu cấu hình tuỳ chọn Indexes cũng không được tìm thấy hoặc không kích hoạt. Apache sẽ liệt kê ra tất cả các thư mục và tập tin hiển thị cho người dùng.

 

Hình 3.4 Liệt kê thư mục và tập tin với Indexes

Với việc liệt kê ra danh sách các thư mục, tập tin sẽ làm cho người dùng có thể xem được cấu trúc của mã nguồn website, có thể tải về các tập tin không được phép…Vì vậy, chúng ta có thể tắt indexes bằng cách khai báo trong httpd.conf:

 

<Directory /home/www>
 Options -Indexes
 </Directory>

 

Hoặc cũng có thể tắt indexes bằng cách cấu hình không cho chạy module mod_autoindex.so

# Disable directory indexing
 # LoadModule autoindex_module modules/mod_autoindex.so

 

Lưu ý: Một số module của Apache yêu cầu mod_autoindex.so hoạt động, vì vây nếu tắt module này có thể dẫn đến Apache không khởi động được.

Để đảm bảo chắc chắc rằng người dùng không thể liệt kê được các file và thư mục. Chúng ta có thể sử dụng ModSecurity với rule:

SecRule REQUEST_URI "/$" "phase:4,deny,chain,log, msg:'Directory index returned'"
 SecRule RESPONSE_BODY "<h1>Index of /"

Khi người dùng thực hiện liệt kê file, thư mục. Apache sẽ trả về response body có chứa <h1>Index of /, vì vậy rule trên sẽ chặn lại và ghi log với nội dung Directory index returned

Kết thúc chủ đề Bào mật web server Apache với ModSecurity

 

Nguồn: tanviet12 – hvaonline.net

Bình luận (1) -

Anh H&#249;ng
Anh Hùng
28/02/2013 2:27:35 CH #

Anh ơi cho em hỏi muốn demo phần này trên VMWARE thì mô hình demo như thế nào vậy anh?cảm ơn anh

Pingbacks and trackbacks (2)+

Nghe nhạc cho vui

Ghi Chú

+ command "netstat -ano": IPs access

+ Restore dữ liệu trên SQLServer bằng dòng lệnh

RESTORE DATABASE db_name
FROM DISK = 'E:\db.BAK'
WITH REPLACE

+ Cover từ VB.NET sang C#

http://developerfusion.com/tools/convert/vb-to-csharp/

Certifications