2013-08-15 37 views
6

Câu hỏi này không phải là về bảo vệ chống lại các cuộc tấn công SQL injection. Câu hỏi đó đã được trả lời nhiều lần trên StackOverflow và tôi đã thực hiện các kỹ thuật. Đây là về việc dừng số lần thử.18.000 nỗ lực tiêm MySQL mỗi ngày: Ngừng các nỗ lực

Gần đây, trang web của tôi đã bị tấn công với số lượng lớn các cuộc tấn công tiêm. Ngay bây giờ, tôi bẫy chúng và trả lại một trang tĩnh.

Đây là những gì URL của tôi trông giống như:

/products/product.php?id=1 

Đây là những gì một cuộc tấn công trông giống như:

/products/product.php?id=-3000%27%20IN%20BOOLEAN%20MODE%29%20UNION%20ALL%20SELECT%2035%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C%27qopjq%27%7C%7C%27ijiJvkyBhO%27%7C%7C%27qhwnq%27%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35--%20 

Tôi biết chắc chắn rằng đây không phải chỉ là một liên kết xấu hoặc chất béo ngón tay đánh máy vì vậy tôi không muốn gửi chúng đến trang tổng quan. Tôi cũng không muốn sử dụng bất kỳ tài nguyên nào trên trang web của mình cung cấp các trang tĩnh.

Tôi đang xem xét việc để trang chết với die(). Có điều gì sai trái với cách tiếp cận này không? Hoặc là có một mã trả về HTML mà tôi có thể thiết lập với PHP mà sẽ thích hợp hơn?

Chỉnh sửa:

Dựa trên một vài nhận xét bên dưới, tôi đã tìm cách trả về 'không tìm thấy trang'. Stack Overflow này answer bởi icktoofay gợi ý sử dụng 404 và sau đó là die(); - bot nghĩ rằng không có trang và thậm chí có thể biến mất và không còn tài nguyên nào được sử dụng để hiển thị thông báo không tìm thấy trang.

header("HTTP/1.0 404 Not Found"); 
die(); 
+1

chỉ sử dụng báo cáo đã chuẩn bị – bksi

+0

Trả lại lỗi 403 có thể hơi thích hợp. – zebediah49

+0

Bạn có cân bằng tải F5 trước máy chủ không? – Colyn1337

Trả lời

6

Lọc những nỗ lực tiêm có khả năng là những gì mod_security là dành cho.

Có thể mất khá nhiều công sức để định cấu hình để nhận ra yêu cầu hợp pháp cho ứng dụng của bạn.

Một phương pháp phổ biến khác là chặn địa chỉ IP của khách hàng độc hại khi bạn phát hiện ra chúng.

+0

Cảm ơn. Tôi sẽ xem xét nó. Địa chỉ IP thay đổi thường xuyên, do đó không khả thi. – JScarry

+1

Tính khả thi. Xác định một đặc điểm của những yêu cầu này là điều cực kỳ khó xảy ra hoặc không thể cho người dùng thường xuyên kích hoạt, sau đó cấm các IP ngay lập tức khi họ truy cập nó. – tadman

+0

Tôi nhận được một lưu ý ẩn danh. Downvoter, bạn có thể xin vui lòng để lại một bình luận để cho tôi biết lý do tại sao bạn nghĩ rằng câu trả lời này là không tốt? Có lẽ tôi có thể cải thiện nó. –

1

Bạn có thể cố gắng ngăn lưu lượng truy cập này đến máy chủ của bạn bằng phần cứng. Hầu hết các thiết bị kiểm tra gói có thể được sử dụng. Tôi sử dụng một F5 cho mục đích này (trong số những người khác). F5 có một ngôn ngữ kịch bản của riêng nó được gọi là iRules mà kiểm soát tuyệt vời và tùy biến.

+0

Tôi đang sử dụng máy chủ riêng ảo nên tôi không nghĩ đó là một tùy chọn, nhưng tôi sẽ xem xét những gì họ cung cấp. – JScarry

-1

Câu hỏi rất hay 1 từ tôi và câu trả lời không hề đơn giản.

PHP không cung cấp cách duy trì dữ liệu cho các trang khác nhau và các phiên khác nhau, do đó bạn không thể giới hạn quyền truy cập theo địa chỉ IP trừ khi bạn lưu trữ chi tiết truy cập ở đâu đó.

Nếu bạn không muốn sử dụng kết nối cơ sở dữ liệu, bạn có thể sử dụng hệ thống tệp. Tôi chắc rằng bạn đã biết cách thực hiện điều này, nhưng bạn có thể xem ví dụ tại đây:

DL's Script Archives 
http://www.digi-dl.com/ 
(click on "HomeGrown PHP Scripts", then on "IP/networking", then 
on "View Source" for the "IP Blocker with Time Limit" section) 

Tùy chọn tốt nhất được sử dụng là "mod_throttle". Sử dụng điều đó, bạn có thể hạn chế mỗi địa chỉ IP để truy xuất mỗi năm giây bằng cách thêm chỉ thị này để tập tin cấu hình Apache của bạn:

<IfModule mod_throttle.c> 
    ThrottlePolicy Request 1 5 
</IfModule> 

Nhưng có một số tin xấu.Tác giả của mod_throttle đã từ bỏ sản phẩm:

"Snert's Apache modules currently CLOSED to the public 
    until further notice. Questions as to why or requests 
    for archives are ignored." 

Mô-đun apache khác, mod_limitipconn, được sử dụng thường xuyên hơn hiện nay. Nó không cho phép bạn thực hiện các hạn chế tùy ý (chẳng hạn như "không quá mười yêu cầu trong mỗi mười lăm giây"). Tất cả những gì bạn có thể làm là giới hạn từng địa chỉ IP cho một số kết nối đồng thời nhất định. Nhiều quản trị viên web dường như đang ủng hộ đó là một cách tốt để chống lại spam bot, nhưng dường như nó không linh hoạt hơn mod_throttle.

Bạn cần phiên bản khác nhau của mod_limitipconn tùy phiên bản Apache bạn đang chạy:

mod_limitipconn.c - for Apache 1.3 
http://dominia.org/djao/limitipconn.html 

mod_limitipconn.c - Apache 2.0 port 
http://dominia.org/djao/limitipconn2.html 

Cuối cùng, nếu máy chủ Apache của bạn được lưu trữ trên một máy Linux, có một giải pháp bạn có thể sử dụng mà không liên quan đến biên dịch lại hạt nhân. Thay vào đó, nó sử dụng các quy tắc tường lửa "iptables". Phương pháp này khá thanh lịch và đủ linh hoạt để áp đặt các ràng buộc như "không quá ba kết nối từ IP này trong một phút". Dưới đây là cách thực hiện:

Linux Noob forums - SSH Rate Limit per IP 
http://www.linux-noob.com/forums/index.php?showtopic=1829 

Tôi nhận thấy rằng không có tùy chọn nào trong số này là lý tưởng, nhưng chúng minh họa những gì có thể. Có lẽ sử dụng một cơ sở dữ liệu địa phương sẽ kết thúc tốt nhất sau khi tất cả? Trong mọi trường hợp, hãy nhớ rằng chỉ đơn giản là hạn chế tốc độ yêu cầu, hoặc hạn chế băng thông, không giải quyết được vấn đề của bot. Họ có thể mất nhiều thời gian hơn, nhưng cuối cùng họ sẽ tiêu hao càng nhiều tài nguyên càng tốt nếu họ không bị chậm lại. Nó thực sự cần thiết để từ chối yêu cầu HTTP của họ, không chỉ đơn giản là trì hoãn chúng hoặc lây lan chúng ra.

Chúc bạn may mắn trong cuộc chiến leo thang giữa nội dung và spam!

0

Bài đăng đã được bỏ chặn, vì vậy tôi nghĩ rằng tôi sẽ chia sẻ những gì tôi đã làm để giảm các cuộc tấn công từ cùng địa chỉ IP. Tôi vẫn nhận được một nửa tá một ngày, nhưng họ thường chỉ cố gắng một lần hoặc hai lần từ mỗi địa chỉ IP.

Lưu ý: Để trả lại thông báo lỗi 404, tất cả điều này phải đến trước khi bất kỳ HTML nào được gửi. Tôi đang sử dụng PHP và chuyển hướng tất cả các lỗi đến một tệp lỗi.

<?php 
require_once('mysql_database.inc'); 

// I’m using a database, so mysql_real_escape_string works. 
// I don’t use any special characters in my productID, but injection attacks do. This helps trap them. 
$productID = htmlspecialchars((isset($_GET['id']) ? mysql_real_escape_string($_GET['id']) : '55')); 

// Product IDs are all numeric, so it’s an invalid request if it isn’t a number. 
if (!is_numeric($productID)) { 
    $url = $_SERVER['REQUEST_URI']; // Track which page is under attack. 
    $ref = $_SERVER['HTTP_REFERER']; // I display the referrer just in case I have a bad link on one of my pages 
    $ip = $_SERVER['REMOTE_ADDR']; // See if they are comng from the same place each time 

    // Strip spaces just in case they typed the URL and have an extra space in it 
    $productID=preg_replace('/[\s]+/','',$productID); 
    if (!is_numeric($productID)) { 
     error_log("Still a long string in products.php after replacement: URL is $url and IP is $ip & ref is $ref"); 
     header("HTTP/1.0 404 Not Found"); 
     die(); 
    } 
} 

Tôi cũng có nhiều trang nơi tôi hiển thị nội dung khác nhau tùy thuộc vào danh mục được chọn. Trong những trường hợp này, tôi có một loạt các câu lệnh if, như là nếu ($ cat == 'Speech') {} Không có tra cứu cơ sở dữ liệu, vì vậy không có cơ hội tiêm SQL, nhưng tôi vẫn muốn dừng các cuộc tấn công chứ không phải lãng phí băng thông hiển thị một trang mặc định cho một bot. Thông thường danh mục là một từ ngắn nên tôi sửa đổi is_numeric có điều kiện ở trên để kiểm tra độ dài chuỗi, ví dụ: nếu (strlen ($ cat)> 10) Vì hầu hết các nỗ lực có nhiều hơn 10 ký tự, chúng hoạt động khá tốt.

Các vấn đề liên quan