?? 拒絕服務攻擊原理及解決方法.txt
字號:
#define DNS_SERVER_IP "10.0.0.8"
Ngrep通過監(jiān)視DNS服務器的53端口的UDP包來跟蹤向內(nèi)的DNS請求(只有UDP)。因此,n
grep需要知道您的DNS服務器的IP地址。
我們的設備可能會有多個DNS服務器,但我們認為對一臺DNS服務器的支持足以證明這項
技術的能力。
#define TTL_THRESHOLD 150
tfn2k SYN flood 攻擊使用的 TTL值通常在200-255的范圍內(nèi)。估計到攻擊者與目標主機
之間不止50跳,因此我們可以只查找TTL時間高于150的包。假如您相信攻擊者在50跳左
右,那么您可以對TTL的限制進行一下更改。
編譯更改過的 ngrep
編譯和安裝都非常簡單。您僅需要使用以下之一來取代ngrep.c 文件。處于方便起見,
我們可以詳細說明。
這段代碼只是在RedHat 6.1 和Mandrake 6.5 Linux上測試過。
首先您需要在 http://www.packetfactory.net/ngrep/ 下載ngrep,我們測試的是1.35
版。
然后在 ftp://ftp.ee.lbl.gov/libpcap.tar.Z下載libpcap 我們使用的是 0.40版。
把文件放在臨時文件夾里并解包,
tar xvzf libpcap.tar.Z
然后進行編譯
cd libpcap-0.4; ./configure; make; make install; make install-incl
假如您遇到了困難,可以參見在libpcap-0.4目錄里的README或INSTALL文件。根據(jù)我們
實驗的經(jīng)驗,如果/usr/local/include 和/usr/local/include/net目錄在linux系統(tǒng)中
不存在的話,安裝會失敗。加入您在安裝時遇到了pcap.h 或 bpf.h的錯誤時你可以運行
mkdir /usr/local/include; mkdir /usr/local/include/net然后重新運行'make inst
all-incl'。然后我們需要編譯ngrep (使用我們修改過的版本)。首先解包
tar xvzf ngrep-1.35.tar.gz
然后進行配置
cd ngrep; ./configure
然后把ngrep.c復制到ngrep目錄里。你可以覆蓋也可以備份原始的ngrep.c文件。在這里
,您應當回顧在修改過的ngrep.c里的配置,至少您應當把DNS_SERVER_IP更改為您所使
用的DNS的地址。更改完畢后你就可以運行'make',這樣就建立了ngrep應用程序。
Modified ngrep.c source code
/* this code is available for download from http://www.wiretrip.net/na/ngrep
.c */
/*
* $Id: ngrep.c,v 1.35 1999/10/13 16:44:16 jpr5 Exp $
*
*/
/* TFN detection code added by Rain Forest Puppy / rfp@wiretrip.net
and Night Axis / na@wiretrip.net */
/********* TFN detection defines *******************************/
/* how many DNS and ICMP requests to track */
#define DNS_REQUEST_MAX 5000
#define ICMP_REQUEST_MAX 1000
/* flood threshold is matches per 10 seconds */
#define FLOOD_THRESHOLD 20
/* IP of your DNS server */
#define DNS_SERVER_IP "10.9.100.8"
/* TFN syn uses ttl between 200-255. Assuming less than 50 hops,
flag stuff with ttl > TTL_THRESHOLD (other critera are used
as well) */
#define TTL_THRESHOLD 150
/**************************************************************/
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#ifdef LINUX
#include <getopt.h>
#endif
#if defined(BSD) || defined(SOLARIS)
#include <unistd.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#endif
#if defined(LINUX) && !defined(HAVE_IF_ETHER_H)
h>
#include <pcap.h>
#include <net/bpf.h>
#include "regex.h"
#include "ngrep.h"
static char rcsver[] = "$Revision: 1.35 $";
int snaplen = 65535, promisc = 1, to = 1000;
int show_empty = 0, show_hex = 0, quiet = 0;
int match_after = 0, keep_matching = 0, invert_match = 0;
int matches = 0, max_matches = 0;
char pc_err[PCAP_ERRBUF_SIZE], *re_err;
int (*match_func)();
int re_match_word = 0, re_ignore_case = 0;
struct re_pattern_buffer pattern;
char *regex, *filter;
struct bpf_program pcapfilter;
struct in_addr net, mask;
char *dev = NULL;
int link_offset;
pcap_t *pd;
/**************** TFN2K detection **********************************/
unsigned int udp_flood_count=0, syn_flood_count=0;
unsigned int targa_flood_count=0, icmp_flood_count=0;
unsigned long my_dns, targ1, targ2, rfp1, icmp_flood=1;
time_t t;
unsigned long dns_circbuff[DNS_REQUEST_MAX];
unsigned int dns_cb_ptr=0;
unsigned long icmp_circbuff[ICMP_REQUEST_MAX];
unsigned int icmp_cb_ptr=0;
void add_dns (unsigned long ipadd){
dns_circbuff[dns_cb_ptr++]=ipadd;
if (dns_cb_ptr==DNS_REQUEST_MAX) dns_cb_ptr=0;}
void add_icmp (unsigned long ipadd){
icmp_circbuff[icmp_cb_ptr++]=ipadd;
if (icmp_cb_ptr==ICMP_REQUEST_MAX) dns_cb_ptr=0;}
void anti_tfn_init (void) {
unsigned int x;
for(x=0;x<DNS_REQUEST_MAX;x++) dns_circbuff[x]=0;
for(x=0;x<ICMP_REQUEST_MAX;x++) icmp_circbuff[x]=0;
my_dns=inet_addr(DNS_SERVER_IP);
printf("Ngrep with TFN detection modifications by wiretrip / www.wiretrip.ne
t\n");
printf("Watching DNS server: %s\n",inet_ntoa(my_dns));
targ1=htons(16383); targ2=htons(8192);
rfp1=htons(~(ICMP_ECHO << 8)); /* hopefull this is universal ;) */
alarm(20);}
void print_circbuffs (void) {
unsigned int x;
printf("Last (%u) DNS requests:\n",DNS_REQUEST_MAX);
for(x=0;x<DNS_REQUEST_MAX;x++)
if(dns_circbuff[x]>0) printf("%s\n",inet_ntoa(dns_circbuff[x]));
printf("\nLast (%u) ICMP echo requests (pings):\n",ICMP_REQUEST_MAX);
for(x=0;x<ICMP_REQUEST_MAX;x++)
if (icmp_circbuff[x]>0) printf("%s\n",inet_ntoa(icmp_circbuff[x]));}
void reset_counters (int sig) {
udp_flood_count=syn_flood_count=targa_flood_count=icmp_flood_count=0;
alarm(10);}
void tfn_attack_detected (char* attack_type){
if(icmp_flood==0) return;
(void)time(&t);
printf("\n%s",ctime(&t));
printf("A TFN2K %s attack has been detected!\n\n",attack_type);
print_circbuffs();
printf("\nIncoming realtime ICMP echo requests (pings):\n");
icmp_flood=0;}
/*********************************************************************/
int main(int argc, char **argv) {
char c;
signal(SIGINT,dealloc);
signal(SIGQUIT,dealloc);
signal(SIGABRT,dealloc);
signal(SIGPIPE,dealloc);
signal(SIGALRM,reset_counters);
anti_tfn_init();
while ((c = getopt(argc, argv, "d:")) != EOF) {
switch (c) {
case 'd':
dev = optarg;
break;}}
if (!dev)
if (!(dev = pcap_lookupdev(pc_err))) {
perror(pc_err);
exit(-1);}
if ((pd = pcap_open_live(dev, snaplen, promisc, to, pc_err)) == NULL) {
perror(pc_err);
exit(-1);}
if (pcap_lookupnet(dev,&net.s_addr,&mask.s_addr, pc_err) == -1) {
perror(pc_err);
exit(-1);}
printf("interface: %s (%s/", dev, inet_ntoa(net));
printf("%s)\n",inet_ntoa(mask));
switch(pcap_datalink(pd)) {
case DLT_EN10MB:
case DLT_IEEE802:
link_offset = ETHHDR_SIZE;
break;
case DLT_SLIP:
link_offset = SLIPHDR_SIZE;
break;
case DLT_PPP:
link_offset = PPPHDR_SIZE;
break;
case DLT_RAW:
link_offset = RAWHDR_SIZE;
break;
case DLT_NULL:
link_offset = LOOPHDR_SIZE;
break;
default:
fprintf(stderr,"fatal: unsupported interface type\n");
exit(-1);
} while (pcap_loop(pd,0,(pcap_handler)process,0));}
void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) {
struct ip* ip_packet = (struct ip *)(p + link_offset);
switch (ip_packet->ip_p) {
case IPPROTO_TCP: {
struct tcphdr* tcp = (struct tcphdr *)(((char *)ip_packet) + ip_packet->ip_h
l*4);
if(tcp->th_flags==0x22 && ip_packet->ip_ttl > TTL_THRESHOLD){
if(++syn_flood_count > FLOOD_THRESHOLD) tfn_attack_detected("SYN");}
if(ip_packet->ip_ttl==0 &&
(ip_packet->ip_off==targ1 || ip_packet->ip_off==targ2)){
if(++targa_flood_count > FLOOD_THRESHOLD) tfn_attack_detected("TARGA");
}} break;
case IPPROTO_UDP: {
struct udphdr* udp = (struct udphdr *)(((char *)ip_packet) + ip_packet->ip_h
l*4);
#ifdef HAVE_DUMB_UDPHDR
if ((ntohs(udp->source) + ntohs(udp->dest)) == 65536) {
#else
if ((ntohs(udp->uh_sport) + ntohs(udp->uh_dport)) == 65536) {
#endif
if(++udp_flood_count > FLOOD_THRESHOLD) tfn_attack_detected("UDP");}
if(ip_packet->ip_dst.s_addr==my_dns &&
#ifdef HAVE_DUMB_UDPHDR
ntohs(udp->dest) == 53) {
#else
ntohs(udp->uh_dport) == 53) {
#endif
add_dns(ip_packet->ip_src.s_addr);
}} break;
icmp_cksum==rfp1 && ip_packet->ip_ttl==0){
if(++icmp_flood_count > FLOOD_THRESHOLD) tfn_attack_detected("ICMP");
} else { if(icmp_flood>0) add_icmp(ip_packet->ip_src.s_addr);
else printf("%s\n",inet_ntoa(ip_packet->ip_src));}}}}}
void dealloc(int sig) {
if (filter) free(filter);
exit(0);}
--
世界上有兩件東西能夠深深地震撼人們的心靈
一件是我們心中崇高的道德準則
另一件是我們頭頂上燦爛的星空
——伊曼努爾·康德
※ 來源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 172.16.3.205]
--
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -