Bảo mật web server Apache với mod Security

dayto.kdh

Administrator
PHẦN 1: CƠ BẢN VỀ GIAO THỨC HTTP

Phần này chỉ giới thiệu sơ lược các kiến thức cơ bản về giao thức HTTP, tạo tiền đề để phần 2 trình bày về MODSECURITY. Vì vậy, nếu bạn nào cần tìm hiểu sâu hơn, hãy tham khảo RFC hoặc cuốn HTTP Essentials

1.1. Giới thiệu chung
1.1.1. Lớp của giao thức HTTP

HTTP (Hypertext Transfer Protocol) là giao thức thuộc lớp ứng dụng trong mô hình tham chiếu OSI. Hoạt động thông thường ở port 80 và là giao thức hướng kết nối. Nói cách khác, trước khi thực hiện phiên làm việc, giao thức HTTP sẽ thực hiện bắt tay ba bước.

Hình 1.1 Lớp của giao thức HTTP

1.1.2. URI – Uniform Resource Identifiers
Thông thường, chúng ta thường quen thuộc với định nghĩa URL (Uniform Resource Locators) Địa chỉhttp://www.example.com.vn là một ví dụ về URL. Trên thực tế, không có nhiều khác biệt giữa hai khái niệm URL và URI, URL một chỉ là một loại của URI.
URI là một đặc điểm kỹ thuật của giao thức HTTP. Như hình dưới cho thấy một URI chứa rất nhiều các thành phần, không đơn giản như URL.
Hình 1.2 Cấu trúc đầy đủ của URI

  • Protocol: Xác định các giao thức và các ứng dụng cần thiết để truy cập tài nguyên, trong trường hợp này là giao thức HTTP
  • Username: Nếu giao thức hỗ trợ khái niệm về tên người dùng thì username cung cấp tên người dùng để chứng thực truy cập tài nguyên
  • Password: Mật khẩu truy cập tài nguyên
  • Host: Tên miền truyền thông cho webserver
  • Port: Là port cho các giao thức lớp ứng dụng, ví dụ như HTTP là cổng 80 (có thể bỏ qua tham số này).
  • Path: đường dẫn phân cấp đến tài nguyên được đặt trên Server
  • File: Tên các tập tin tài nguyên trên Server
  • Query: Các tuy vấn thêm thông tin về tài nguyên của Client
  • Fragment: Một vị trí nào đó trong tài nguyên

    1.2. Hoạt động HTTP
    1.2.1. Kết nối

    HTTP thuộc giao thức TCP, vì vậy trước khi tiến hành truyền thông phải thực hiện phiên kết nối TCP. Trước đây, mỗi kết nối TCP sẽ thực hiện chỉ 1 request HTTP và 1 response, nghĩa là nếu client request 2 lần thì sẽ cần 2 phiên kết nối TCP. Điều này gây ra nhiều bất cập, ảnh hưởng rất nhiều đến hiệu năng hoạt động của server.
Hình 1.3 Hoạt động của HTTP
Hiện nay, giao thức HTTP đã hỗ trợ một phiên kết nối TCP cho phép nhiều HTTP request.
Hình 1.4 Hoạt động kết nối của HTTP

1.2.2. Pipelining
Pipelining cũng nhằm mục đích cải thiện hiệu năng của HTTP. Client không cần phải chờ Server response mới có thể request và ngược lại.
Hình 1.5 Hoạt động Pipelining của HTTP
1.2.3. Web Page Retrieval – GET
Hoạt động HTTP đơn giản nhất là GET. Đó là cách để Client lấy một đối tượng hoặc tài nguyên nào đó trên Server. Các trình duyệt sẽ yêu cầu một website từ Server với GET.
Hình 1.6 Hoạt động GET của HTTP

Với ví dụ trên, Client khởi tạo và gởi thông điệp GET đến Server, thông điệp này định danh đối tượng mà Client yêu cầu Server đáp ứng bằng một URI (Uniform Resource Identifier). Server có thể trả về tài nguyên mà Client yêu cầu với một mã trạng thái 200 OK. Nếu Server không đáp ứng được yêu cầu Client thì nó sẽ gởi về một số mã trạng thái khác được mô tả ở bảng bên dưới.

Bảng 1.1 Mã trạng thái được trả về của HTTP

1.2.4. Web Forms – POST
Trong khi GET cho phép một Server gửi thông tin đến Client, thì hoạt động POST cung cấp một cách để Client gửi thông tin đến các Server. Trình duyệt sử dụng POST để gởi nội dung các Form đến Web Server. Hình dưới cho thấy một ví dụ như vậy.
Hình 1.7 Ví dụ về Web Forms POST
Hình 1.8 Hoạt động POST của HTTP

Như hình trên cho thấy, hoạt động POST đơn giản như GET. Client gửi một thông điệp POST và bao gồm thông tin mà nó muốn gửi đến server. Cũng giống như GET, một phần của thông điệp POST là URI. Nhưng trong trường hợp này, URI xác định các đối tượng trên Server có thể xử lý thông tin.
Cũng như GET, Server có thể trả về thông tin cho client. Đối với trình duyệt web, thông tin thường là một trang web mới để hiển thị.


1.2.5. File Upload – PUT

Các hoạt động PUT cũng cung cấp một cách để client gửi thông tin đến các Server. Hay nói cách khác, PUT dùng để upload dữ liệu lên server.
Như hình dưới cho thấy, hai hoạt động nhìn rất giống nhau. Với POST, Client gửi bao gồm một URI và dữ liệu. Web Server về mã trạng thái, tuỳ chọn kèm theo và dữ liệu. Sự khác biệt giữa POST và PUT ở chỗ URI : Với POST, các URI xác định một đối tượng trên Server mà có thể xử lý dữ liệu. Với một PUT, các URI xác định đối tượng trong đó các Server nên đặt dữ liệu (ví dụ đường dẫn cho Server đặt dữ liệu).
Trong khi một POST URI thường chỉ ra một chương trình, script.. thì PUT uri thường là đường dẫn và tên cho tập tin.
Hình 1.9 Hoạt động PUT của HTTP
Hình 1.10 Ví dụ về File Upload - PUT

1.2.6. File Deletion – DELETE

Với GET và PUT, giao thức HTTP trở thành một giao thức chuyển file đơn giản. Hoạt động DELETE sẽ hoàn thành chức năng này bằng cách giúp client xoá các đối tượng, tài nguyên từ các server.
Như hình dưới cho thấy, client gửi một thông điệp DELETE cùng với các URI của đối tượng mà server nên xoá. Các server đáp ứng với một mã trạng thái và dữ liệu kèm theo.
Hình 1.11 Hoạt động File Delection - DELETE

1.2.7. Trạng thái – HEAD
Các hoạt động của HEAD giống như GET, ngoại trừ Server không trả lại đối tượng thực tế yêu cầu. Cụ thể, server sẽ trả về một mã trạng thái nhưng không có dữ liệu. (HEAD có nghĩa là "tiêu đề," nghĩa là server chỉ trả về thông điệp chứa tiêu đề chứ không chứa dữ liệu) .
Client có thể sử dụng thông điệp HEAD khi muốn xác minh rằng một đối tượng có tồn tại hay không,.
Ví dụ: Có thể sử dụng thông điệp HEAD để đảm bảo liên kết đến một đối tượng hợp lệ mà không tiêu tốn băng thông.

Cache trong trình duyệt cũng có thể sử dụng thông điệp HEAD để xem một đối tượng đã thay đổi hay không, nếu không thay đổi thì hiển thị thông tin đã được lưu trước đây, nếu thay đổi thì sẽ thực hiện GET để lấy dữ liệu về từ Server

1.3. Thông điệp HTTP

Các phần trước đã trình bày hoạt động của HTTP, và chúng ta đã xem xét từng thông điệp cụ thể. Không giống như các giao thức truyền thông khác, các thông điệp HTTP chủ yếu là các văn bản tiếng Anh. Thay vì lo lắng về các bit và byte, trong phần này chúng ta xem xét những từ mà HTTP định dạng.

Phần này sẽ trình bày cấu trúc tổng thể của thông điệp HTTP. Chúng ta sẽ thấy, một thông điệp HTTP bắt đầu với một “line” hay một mã trạng thái, có thể được theo sau bởi các tiêu đề (header) khác nhau và phần thân (body) của thông điệp.


1.3.1. Cấu trúc của thông điệp HTTP


HTTP có hai tác nhân là client và server. Các client gởi yêu cầu (request) và server trả lời (response). Vì vậy, chúng ta sẽ phân tích hai thông điệp chính là HTTP Requests và HTTP Responses.

a. HTTP Request

Hình 1.12 Cấu trúc thông điệp HTTP Request
Hình trên cho thấy cấu trúc cơ bản của HTTP Requests. Một HTTP Requests. bắt đầu bởi Request-Line. Request-Line có thể được theo sau bởi một hoặc nhiều header và body.

Để cụ thể hơn, hình bên dưới cho thấy một thông điệp http (dưới dạng văn bản) do Internet Explorer của Microsoft gửi khi người dùng truy cập vào trang www.ft.com. Dòng đầu tiên là Request-Line, và tiêu đề thông điệp tạo nên phần còn lại của văn bản.

Hình 1.13 Một ví dụ về nội dung thông điệp HTTP
Hình dưới phân tích cụ thể hơn Request-Line, bao gồm 3 phần: Method – phương thức của thông điệp, URI, và Version- phiên bản của HTTP
Hình 1.14 Ví dụ cụ thể về Request-Line
Phương thức (method) cụ thể xuất hiện đầu tiên trong Request-Line. Trong ví dụ trên đây là một phương thức GET
Mục tiếp theo trong Request-Line là Request-URI. Request-URI chứa nguồn tài nguyên cần truy cập. Trong ví dụ trên, Request-uri là (/), chỉ ra một yêu cầu đối với các nguồn tài nguyên gốc. Phần cuối cùng của Request-Line là phiên bản HTTP. Như ví dụ trên cho thấy, HTTP phiên bản 1.1.


b. HTTP Response:

Request Resonse bắt đầu bởi Status-Line (dòng mã trạng thái). Sau đó là phần thông tin của Header và một dòng trắng. Cuối cùng là phần body.
Hình 1.15 Cấu trúc thông điệp HTTP Response
Status-Line bắt đầu bởi số phiên bản của HTTP (trường hợp này là HTTP/1.1), sau đó là mã trạng thái(trường hợp này là 200 OK)
Hình 1.16 Cụ thể trường Status-Line

1.3.2. Các trường trong HTTP header
Như chúng ta đã thấy ở các phần trước, HTTP Request và HTTP Response có thể bao gồm một hoặc nhiều thông điệp header (message header). Message header bắt đầu với một tên trường và dấu hai chấm :)).
Như ví dụ trên, các Message header là Accept: , Accept-Language…

Trong HTTP header có rất nhiều trường đảm nhận các tính năng, mục đích khác nhau. Bài viết này chỉ mang tính giới thiệu nên sẽ không trình bày. Các bạn có thể tham khảo ở http://tools.ietf.org/html/rfc2068

Trích: khanh.com.vn

Nguồn: tanviet12 – hvaonline.net​
 

dayto.kdh

Administrator
PHẦN 2: MODSECURITY

2.1. GIỚI THIỆU MODSECURITY

ModSecurity là một Opensource web application firewall được Ivan Ristic phát triển dành cho Web Server Apache. Ivan Ristic cũng là tác giả quyển sách “Mod Security Handbook”. Ông là một người có rất nhiều kinh nghiệm trong bảo vệ Web Server Apache. Ông đã có nhiều thời gian nghiên cứu Web Application Security, Web Intrusion Detection, và Security Patterns. Trước khi chuyển sang lĩnh vực security, Ivan đã có nhiều năm làm việc như một Developer, System Architect, Technical Director trong phát triển phần mềm. Ông là người sáng lập ra công ty ThinkingStone làm các dịch vụ liên quan đến web application security.

Hiện tại ModSecurity sử dụng giấy phép GPL, hoàn toàn miễn phí.


2.2. CÁC KHẢ NĂNG CỦA MODSECURITY

http://kenhdaihoc.com/links.php?url=http://khanh.com.vn/image.axd?picture=webserver-mod-security-part2-01.jpg


Hình 2.1 Mô hình tổng quan của ModSecurity
  • Request filtering: Tất cả các request gửi đến web server đều được phân tích và cản lọc (filter) trước khi chúng được đưa đến các modules khác để xử lý
  • Understanding of the HTTP protocol: ModSecurity là một tường lửa ứng dụng nên nó có khả năng hiểu được giao thức HTTP. ModSecurity có khả năng cản lọc dựa trên các thông tin ở HTTP Header hay có thể xem xét đến từng thông số hay cookies của các request...vv
  • POST payload analysis: Ngoài việc cản lọc dựa trên HTTP Header, ModSecurity có thể dựa trên nội dung (payload) của POST requests.
  • Audit logging: Mọi requests đều có thể được ghi lại (bao gồm cả POST) để người quản trị có thể theo dõi nếu cần.
  • HTTPS filtering: ModSecurity có thể phân tích HTTPS.
    Compressed content filtering: ModSecurity sẽ phân tích sau khi đã giải nén các các dữ liệu được yêu cầu.
Hình 2.2 Quá trình xử lý các request của Apache và ModSecurity

Modsecurity cho phép chúng ta đặt rule tại một trong năm thời điểm trong chu kỳ xử lý của Apache như sau:

1. Phase Request Header: Rule được đặt tại đây sẽ được thực hiện ngay say khi Apache đọc request header, lúc này phần request body vẫn chưa được đọc.


2. Phase Request Body: Đây là thời điểm các thông tin chức năng chung đưa vào vào được phân tích và xem xét, các rule mang tính ứng dụng hướng kết nối (application-oriented) thường được đặt ở đây. Ở thời điểm này, Server đã nhận đủ các thông số của request và phần request body đã được đọc. Modsecurity hỗ trợ ba loại mã hoá request body

+ application/x-www-form-urlencoded: Dùng để truyền form dữ liệu
+ multipart/form-data: Dùng để truyền file
+ text/xml: Dùng để phân tích dữ liệu XML


3. Phase Response Header: Đây là thời điểm ngay sau khi phần response header được gửi trả về cho client. Chúng ta đặt rule ở đây nếu muốn giám sát quá trình sau khi phần response được gửi đi.


4. Phase Response Body: Đây là thời điểm chúng ta muốn kiểm tra những dữ liệu HTML gửi trả về.


5. Phase logging: Là thời điểm các hoạt động log được thực hiện, các rules đặt ở đây sẽ định rõ việc log sẽ như thế nào, nó sẽ kiểm tra các error message log của Apache. Đây cũng là thời điểm cuối cùng để chúng ta chặn các kết nối không mong muốn, kiểm tra các response header mà chúng ta không thể kiểm tra ở phase 3 và phase 4.


2.3. CÀI ĐẶT VÀ CẤU HÌNH

Trước khi cài đặt, chúng ta phải đảm bảo web server Apache đã hoạt động tốt. Distro Linux sử dụng là CentOS5 và phiên bản ModSecurity sử dụng là 2.5. Có thể thực hiện trên các Distro khác như Ubuntu, Fedora...


- Thực hiện tải mã nguồn về

# wget http://www.modsecurity.org/download/modsecurity-apache_2.5.11.tar.gz

- Thực hiện tra tính toàn vẹn của mã nguồn (việc này không bắt buộc nhưng chúng ta nên có thói quen kiểm tra để đảm bảo rằng mã nguồn đã không bị can thiệp vào dưới bất kỳ hình thức nào). Có thể sử dụng MD5 hay PGP để làm việc này. Ở đây sử dụng PGP


+ Đầu tiên cần download chữ ký :

# wget http://www.modsecurity.org/download/modsecurity-apache_2.5.11.tar.gz.asc

+ Download Publick Key:


# gpg --keyserver pgp.mit.edu --recv-key E77B534D

+ Kiểm tra chữ ký:
# gpg --verify modsecurity-apache_2.5.11.tar.gz.asc

...... gpg: Good signature from "Brian Rectanus (work) <[email protected]>" gpg: aka "Brian Rectanus <[email protected]>" gpg: aka "Brian Rectanus (personal) <[email protected]>"

- Kiểm tra thành công. Thực hiện giải nén mã nguồn:


# tar xfvz modsecurity-apache_2.5.11.tar.gz


Kiểm tra các gói thư viện cần thiết, ModSecurity yêu cầu có 4 thành phần sau trước khi biên dịch :


+ apxs : Kiểm tra bằng cách :

# whereis -b apxs

...... apxs: /usr/sbin/apxs

Nếu chưa có, chúng ta phải cài thêm gói httpd-devel (hay apache2-dev đối với dòng debian,ubuntu.. )


# yum install httpd-devel (hoặc apt-get install apache2-dev)


+ libxml2: Kiểm tra bằng cách :

# whereis -b libxml2

...... libxml2: /usr/lib/libxml2.a /usr/lib/libxml2.so /usr/include/libxml2

Nếu chưa có, chúng ta phải cài thêm gói libxml2-devel (hay libxml2-dev đối với debian,ubuntu...)


# yum install libxml2-devel (hoặc apt-get install libxml2-dev)


+ pcre: Kiểm tra bằng cách :

# whereis pcre

...... pcre: /usr/include/pcre.h /usr/share/man/man3/pcre.3.gz

Nếu chưa có thì chúng ta phải cài thêm gói pcre-devel :


# yum install pcre-devel (hoặc apt-get install pcre-dev)


+ mod_unique_id: Là mod thường đã được biên dịch cùng Apache. Có thể kiểm tra lại bằng cách tìm trong httpd.conf dòng:


LoadModule unique_id_module modules/mod_unique_id.so

Nếu chưa có, chúng ta phải thêm vào với nội dung như trên.


- Chuyển vào thư mục chứa mã nguồn và tiến hành biên dịch :


# cd modsecurity-apache_2.5.11/apache2/

+ Tạo Make file :

./configure ...... configure: creating ./config.status config.status: creating Makefile config.status: creating build/apxs-wrapper config.status: creating mlogc-src/mlogc-batch-load.pl config.status: creating t/run-unit-tests.pl config.status: creating t/run-regression-tests.pl config.status: creating t/gen_rx-pm.pl config.status: creating t/csv_rx-pm.pl config.status: creating t/regression/server_root/conf/httpd.conf config.status: creating ../tools/rules-updater.pl config.status: creating mlogc-src/Makefile config.status: creating mod_security2_config.h

+ Tiến hành biên dịch


# make


Sau khi biên dịch thành công file mod_security2.so sẽ được tạo ra trong thư mục libs.


- Tích hợp ModSecurity vào Apache

Để Apache nhận ra sự tồn tại của ModSecurity chúng ta cần copy mod_security2.so đến thư mục chứa
modules của apache, đối với distro CentOS là /etc/httpd/modules


# cp .libs/mod_security2.so /etc/httpd/modules/


Sửa lại file httpd.conf để thực hiện load module ModSecurity:


# vi /etc/httpd/conf/httpd.conf


Thêm dòng


LoadModule security2_module modules/mod_security2.so

- Quy định file cấu hình ModSecurity

Chúng ta có thể cấu hình trực tiếp các thông số và rule của ModSecurity vào file httpd.conf. Nhưng để cho rõ ràng và đảm bảo không sai sót trong quá trình thực hiện - gây ảnh hưởng Apache, Chúng ta nên tạo một file cấu hình riêng và sau đó include vào.
Trong CentOS các file cấu hình riêng mặc định chứa trong /etc/httpd/conf.d/
# vi /etc/httpd/conf.d/modsecurity.conf

Thêm vào các thông số cấu hình cơ bản


<IfModule security2_module> # Bat che do loc cua Modsecurity SecRuleEngine On # Thiet lap action mac dinh SecDefaultAction "phase:2,deny,log,status:404" # rule thu nghiem block tat ca request co uri chua "hacker" SecRule REQUEST_URI "hacker" </IfModule>

Thực hiện thử nghiệm để kiểm tra hoạt động của ModSecurity. Tiến hành tạo 2 file trong thư mục web, hacker.html và index.html chẳng hạn. Khi chúng ta truy cập vào file index.html thì trình duyệt trả về kết quả bình thường
Còn khi truy cập vào hacker.html thì trình duyệt báo lỗi :


404 – Forbidden
Đó là kết quả do ModSecurity đã chặn những URI có chứa chuỗi hacker và cũng đồng nghĩa với việc ModSecurity đã hoạt động.


2.4. VIẾT RULES

2.4.1. Cú pháp SecRule

SecRule được sử dụng để tạo các rule cho ModSecurity . Cú pháp rất đơn giản


SecRule Target Operator [Actions]

Target (mục tiêu)
: Quy định cụ thể mục tiêu của request hoặc response mà chúng ta muốn kiểm tra. Trong ví dụ kiểm cơ bản được đưa ra trong phần trước, sử dụng biến có tên REQUEST_URI, trong đó có các URI được request trên server, để nhận diện và chặn bất cứ Client nào truy cập vào các vị trí /hacker.html. Hiện có hơn 70 biến có thể được sử dụng để tạo rule.


Ngoài ra còn có một loại biến đặc biệt được gọi là biến collection có thể chứa nhiều đối số. Một ví dụ về collection làARGS, trong đó có chứa tất cả các đối số được truyền trong một chuỗi truy vấn hoặc thông qua một request POST.

Phần Operator xác định phương pháp và so sánh khớp dữ liệu để kích hoạt Action. Với Operator, mặc định là @rx

Cuối cùng, Actions (hành động) là một danh sách các hành động được thực hiện nếu phù hợp (matching) rule. Action có thể là allow (cho phép) hoặc deny (từ chối) các request; và quy định cụ thể các mã trạng thái (status code) khi trả về (response) cho client. Nếu không có action nào được quy định, các action mặc định của action SecDefaultAction sẽ được sử dụng (rule chứa action này thường được khai báo đầu tiên).


Để làm rõ hơn, chúng ta xem ví dụ. Giả sử chúng ta là một chủ doanh nghiệp nhỏ bán sách dạy nấu ăn ở định dạng file PDF trên website. Để lôi kéo khách hàng mua sách, chúng ta cung cấp một chương mẫu có chứa các công thức nấu ăn ngon nhất trong cuốn sách, mà họ có thể tải về miễn phí để xem trước khi quyết định mua.

Công việc kinh doanh đang ổn định, nhưng sau đó đột nhiên chúng ta nhận được đơn khiếu nại qua email nói rằng trang web của chúng ta rất chậm hoặc không truy cập được.


Khi nhìn vào log chúng ta nhận thấy rằng, một IP kết nối tới server web tràn ngập với các request cho các chương mẫu. Các chuỗi user-agent thấy được có tên Red Bullet Downloader . User-agent này của các chương trình Download nhanh.

Giải pháp đưa ra để giải quyết vấn đề này là dùng Mod Securiry để ngăn chặn các user-agent này download. Rules được viết như sau.

SecRule REQUEST_HEADERS:User-Agent "Red Bullet" "deny,nolog"
Trong ví dụ trên, REQUEST_HEADERS là một Collection chứa tất cả các trường trong thông điệp header (message header) được gởi đến bởi client và trong header này chứa User-agent. Vì vậy, ta sử dụng từ khoá cho user-agent là “Red Bullet” vì từ Red Bullet này thường xuyên xuất hiện trong các header được gởi đển từ client. Và Action là deny – là từ chối và nolog là không ghi lại log

2.4.1.1. Biến và bộ chọn lọc Collection

Hiện khoản hơn 70 biến có sẵn. ModSecurity sử dụng hai loại biến: biến Standard, đơn giản chỉ chứa một giá trị duy nhất, và biến Collection, có thể chứa nhiều hơn một giá trị. Một ví dụ về một Collection là REQUEST_HEADERS, trong đó chứa tất cả các trường trong thông điệp header mà Client gởi tới Server, chẳng hạn như User-agent hoặc Referer.

Để truy cập vào một trường trong collection, chúng ta ghi tên collection, tiếp theo là dấu hai chấm và sau đó là tên của trường hoặc tuỳ chọn mà chúng ta muốn truy cập. Ví dụ:


SecRule REQUEST_HEADERS:Referer "bad-referer.com"

Trong trường hợp kiểm tra toàn bộ dữ liệu trên tất cả các collection. Ví dụ, nếu chúng ta muốn kiểm tra sự hiện diện của chuỗi script có thể sử dụng rules sau đây:


SecRule ARGS "script"

Nếu muốn kiểm tra thêm các chuỗi truy vấn được gửi là username=john&login=yes , chúng ta có thể mở rộng rule bằng cách.


SecRule ARGS:john|ARGS:login "script"

Các collection có sẵn trong ModSecutity 2.5
- ARGS
- ENV
- FILES
- FILES_NAMES
- FILES_SIZES
- FILES_TMPNAMES
- GEO
- IP
- REQUEST_COOKIES
- REQUEST_COOKIES_NAMES
- REQUEST_HEADERS
- REQUEST_HEADERS_NAMES
- RESPONSE_HEADERS
- RESPONSE_HEADERS_NAMES
- SESSION
- TX
- USER


2.4.1.2. Chuyển đổi giữa các Collection


TX Collection còn được gọi là các Transaction collection. Chúng ta có thể sử dụng nó để tạo ra các biến phục vụ riêng cho mình.


SecRule REQUEST_URI “passwd” “pass,setvar:tx.hackscore=+5” SecRule TX:HACKSCORE “@gt 10” deny

Trong hai rule đầu tiên sử dụng action setvar để thiết lập các biến collection. Thực hiện tạo biến hackscore và tăng giá trị lên 5 nếu rule được thực thi (matching rule). Đến khi biến hackscore có giá trị bằng 10 thì thực thi rule thứ hai sẽ được thực thi với action là deny.

(Có thể loại bỏ biến bằng cách sử dụng setvar cú pháp setvar:!tx.hackscore)

2.4.1.3. Lưu trữ các Request

Có ba loại collection trong ModSecurity được sử dụng để lưu trữ liên tục( persistent storage). Như phần trước đã trình bày, setvar giúp tạo ra một biến và gán giá trị cho nó. Tuy nhiên, biến sẽ hết hạn và không còn nữa khi các request hiện tại đã được xử lý. Trong một số trường hợp chúng ta muốn lưu trữ giá trị biến và truy cập nó cho các request sau này, có thể sử dụng kiểu lưu trữ này.
Có ba collection có thể được sử dụng cho mục đích này:

- IP
- SESSION
- USER


Collection IP được sử dụng để lưu trữ thông tin về IP của người sử dụng. Nó có thể được sử dụng để lưu trữ IP ở các trường hợp như: Số lần truy cập không thành công vào tài nguyên trên server, hoặc số lượng các request của người dùng…

Trước khi sử dụng một trong các collection, chúng ta cần khởi tạo nó. Điều này được thực hiện bằng cách sử dụng các action initcol:

SecAction initcol:ip=%{REMOTE_ADDR},nolog,pass

Để thực hiện được rule trên, phải chắc chắn đã khai báo đường dẫn đến thư mục lưu trữ cho ModSecurity


SecDataDir /var/log/httpd/modsec_data

2.4.1.4. Kiểm tra nhiều biến

ModSecurity có thể kiểm tra nhiều biến cùng một lúc, mục đích để kết hợp so sánh (matching) một chuỗi.
Ví dụ:

SecRule ARGS|REQUEST_HEADERS "park" deny
Dấu (|) được sử dụng để tách các tên biến. Nó cũng có nhiều chức năng logic giống như “or” trong lập trình.

2.4.1.5. Sử dụng dấu “ khi viết rule
Chúng ta xem xét các rule sau

SecRule REQUEST_URI "secret" "deny" SecRule REQUEST_URI secret deny SecRule REQUEST_URI "secret place" deny

Hai rule đầu đều đúng và có tác dụng như nhau. Dấu (“) được sử dụng để chứa các cụm từ cách nhau bởi có dấu space. Các đơn từ thì có thể dùng hoặc không dùng.

Sử dụng (“) còn để nhóm các thông điệp ghi log.

SecRule REQUEST_URI "secret place" "deny,log,msg:'Someone tried to access the
secret place!'"

Nếu chúng ta muốn đặt dấu (‘) trong thông điệp cần ghi log. Thực hiện chèn dấu (\) trước dấu (‘).


SecRule REQUEST_URI "secret place" "deny,log,msg:'Someone\'s trying to hack us!'"

2.4.1.6. Tạo rule kết chuỗi – chain


Để kết hợp nhiều rule hoạt động liên tiếp với nhau, ta sử dụng chain.

Ví dụ: Người quản trị web server muốn chặn một số người download nhiều file gây ảnh hưởng đến web server, nhưng một số khách hàng khác cũng download mà không gây ảnh hưởng đến webserver bởi họ chỉ download vài file là xong và ta không chặn những người này. Và người quản trị server quyết định chặn những người có user-agent có chứa “Red Bullet” và IP của người này nằm trong dãy IP của một ISP xác định. Với từ chain trong action. Sử dụng nó, chúng ta có thể tạo ra một chain rule mà nếu phù hợp tất cả các rule trong chain thì action của chain sẽ được thực hiện.

Ví dụ đây là rule cấm người dùng với user-agent có từ “Red Bullet”


SecRule REQUEST_HEADERS:User-agent “Red Bullet” deny

Rule thứ hai là chỉ những client nằm trong dãy IP 192.168.1.0-192.168.1.255:


SecRule REMOTE_ADDR “^192\.168\.1\.”

Để thoả mãn điều kiện đặt ra như trên, ta sử dụng rule chain để kết hợp hai rule trên:


SecRule REQUEST_HEADERS:User-agent “Red Bullet” “chain,deny”
SecRule REMOTE_ADDR “^192\.168\.1\.”

Có thể thêm nhiều rule vào chain rule. Nếu chúng ta muốn thêm điều kiện là các rule chỉ hoạt động trước 6:00 giờ tối, ta sẽ thêm một rule thứ ba


SecRule REQUEST_HEADERS:User-agent “Red Bullet” “chain,deny” SecRule REMOTE_ADDR “^192\.168\.1\.” “chain” SecRule TIME_HOUR “@lt 18”

Từ @lt viết tắt của “less-than” là nhỏ hơn. Thuộc cú pháp so sánh số (matching number), sẽ được trình bày chi tiết ở phần 2.4.3.


2.4.1.7. Rule IDs


Chúng ta có thể quản lý các rule bằng cách đặt ID cho mỗi rule.


SecRule ARGS "login" "deny,id:1000"

Một số cú pháp thông thường


- SecRuleRemoveById:Gỡ bỏ rule có ID là
- SecRuleUpdateActionById: Cập nhật rule có ID là


2.4.2. Giới thiệu về biểu thức chính quy – Regular expressions

2.4.2.1. Ví dụ về các biểu thức chính quy

Bảng 2.1 Các biểu thức chính quy

Trong trường hợp muốn cả từ favorite và favourite đều đúng thì có thể dùng dấu chấm hỏi ? để quy định có thể có hoặc có thể không ký tự u. Cú pháp sẽ là favou?rite

Trường hợp trên đối với một ký tự u, nếu có nhiều hơn một ký tự chúng ta có thể nhóm lại bởi hai dấu ngoặc đơn (). Ví dụ với hai từ previous và previously. Cú pháp sẽ là previous(ly)?

2.4.2.2. Các biểu thức chính quy khác


Bảng 2.2 Các biểu thức chính quy khác

Vd:


SecRule REMOTE_USER "@within tim,john,alice"

2.4.2.3. Sử dụng @ rx để chặn một server từ xa


Ví dụ chúng ta có 2 rule như sau


# Rule 1 SecRule REMOTE_HOST "@rx \.microsoft\.com$" deny # Rule 2 SecRule REMOTE_HOST "\.microsoft\.com$" deny

Cả hai rule đề có tác dụng như sau là chặn các host truy cập từ xa từ tập đoàn Microsoft. Mục tiêu của @rx mà bỏ qua rule thứ hai bởi hai rule đều có mục đích như nhau.


2.4.3. So sánh số (matching number)


Bảng 2.3 So sánh số

2.4.4. Phases và sắp xếp rule


Điều quan trọng là hiểu được việc sắp xếp rule của ModSecurity. Điều này tránh các tình huống mà mọi phương thức, hoạt động đều
bất ngờ bị chặn(deny) hoặc cho phép (allow) trái với ý định.


Có 5 giai đoạn (phase)


1. REQUEST_HEADERS (phase 1)
2. REQUEST_BODY (phase 2)
3. RESPONSE_HEADERS (phase 3)
4. RESPONSE_BODY (phase 4)
5. LOGGING (phase 5)


Một rule được thực hiện đúng từng phase theo thứ tự . Điều này có nghĩa là ModSecurity duyệt tất cả các rule trong phase 1 ("REQUEST_HEADERS"). Sau đó, đến phase 2…


Trong mỗi phase, rule được xử lý theo thứ tự mà chúng xuất hiện trong các tập tin cấu hình. Chúng ta có thể hiểu khi có action, ModSecurity sẽ duyệt các tập tin năm lần, một lần cho từng phase.


Trong thời gian xử lý ModSecurity chỉ xem xét rule thuộc pha hiện đang xử lý, và những rule được áp dụng theo thứ tự chúng xuất hiện trong các tập tin cấu hình.


Phase LOGGING đặc biệt ở chỗ nó luôn luôn được thực hiện cả khi request đã được cho phép hay từ chối trong các phase trước đó. Ngoài ra, một khi phase LOGGING bắt đầu, chúng ta không thể thực hiện bất kỳ action ngăn chặn nào vì response đã được gửi cho người truy cập.


Vì vậy, chúng ta phải cẩn thận không để cho bất kỳ action nào trái quy định được truyền vào rule ở phase 5. Nếu không sẽ gây lỗi làm Apache không khởi động được. Nếu chúng ta đặt rule sau đây trước các rule thuộc phase 5 sẽ ngăn chặn được lỗi này xảy ra. (nhưng phải đặt sau các rule của phase trước đó).


SecDefaultAction "phase:5,pass"

2.4.5. Chức năng chuyển đổi


ModSecurity cung cấp một số chức năng chuyển đổi mà chúng ta có thể áp dụng cho các biến và các collection. Những biến đổi được thực hiện trên một bản sao của dữ liệu được kiểm tra, có nghĩa là các HTTP request hoặc response ban đầu vẫn được giữ nguyên, không thay đổi.


Chức năng này rất quan trọng. Nếu chúng ta muốn phát hiện tấn công XSS (cross-site scripting), chúng ta phải phát hiện mã JavaScript bất kể trường hợp nó được viết in hay viết thường. Để làm điều này, chức năng chuyển đổi có thể được áp dụng để so sánh một chuỗi viết hoa với chuỗi viết thường.


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

Rule trên sẽ chặn tất cả các URL chứa chuỗi >;<;script bất kể chữ hoa thường, vd sCript; >;<;scripT ..



Bảng 2.4 Một số chức năng chuyển đổi của ModSecurity


2.4.5.1. Thiết lập so sánh với @pm và @pmFromFile


Vd: thay vì sử dụng red|blue|green ta có thể sử dụng


SecRule ARGS "@pm red green blue" deny

Nếu có quá nhiều chuỗi muốn đặt vào, ta có thể liệt kê các chuỗi này vào một file và dùng @pmFromFile


Vd: Trong file /usr/log/alo.txt chứa nội dung red green blue yellow magenta cyan orange maroon pink black white gray grey violet purple brown tan olive. Ta có rule:


SecRule ARGS “@pmFromFile /usr/log/alo.txt”


2.4.6. Khoá một số request thông thường


Giả sử một website khai báo thuế của chính phủ muốn tăng độ bảo mật, website này chỉ mở cửa vào ban ngày (từ 8 giờ sáng đến 5 giờ chiều). Chúng ta có thể sử dụng biến TIME_HOUR cùng với biểu thức chính quy để thực hiện rule này.


SecRule TIME_HOUR !^(8|9|10|11|1213|14|15|16|17)$ deny


2.4.7. Khoá một số request không thông thường


Ba phương thức (method) HTTP thường được sử dụng cho request là GET, POST và HEAD. Chúng ta có thể ngạc nhiên khi biết rằng HTTP thực sự thực có rất nhiều phương thức, nếu một web server hỗ trợ WebDAV (Web-based Distributed Authoring và Versioning), tổng số method trở nên gần như 30.


Ví dụ, ở đây là những phương thức request thực hiện bởi phiên bản mới nhất của Apache:


Bảng 2.5 Các phương thức request của Apache

Trừ khi chúng ta có một lý do nào đó để cho phép một số phương thức không phổ biến được vận hành. Các phương thức không phổ biến còn lại nên ngăn chặn để đề phòng các lỗ hổng trong Apache gây ra bở các phương thức này.

Ví dụ: về ngăn chặn tất cả phương thức request không thông thường, chỉ để lại GET, POST, HEAD.

SecRule REQUEST_METHOD “!^(GET|POST|HEAD)” “deny,status:405”


2.4.8. Phát hiện rò rỉ thẻ tín dụng

2.4.8.1. Phát hiện rò rỉ thẻ tín dụng

Giả sử website bán hàng của chúng ta có chứa thông tin nhạy cảm của khách hàng như địa chỉ, số thẻ tín dụng… mà họ cung cấp khi mua hàng. Sẽ rất nguy hiểm nếu hacker có thể khai thác các lỗ hổng của website và xem được những thông tin này.

Cụ thể, một số lỗi như SQL injection, hacker có thể làm cho các thông tin này hiển thị trên website. Rất may mắn, ModSecurity có thể giải quyết vấn đề trên.

Ý tưởng là viết rule để kiểm tra HTTP response. ModSecurity có chứa một toán tử gọi là @verifiCC dùng để kiểm tra một chuỗi số có phải là số thẻ tín dụng hay không. Nếu toán tử trả về true, chúng ta có thể chặn các response không cho gởi đến hacker, bởi vì nó có thể chứa số thẻ tín dụng. Ví dụ một rule như sau


SecResponseBodyAccess On SecRule RESPONSE_BODY "@verifyCC \d{13,16}" "phase:4,deny,t:removeWhitespace,log,
msg:'Possible credit card number leak detected'"
Chú thích: {13,16} nghĩa là kiểm tra các dãy số từ 13 đến 16 chữ số (số thẻ tín dụng từ 13 đến 16 số)

2.4.8.2. Thuật toán Luhn – Kiểm tra số thẻ tín dụng


ModSecurity sử dụng thuật toán Luhn để kiểm tra một dãy số liệu có phải là số thẻ tín dụng hay không
Thuật toán này rất đơn giản. Chúng ta có một dãy số được xem xét có phải là số thẻ tín dụng hay không. Thực hiện đảo ngược dãy số, rồi lần lượt nhân số thứ nhất với 1, số thứ hai với 2, số thứ ba với 1, số thứ tư với 2…. Nhân đến khi hết dãy số. Sau đó tách các kết quả thu được thành các số riêng biệt có một chữ số. Rồi cộng các số này lại. Nếu kết quả đạt được chia hết cho 10 thì dãy số đó là số thẻ tín dụng.


