⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_evasive.c

📁 实现DOS攻击的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: mod_evasive.c,v 1.3 2005/10/08 19:17:14 jonz Exp $ *//*mod_evasive for Apache 1.3Copyright (c) by Jonathan A. ZdziarskiLICENSEThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; version 2of the License.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                                                                                */#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <time.h>#include <syslog.h>#include <errno.h>#include "httpd.h"#include "http_core.h"#include "http_config.h"#include "http_log.h"#include "http_request.h"module MODULE_VAR_EXPORT evasive_module;/* BEGIN DoS Evasive Maneuvers Definitions */#define MAILER	"/bin/mail -t %s"#define  LOG( A, ... ) { openlog("mod_evasive", LOG_PID, LOG_DAEMON); syslog( A, __VA_ARGS__ ); closelog(); }#define DEFAULT_HASH_TBL_SIZE   3079ul  // Default hash table size#define DEFAULT_PAGE_COUNT      2       // Default max page hit count/interval#define DEFAULT_SITE_COUNT      50      // Default max site hit count/interval#define DEFAULT_PAGE_INTERVAL   1       // Default 1 second page interval#define DEFAULT_SITE_INTERVAL   1       // Default 1 second site interval#define DEFAULT_BLOCKING_PERIOD 10      // Default block time (Seconds)#define DEFAULT_LOG_DIR		"/tmp"/* END DoS Evasive Maneuvers Definitions *//* BEGIN NTT (Named Timestamp Tree) Headers */enum { ntt_num_primes = 28 };/* ntt root tree */struct ntt {    long size;    long items;    struct ntt_node **tbl;};/* ntt node (entry in the ntt root tree) */struct ntt_node {    char *key;    time_t timestamp;    long count;    struct ntt_node *next;};/* ntt cursor */struct ntt_c {  long iter_index;  struct ntt_node *iter_next;};struct ntt *ntt_create(long size);struct ntt_node	*ntt_find(struct ntt *ntt, const char *key);struct ntt_node	*ntt_insert(struct ntt *ntt, const char *key, time_t timestamp);struct ntt_node *c_ntt_first(struct ntt *ntt, struct ntt_c *c);struct ntt_node *c_ntt_next(struct ntt *ntt, struct ntt_c *c);int ntt_destroy(struct ntt *ntt);int ntt_delete(struct ntt *ntt, const char *key);long ntt_hashcode(struct ntt *ntt, const char *key);/* END NTT (Named Timestamp Tree) Headers *//* BEGIN DoS Evasive Maneuvers Globals */struct ntt *hit_list;	// Our dynamic hash tablestruct ntt *white_list = NULL; // White list tablestatic unsigned long hash_table_size = DEFAULT_HASH_TBL_SIZE;static int page_count      = DEFAULT_PAGE_COUNT;static int page_interval   = DEFAULT_PAGE_INTERVAL;static int site_count      = DEFAULT_SITE_COUNT;static int site_interval   = DEFAULT_SITE_INTERVAL;static int blocking_period = DEFAULT_BLOCKING_PERIOD;static char *log_dir       = NULL;static char *email_notify  = NULL;static char *sys_command   = NULL;int is_whitelisted(const char *ip);static const char *whitelist(cmd_parms *cmd, void *mconfig, char *ip);/* END DoS Evasive Maneuvers Globals */static void evasive_child_init(server_rec *s, pool *p){    hit_list   = ntt_create(hash_table_size);}static int check_access(request_rec *r) {    int ret = OK;    /* BEGIN Evasive Maneuvers Code */    if (r->prev == NULL && r->main == NULL && hit_list != NULL) {      unsigned long address = r->connection->remote_addr.sin_addr.s_addr;      char *text_add = inet_ntoa(r->connection->remote_addr.sin_addr);      char hash_key[2048];      struct ntt_node *n;      time_t t = time(NULL);      /* Check whitelist */             if (is_whitelisted(text_add))        return OK;      /* First see if the IP itself is on "hold" */      snprintf(hash_key, 2048, "%ld", address);      n = ntt_find(hit_list, hash_key);      if (n != NULL && t-n->timestamp<blocking_period) {         /* If the IP is on "hold", make it wait longer in 403 land */        ret = FORBIDDEN;        n->timestamp = time(NULL);      /* Not on hold, check hit stats */      } else {        /* Has URI been hit too much? */        snprintf(hash_key, 2048, "%ld_%s", address, r->uri);        n = ntt_find(hit_list, hash_key);        if (n != NULL) {          /* If URI is being hit too much, add to "hold" list and 403 */          if (t-n->timestamp<page_interval && n->count>=page_count) {            ret = FORBIDDEN;            snprintf(hash_key, 2048, "%ld", address);            ntt_insert(hit_list, hash_key, time(NULL));          } else {            /* Reset our hit count list as necessary */            if (t-n->timestamp>=page_interval) {              n->count=0;            }          }          n->timestamp = t;          n->count++;        } else {          ntt_insert(hit_list, hash_key, t);        }        /* Has site been hit too much? */        snprintf(hash_key, 2048, "%ld_SITE", address);        n = ntt_find(hit_list, hash_key);        if (n != NULL) {          /* If site is being hit too much, add to "hold" list and 403 */          if (t-n->timestamp<site_interval && n->count>=site_count) {            ret = FORBIDDEN;            snprintf(hash_key, 2048, "%ld", address);            ntt_insert(hit_list, hash_key, time(NULL));          } else {            /* Reset our hit count list as necessary */            if (t-n->timestamp>=site_interval) {              n->count=0;            }          }          n->timestamp = t;          n->count++;        } else {          ntt_insert(hit_list, hash_key, t);        }      }      /* Perform email notification and system functions */      if (ret == FORBIDDEN) {        char filename[1024];        struct stat s;        FILE *file;        snprintf(filename, sizeof(filename), "%s/dos-%s", log_dir != NULL ? log_dir : DEFAULT_LOG_DIR, text_add);        if (stat(filename, &s)) {          file = fopen(filename, "w");          if (file != NULL) {            fprintf(file, "%ld\n", getpid());            fclose(file);            LOG(LOG_ALERT, "Blacklisting address %s: possible attack.", text_add)            if (email_notify != NULL) {              snprintf(filename, sizeof(filename), MAILER, email_notify);              file = popen(filename, "w");              if (file != NULL) {                fprintf(file, "To: %s\n", email_notify);                fprintf(file, "Subject: HTTP BLACKLIST %s\n\n", text_add);                fprintf(file, "mod_evasive HTTP Blacklisted %s\n", text_add);                pclose(file);              }            }            if (sys_command != NULL) {              snprintf(filename, sizeof(filename), sys_command, text_add);              system(filename);            }           } else {		LOG(LOG_ALERT, "Couldn't open logfile %s: %s",filename, strerror(errno));	  }        } /* if (temp file does not exist) */      } /* if (ret == FORBIDDEN) */    } /* if (r->prev == NULL && r->main == NULL && hit_list != NULL) */    /* END Evasive Maneuvers Code */    if (ret == FORBIDDEN	&& (ap_satisfies(r) != SATISFY_ANY || !ap_some_auth_required(r))) {	ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,		  "client denied by server configuration: %s",		  r->filename);    }    return ret;}static void evasive_child_exit(server_rec *s, pool *p) {    ntt_destroy(hit_list);    free(email_notify);    free(sys_command);}/* BEGIN NTT (Named Timestamp Tree) Functions */static unsigned long ntt_prime_list[ntt_num_primes] = {    53ul,         97ul,         193ul,       389ul,       769ul,    1543ul,       3079ul,       6151ul,      12289ul,     24593ul,    49157ul,      98317ul,      196613ul,    393241ul,    786433ul,    1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,    50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,    1610612741ul, 3221225473ul, 4294967291ul};/* Find the numeric position in the hash table based on key and modulus */long ntt_hashcode(struct ntt *ntt, const char *key) {    unsigned long val = 0;    for (; *key; ++key) val = 5 * val + *key;    return(val % ntt->size);}/* Creates a single node in the tree */struct ntt_node *ntt_node_create(const char *key) {    char *node_key;    struct ntt_node* node;    node = (struct ntt_node *) malloc(sizeof(struct ntt_node));    if (node == NULL) {	return NULL;    }    if ((node_key = strdup(key)) == NULL) {        free(node);	return NULL;    }    node->key = node_key;    node->timestamp = time(NULL);    node->next = NULL;    return(node);}/* Tree initializer */struct ntt *ntt_create(long size) {    long i = 0;    struct ntt *ntt = (struct ntt *) malloc(sizeof(struct ntt));    if (ntt == NULL)        return NULL;    while (ntt_prime_list[i] < size) { i++; }    ntt->size  = ntt_prime_list[i];    ntt->items = 0;    ntt->tbl   = (struct ntt_node **) calloc(ntt->size, sizeof(struct ntt_node *));    if (ntt->tbl == NULL) {        free(ntt);        return NULL;    }    return(ntt);}/* Find an object in the tree */struct ntt_node *ntt_find(struct ntt *ntt, const char *key) {    long hash_code;    struct ntt_node *node;    if (ntt == NULL) return NULL;    hash_code = ntt_hashcode(ntt, key);    node = ntt->tbl[hash_code];    while (node) {        if (!strcmp(key, node->key)) {            return(node);        }        node = node->next;    }    return((struct ntt_node *)NULL);}/* Insert a node into the tree */struct ntt_node *ntt_insert(struct ntt *ntt, const char *key, time_t timestamp) {    long hash_code;    struct ntt_node *parent;    struct ntt_node *node;    struct ntt_node *new_node = NULL;    if (ntt == NULL) return NULL;    hash_code = ntt_hashcode(ntt, key);    parent	= NULL;    node	= ntt->tbl[hash_code];    while (node != NULL) {        if (strcmp(key, node->key) == 0) {             new_node = node;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -