2013-08-15 20 views
6

Questa domanda non riguarda la protezione dagli attacchi SQL injection. Quella domanda ha ricevuto risposta molte volte su StackOverflow e ho implementato le tecniche. Si tratta di interrompere i tentativi .18.000 tentativi di iniezione MySQL al giorno: interruzione dei tentativi

Recentemente il mio sito è stato colpito da un numero enorme di attacchi di iniezione. In questo momento, li intrappolano e restituisco una pagina statica.

Ecco ciò che il mio URL appare come:

/products/product.php?id=1 

Questo è ciò che un attacco assomiglia:

/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 

so per certo che questo non è solo un cattivo collegamento o il grasso dalle dita digitando quindi non voglio inviarli a una pagina panoramica. Inoltre, non voglio utilizzare alcuna risorsa sul mio sito che fornisce pagine statiche.

Sto considerando di lasciare che la pagina muoia con die(). C'è qualcosa di sbagliato in questo approccio? O c'è un codice di ritorno HTML che posso impostare con PHP che sarebbe più appropriato?

Edit:

Sulla base di un paio di commenti qui sotto, ho guardato come restituire 'pagina non trovata'. Questo Stack Overflow answer di icktoofay suggerisce di usare un 404 e quindi il dado(); - il bot pensa che non ci sia una pagina e potrebbe anche sparire, e non vengono più utilizzate risorse per visualizzare un messaggio non trovato nella pagina.

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

è sufficiente utilizzare le istruzioni preparate – bksi

+0

Il ripristino di un errore 403 potrebbe essere un po 'appropriato. – zebediah49

+0

Avete un sistema di bilanciamento del carico F5 prima del server? – Colyn1337

risposta

6

Filtrare i probabili tentativi di iniezione è ciò che è mod_security.

Può essere necessario un bel po 'di lavoro per configurarlo per riconoscere richieste legittime per la tua app.

Un altro metodo comune è bloccare gli indirizzi IP dei client dannosi quando li si rileva.

+0

Grazie. Lo esaminerò. Gli indirizzi IP cambiano frequentemente, quindi non è fattibile. – JScarry

+1

È fattibile. Identifica una caratteristica di queste richieste che è estremamente improbabile o impossibile da far scattare agli utenti regolari, quindi batta immediatamente gli IP quando inciampano. – tadman

+0

Ho ottenuto un downvote anonimo. Downvoter, puoi lasciare un commento per dirmi perché pensi che questa risposta non sia buona? Forse posso migliorarlo. –

1

È possibile tentare di impedire che questo traffico raggiunga il server con l'hardware. La maggior parte dei dispositivi che eseguono l'ispezione dei pacchetti può essere utile. Io uso un F5 per questo scopo (tra gli altri). La F5 ha un linguaggio di scripting proprio chiamato iRules che offre un grande controllo e personalizzazione.

+0

Sto utilizzando un server virtuale privato, quindi non penso che sia un'opzione, ma esaminerò ciò che offrono. – JScarry

-1

Una buona domanda +1 da parte mia e la risposta non è semplice.

PHP non fornisce il modo di conservare i dati per pagine diverse e sessioni diverse, quindi non è possibile limitare l'accesso tramite indirizzo IP a meno che non si memorizzino i dettagli di accesso da qualche parte.

Se non si desidera utilizzare una connessione al database per questo, è ovviamente possibile utilizzare il filesystem. Sono sicuro che già sapete come fare questo, ma si può vedere un esempio qui:

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) 

L'opzione migliore usato per essere "mod_throttle". Usando questo, si potrebbe limitare ogni indirizzo IP per un accesso ogni cinque secondi con l'aggiunta di questa direttiva al file di configurazione di Apache:

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

Ma c'è una brutta notizia.L'autore di mod_throttle ha abbandonato il prodotto:

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

Un altro modulo di Apache, mod_limitipconn, è usato più spesso al giorno d'oggi. Non consente di effettuare restrizioni arbitrarie (come "non più di dieci richieste in ogni quindici secondi"). Tutto quello che puoi fare è limitare ogni indirizzo IP a un certo numero di connessioni simultanee. Molti webmaster sembrano sostenere che sia un buon modo per combattere lo spam bot, ma sembra meno flessibile rispetto a mod_throttle.

È necessario diverse versioni di mod_limitipconn a seconda di quale versione di Apache si sta eseguendo:

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 

Infine, se il server Apache è ospitato su una macchina Linux, c'è una soluzione è possibile utilizzare che non lo fa coinvolgere la ricompilazione del kernel. Invece, utilizza le regole del firewall "iptables". Questo metodo è piuttosto elegante ed è abbastanza flessibile da imporre vincoli come "non più di tre connessioni da questo IP in un minuto". Ecco come si fa:

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

mi rendo conto che nessuna di queste opzioni sarà l'ideale, ma illustrano ciò che è possibile. Forse l'utilizzo di un database locale finirà per essere il migliore dopo tutto? In ogni caso, tenete presente che limitando semplicemente la velocità delle richieste o limitando la larghezza di banda, non risolve il problema dei bot. Potrebbero impiegare più tempo, ma alla fine esauriranno tutte le risorse che avrebbero se non venissero rallentate. È necessario respingere effettivamente le loro richieste HTTP, non semplicemente rimandarle o diffonderle.

Buona fortuna nella battaglia crescente tra il contenuto e lo spam!

0

Il post è stato sbloccato, quindi ho pensato di condividere ciò che stavo facendo per ridurre gli attacchi dallo stesso indirizzo IP. Ne ricevo ancora una mezza dozzina al giorno, ma di solito provano solo una o due volte da ciascun indirizzo IP.

Nota: per restituire il messaggio di errore 404, è necessario che tutto ciò avvenga prima che venga inviato qualsiasi codice HTML. Sto usando PHP e reindirizzare tutti gli errori in un file di errore.

<?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(); 
    } 
} 

Ho anche molte pagine in cui visualizzo contenuti diversi a seconda della categoria selezionata. In questi casi ho una serie di istruzioni if, come questa if ($ cat == 'Speech') {} Non c'è alcuna ricerca nel database, quindi nessuna possibilità di SQL injection, ma voglio comunque fermare gli attacchi e non spreco di larghezza di banda che mostra una pagina predefinita a un bot. Di solito la categoria è una parola breve, quindi modifico il parametro is_numeric per verificare la lunghezza della stringa, ad es. if (strlen ($ cat)> 10) Poiché la maggior parte dei tentativi ha più di 10 caratteri, funziona abbastanza bene.

Problemi correlati