Để rõ hơn chúng ta xem một ví dụ. Xét số thẻ tín dụng 4012888888881881. Thực hiện đảo ngược dãy số thành 1 88 1 8 8 8 8 8 8 8 8 2 1 0 4



Kết quả đạt được là chuỗi 116828168168168162208.
Cộng từng chữ số lại ta được kết quả 90
1+1+6+8+2+8+1+6+8+1+6+8+1+6+8+1+6+2+2+0+8 = 90

Kết quả 90 chia hết cho 10, vì vậy dãy số 4012888888881881 là số thẻ tín dụng.


2.4.9. Theo dõi vị trí địa lý của khách truy cập


Một địa chỉ IP có thể cung cấp thông tin về địa điểm của người truy cập vào web server trên bản đồ thế giới. Với phiên bản 2.5, ModSecurity hỗ trợ kiểm tra vị trí địa lý của khách truy cập bằng cách tham chiếu đến một cơ sở dữ liệu địa lý (cụ thể là quốc gia).

Điều này rất hữu ích cho nhiều ứng dụng. Nếu như chúng ta xử lý thanh toán thẻ tín dụng và muốn vị trí người truy cập phải phù hợp với vị trí địa lý (các quốc gia) mà thẻ tín dụng đã được ban hành. Nếu một thẻ tín dụng Việt Nam đột nhiên được sử dụng tại Đài Loan, chúng ta có thể nghi ngờ và từ chối đơn đặt hàng này.
ModSecurity sử dụng GEO collection để lưu trữ thông tin địa lý. Chúng ta hãy xem xét kỹ hơn collection này và các trường mà nó hỗ trợ.

2.4.9.1. Các trường trong collection GEO

- COUNTRY_CODE
- COUNTRY_CODE3
- COUNTRY_NAME
- COUNTRY_CONTINEN
- REGION
- CITY
- POSTAL_CODE
- LATITUDE
- LONGITUDE
- DMA_CODE (US only)
- AREA_CODE (US only)


Trường COUNTRY_CODE là mã quốc gia gồm hai chữ cái theo tiêu chuẩn ISO 3166. Ví dụ, mã quốc gia của Hoa Kỳ là US. COUNTRY_CODE3 chứa mã quốc gia ba ký tự, ví dụ Hoa Kỳ là USA. Trường COUNTRY_CONTINENT chứa châu lục, ví dụ như EU cho người sử dụng từ châu Âu và AS cho châu Á.



2.4.9.2. Cấm các người dùng từ các quốc gia được chỉ định


Đầu tiên, chúng ta cần download GEO database. Thực hiện theo các bước

1. Truy cập vào http://www.maxmind.com và click vào GeoLocation Technology.
2. Click vào GeoLite Country, với phiên bản miễn phí của database.
3. Copy link các phiên bản nhị phân (binary)của GeoLite database.

Sử dụng wget để download về,

wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz gunzip GeoIP.dat.gz mkdir /usr/local/geoip mv GeoIP.dat /usr/local/geoip
Ví dụ. Viết rule để chặn các khách truy cập từ Nga(RU) Pakistan(PK) và Trung Quốc(TQ)

SecGeoLookupDb "/usr/local/geoip/GeoIP.dat" SecRule REMOTE_ADDR “@geoLookup” “deny,nolog,chain,status:500” SecRule GEO:COUNTRY_CODE “@pm RU PK CN”

Để chặn nhiểu quốc gia hơn, có thể dùng @pmFromFile thay cho @pm


2.4.9.3. Cân bằng tải giữa các server trên các châu lục khác nhau


Nếu chúng ta đang cung cấp dữ liệu cho khách truy cập download, chúng ta sẽ tính đến bài toán để người truy cập có được tốc độ download tốt nhất có thể. Giả sử chúng ta có một Server ở Mỹ và một Server ở châu Âu. Bằng cách sử dụng ModSecurity với operator là @geoLookup, ta có thể xác định nơi khách truy cập và chuyển vị trí download đến server gần nhất, vì vậy tốc độ download sẽ cải thiện cũng như cân bằng tải cho Server. Rule trong trường hợp này được viết như sau:


SecRule REQUEST_URI “^/download/(.*)$” “phase:1,capture,chain,
redirect:http://sveu.example.com/download/%{TX.1}” SecRule REMOTE_ADDR “@geoLookup” “chain” SecRule GEO:COUNTRY_CONTINENT “@streq EU”
Rule đầu tiên sẽ phù hợp với bất kỳ request nào đến thư mục /download/. Sử dụng dấu chấm(.) và dấu sao để đại diện cho tất cả các file có trong thư mục. ModSecurity sẽ nắm bắt tất cả các giá trị này và lưu nó vào trong biếnTX:1. Nếu người truy cập từ Châu Âu, ModSecurity sẽ chuyển hướng request đến server sveu.example.com với đường dẫn thư mục và file request như REQUEST _URI ở rule đầu tiên.

2.4.10. Thực hiện các shell scripts với ModSecurity


ModSecurity có thể thực thi một shell scripts khi khớp (math) với một rule. Điều này được thực hiện thông qua actions exec() . Đây là một kỹ thuật rất mạnh cho phép chúng ta sử dụng toàn bộ sức mạnh của shell scripts khi một rules được kích hoạt.

Các file shell scripts phải được thực thi bởi user Apache, vì vậy phải chắc chắn rằng user Apache có quyền thực thi scripts. Nếu thực hiện shell scripts không thành công, ModSecurity sẽ ghi lỗi vào file log lỗi của Apache. Dưới đây là một số ứng dụng thông thường khi sử dụng Modsecurity thực hiện Shell scripts.

2.4.10.1. Giởi email cảnh báo


Ví dụ, giả sử rằng chúng ta muốn thực hiện một script để gởi cho người quản trị web server email cảnh báo ModSecurity phát hiện hacker đang khai thác lỗi SQL injection. Để làm điều này, chúng ta cần hai bước:


1. Viết một file script có khả năng gởi email cảnh báo đến một địa chỉ email chỉ định.
2. Một rule có tác dụng sẽ gọi script khi phát hiện tấn công.


Đối với script, chúng ta có thể sử dụng một standard shell scrip gọi /bin/sh, (có thể sử dụng Perl script hoặc bất kỳ ngôn ngữ khác). Vd ở đây sử dụng standard shell script và gửi email thông báo cho[email protected]
Tạo một file có tên email.sh trong thư mục /usr/local/bin có nội dung


#!/bin/sh echo "Mot cuoc tan cong sql injection da bi chan"|mail –s "ModSecurity Alert"
<a href="mailto:[email protected]">[email protected]</a> echo Done.
Nếu được kích hoạt, script sẽ gởi email đến địa chỉ [email protected] với tiêu đề ModSecurity Alert. Cuối script là chuỗi Done để ModSecurity nhận biết đã thực thi script thành công.

Tiếp theo, viết rule để kích hoạt script khi có tấn công sql injection


SecRule ARGS “drop table” “deny,exec:/usr/local/bin/email.sh”

Bây giờ chúng ta có thể thử nghiệm rule bằng cách truy cập vào đường dẫn http://example.com/test=drop%20table.



2.4.10.2. Gởi nhiều thông tin hơn đến email


Email cảnh báo có thể rất hữu ích cho người quản trị web server để nhanh chóng khắc phục được sự cố khi gặp tấn công…Tuy nhiên, chúng ta có thể làm cho các email được gởi chứa nhiều thông tin hơn về cuộc tấn công (các thông tin như IP, request URI,..).

ModSecurity cho phép chúng ta thiết lập các biến môi trường thông qua action setenv. Giả sử chúng ta muốn thu thập các thông tin sau khi phát hiện tấn công SQL injection:
- Tên máy của server nơi xảy ra cảnh báo
- Địa chỉ IP và tên máy của hacker
- Các request URI
- Các giá trị của tất cả các đối số, cho dù được gửi bằng phương thức GET hay POST
- Các ID của request để chúng ta dễ dàng tìm thấy đoạn request trong file log,


Đặt các thông tin trên vào sáu biến môi trường riêng biệt: HOSTNAME, REMOTEIP, REMOTEHOST, REQUESTURI, ARGS, và UNIQUEID.
Rule được viết như sau:


SecRule ARGS "drop table" "deny,t:lowercase,setenv:HOSTNAME=%{SERVER_NAME},
setenv:REMOTEIP=%{REMOTE_ADDR},
setenv:REQUESTURI=%{REQUEST_URI},setenv:ARGS=%{ARGS}, setenv:UNIQUEID=
{%UNIQUE_ID},exec:/usr/local/bin/email.sh"

File shell script được viết lại như sau


#!/bin/sh echo "Mot cuoc tan cong sql injection da bi chan: Server: $HOSTNAME Attacking IP: $REMOTEIP Attacking host: $REMOTEHOST Request URI: $REQUESTURI Arguments: $ARGS Unique ID: $UNIQUEID Time: `date '+%D %H:%M'` "|mail –s 'ModSecurity Alert' <a href="mailto:[email protected]">
[email protected]</a> echo Done.


2.4.10.3. Chặn tấn công đoán mật khẩu – brute-force

Bây giờ chúng ta sẽ dùng collection IP để chặn tấn công brute-force. Dưới đây là một rule viết để chặn tấn công brute-fore.

# Khoi tao ip collection SecAction "initcol:ip=%{REMOTE_ADDR},pass,phase:1" # kiem tra truy cap den thu muc administrator SecRule REQUEST_URI "^/administrator/" "pass,phase:1,setvar:ip.attempts=+1,
expirevar:ip.attempts=600" # Da duoc xac thuc hay chua? SecRule REQUEST_URI "^/administrator/" "chain,pass,phase:3" # Neu da duoc xac thu, set counter to 0 SecRule RESPONSE_STATUS "^2..$" "setvar:ip.attempts=0" # Deny neu 5 lan xac thuc khong thanh cong SecRule IP:ATTEMPTS "@gt 5" "phase:1,deny"


2.4.11. Chèn dữ liệu vào response

ModSecurity cho phép chúng ta đưa dữ liệu vào response gửi lại cho client nếu SecContentInjection được thiết lập On. Được sử dụng để đưa ra một lời cảnh báo cho hacker khi hành động tấn công được phát hiện.
Với ví dụ dưới đây, chúng ta sẽ đưa ra thông báo “Hoc di dung hack nua!” khi ModSecurity phát hiện tấn công XSS.

SecContentInjection On SecRule ARGS:username "%" "phase:1,allow,t:urlDecode,append:'>
<script type=text/javascript>alert(\"Hoc di dung hack nua!\");</script>',log,msg
:'phat hien tan cong'"



Hình 2.3 Ví dụ về chèn dữ liệu vào Response


2.4.12. Kiểm tra các tập tin được upload lên

Một tính năng rất hữu ích ModSecurity là khả năng kiểm tra các file đã được upload lên thông qua một POST request.
Vì vậy, chỉ cần thiết lập RequestBodyBuffering On là chúng ta có thể kiểm tra chúng bằng cách sử dụng toán tử @inspectFile.
Cần viết một shell script chặn các file được upload lên và quét chúng bằng ClamAV. ClamAV là một antivirus được sử dụng rất phổ biến trên môi trường Unix http://clamav.net) Khi ClamAV đã được cài đặt, sử dụng lệnh clamscan <tenfile> để quét file.
Đầu tiên cần thiết lập vị trí thư mục lưu file tạm

SecUploadDir “/tmp/mosecurity” SecTmpDir “/tmp/mosecurity”

Lưu ý: User apache phải có quyền read và write trên thư mục trên


Tiếp theo viết script /usr/local/bin/filescan.sh để thực hiện quét mã độc khi có file upload lên server.


#!/bin/sh /usr/bin/clamscan $1 > /dev/null 2>&1 if [ "$?" -eq "1" ]; then echo "An infected file was found!" fi

Dòng đầu tiên của script để kích hoạt ClamAV quét thư mục /tmp/ModSecurity. Câu lệnh tiếp theo sẽ kiểm tra giá trị trả về của lệnh thực hiện trước. ClamAV sẽ trả về 1 nếu virus được tìm thấy và 0 nếu ngược lại.

Dưới đây là Rule để chặn các file được upload lên và kích hoạt script quét virus.

SecRule FILES_TMPNAMES “@inspectFile /usr/local/bin/filescan.sh”
“phase:2,deny,status:418”
Trích từ: khanh.com.vn
Nguôn:tanviet12 – hvaonline.net
 

dayto.kdh

Administrator
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.



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.


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ặntấ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


Trích: khanh.com.vn
Nguồn: tanviet12 – hvaonline.net​
 
xây nhà trọn gói tại quảng ngãi xây nhà trọn gói quảng ngãi xây nhà trọn gói tại quảng ngãi nội thất quảng ngãi
Top