DDoS saldýrýlarý nasýl gerçekleþmektedir?
Atak anýnda kiþi, kendini gizlemek için önceden sýzdýðý bilgisayarlara 'zombi' adý verilen küçük programcýklarý yerleþtirir. Böylece kendini saklama fýrsatý elde eder. Ataklar bu zombiler üzerinden yaparak birden fazla bilgisayarý istediði hedefler üzerine veri bombardýmaný yapabilir. Yüzlerce/binlerce bilgisayarlara yerleþtirilen zombiler, bilgisayarlara uzaktan kontrol (remote ) imkaný vererek, bu bilgisayarlar üzerinden istedikleri server'a çok sayýda veri göndererek, server'i sistem dýþý býrakýyor. Böylece saldýrganlar, saldýrýlarý baþka insanlarýn bilgisayarlarý üzerinden gerçekleþtirdiði için saptanmalarý zor hale gelmektedir.
DDoS yöntemi genel olarak sistemlere belli bir düzen çerçevesinde farklý noktalardan saldýrarak server'i hizmet dýþýna býrakma yoludur. Bir bilgisayar server'a kendi adresini yanlýþ veren bir veri paketi yolluyor. Server, bilgisayarýn verdiði adrese geri bilgi vermek için ulaþmaya çalýþtýðýnda adrese ulaþamýyor. Bu esnada server baðlantýyý kapatmadan bir müddet bekliyor. Bu tür baðlantý isteklerinin milyonlarcasý server'a yapýldýðýnda server iþlemez hale gelmektedir.
'Zombiler'
DDoS ataklarýný gerçekleþtirirken yakalanmamak için "zombi" denilen küçük programcýklarýn kullanýldýðýndan söz etmiþtik. Ataklar bu zombiler üzerinden gerçekleþtirilerek ayný anda birden fazla bilgisayarýn hedeflere yönlendirilmesi saðlanarak, saldýrýyý yapan kiþinin IP adresininde gizlenmesi saðlanýr. Zombiler genellikle güvenliði zayýf olan sistemlere yerleþtirilirler. Yani hack'lenen sisteme yerleþtirilen zombiler kendi bünyesindeki daemonlar vasýtasýyla belirli bir porttan (1524 tcp, 27665 tcp, 2744 udp, 31335 udp, 33270 tcp ) gelecek olan DDoS isteklerini gerçekleþtirirler. Ayrýca daha çok Unix ve Linux tabanlý sistemlerde zombiler kullanýlsada Windows tabanlý sistemlerde de zombiler kullanýlmaktadýr.
DDoS için kullanýlan araçlar:
_ Trinoo(Trin00 )
_ The Tribe Flood Network (TFN )
_ Stacheldraht
_ Trinity
_ Shaft
_ Tribe Flood Network 2K (TFN2K )
_ MStream
DDoS ataklarýndan korunmak için;
Bu ataklar fark edildiðinde atakta bulunan adresten gelen baðlantý isteklerinin iptal edilmesi gerekir. Ayriyeten özel yazýlým ve donaným kullanýlarak saldýrýlarýn önüne geçme imkaný vardýr. Þirket ve bireysel kullanýcýlar, güvenlik politikalarýný belirleyerek, müdahale tespit (intrusion detection ) gibi yöntemlere baþvurmalý. Ayrýca saldýrýnýn baþladýðý an saldýrýnýn merkezi tespit edilerek, o merkezin servis saðlyýcýsýyla irtibata geçmek ve eriþimi engellemek gerekiyor.
Sisteminizde bir DDoS aracýnýn kurulup kurulmadýðýný tespit etmek istiyorsanýz find_ddos isimli programý kullanabilirsiniz. Bu programý bulabileceðiniz adres:
http://www.nipc.gov/warnings/alerts/1999/find_ddos_v42_linux.tar.Z - http://www.nipc.gov/warnings/alerts/1999/find_ddos_v42_linux.tar.Z
Sistemde tespit edebildiði DDoS araçlarý:
* mstream master
* mstream server
* stacheldraht client
* stacheldraht daemon
* stacheldraht master
* tfn-rush client
* tfn client
* tfn daemon
* tfn2k client
* tfn2k daemon
* trinoo daemon
* trinoo master
Bu programý root yetkisinde çalýþtýrýn.
Eðer sisteminizde DDoS aracý kurulmuþsa aþaðýdakine benzer bir çýktý ile karþýlaþma olasýlýðý vardýr.
[root@CiLeK find]# ./find_ddos
Logging output to: LOG
Scanning running processes...
Scanning "/tmp"...
Scanning "/"...
/DoS/TFN/tfn: tfn client
/DoS/TFN/tfn-rush: tfn-rush client
/DoS/TFN/td: tfn2k daemon
ALERT: One or more DDOS tools were found on your system.
Please examine LOG and take appropriate action.
Tarama iþlemi sonucunda oluþturduðu LOG dosyasýnda detaylý bilgileri barýndýrýr.
Eðer Windows sistemi altýndan networkünüzü kontrol etmek istiyorsanýz DDoSPing isimli programý kullanabilirsiniz. Bu programý www.foundstone.com adresinde bulabilirsiniz.
Sisteminize yapýlan DDoS ataklarýna karþý yararlanabileceðiniz programlardan biri ZombieZapper isimli programdýr. Programýn kaynak kodu aþaðýda verilmiþtir.
Ayrýca programý;
http://www.razor.bindview.com/ - http://www.razor.bindview.com
Adresinden download edebilirsiniz.
ZombieZapper, zombie kurulmuþ sistemlerden kaynaklanan yoðun trafiðin durdurulmasý için kullanýlmaktadýr. Bu programýn Trinioo, TFN, Stacheldraht, Trinioo for Windows ve Shaft DDoS araclarýna karþý etkili olduðu belirtiliyor. ZombieZapper yazarlarý network yöneticilerinin bu programý kullanarak kendi network'lerinden veya dýþarýdaki bir sistemden kaynaklanan flood saldýrýlarýnýn tespit edilip, durdurulabileceði belirtilmekte.
/*
* zombie_zapper - distributed dos killer
* written by Simple Nomad
* Requirements: Libnet 1.0 or higher (http://www.packetfactory.net/libnet/ )
* Compilation instructions:
* gcc `libnet-config --defines` -o zz zz.c -lnet
* Tested on RedHat, Slackware, but should work most places that libnet compiles
* and installs properly.
* Suggested usages:
* zz -a 1 -v 192.168.1.1
* (stops trinoo daemon at 192.168.1.1 from flooding, uses verbose mode )
* zz -u 80 -c 192.168.1.0
* (stops trinoo, tfn, stach, troj_trinoo on 192.168.1 network from
* flooding, udp source port of 80 is being used )
* zz -a 5 -m www.whitehouse.gov -s 10.10.10.10 192.168.1.1
* (stops a shaft agent at 192.168.1.1 from flooding www.whitehouse.gov
* using a forged source address of 10.10.10.10 )
* Shouts to my homies on BindView's RAZOR team for all the help with this!
*/
#include
int timer;
/*
* Based off of icmpquery, chain structs to store host names.
*/
struct hosts
{
char *hostname;
u_long hostaddr;
struct hosts *next;
};
struct hosts *hostnames;
struct hosts *hosttail;
/*
* Build the targets
*/
void build_target(char *host, u_long ip_addr )
{
if (hostnames == NULL )
{
hostnames = (struct hosts * ) malloc(sizeof(*hostnames ) );
if (hostnames == NULL )
{
perror("hostnames malloc failed" );
exit(-1 );
}
hosttail = hostnames;
}
else
{
hosttail->next = (struct hosts * ) malloc(sizeof(*hostnames ) );
if (hosttail->next == NULL )
{
perror("hosttail->next malloc failed" );
exit(-1 );
}
hosttail = hosttail->next;
}
hosttail->hostname = strdup(host );
if (hosttail->hostname == NULL )
{
perror("strdup failed" );
exit(-1 );
}
hosttail->hostaddr = ip_addr;
hosttail->next = NULL;
}
/*
* Build a class C of targets
*/
void build_class_c(u_long dst_ip )
{
int i;
u_long class_c_ips[256];
union
{
struct in_addr addr;
ulong temp_ip;
} ip;
for (i = 0; i < 256; i++ )
{
class_c_ips = htonl(dst_ip ) + i;
class_c_ips = htonl(class_c_ips );
ip.temp_ip = class_c_ips;
build_target(inet_ntoa(ip.addr ),ip.temp_ip );
}
}
/*
* Process the targets, resolve the hosts, set up the chain
*/
void process_targets(char **hostlist, int verbose )
{
int i;
u_long tmpaddr;
for (i = 0; hostlist; i++ )
{
tmpaddr = libnet_name_resolve(hostlist, LIBNET_RESOLVE );
/*
* if a "local" hostname is given it could "resolve" to a
* broadcast address if the local host is not set up properly,
* so we need to make sure we grab it and not send the packet
*/
if ((tmpaddr == 0xffffffff ) || (tmpaddr == -1 ) )
{
if (verbose ) printf("%s not resolvedn",hostlist );
continue;
};
build_target(hostlist,tmpaddr );
}
}
void caughtsig(int sig )
{
timer = 0;
return;
}
/*
* build and send the icmp packets
*/
void send_packets(u_long src_ip, char *my_host, u_short sport, int antitype, int flood, int verbose )
{
int packet_size, network, i, p, count, data_len = 0;
u_char *packet;
u_short header, id, dport;
u_char proto;
char data[87],sbuf[87];
u_long dst_ip;
struct hosts *list;
for (p=0;p<87;p++ ) data
= 0>;
switch (antitype )
{
case 1: /* Trinoo */
sprintf(sbuf,"d1e l44adsl d1e" );
header = LIBNET_UDP_H;
id = 41072;
dport = 27444;
proto = IPPROTO_UDP;
break;
case 2: /* TFN */
sprintf(sbuf,"12345" );
header = LIBNET_ICMP_ECHO_H;
id = 567;
proto = IPPROTO_ICMP;
break;
case 3: /* Stacheldraht */
header = LIBNET_ICMP_ECHO_H;
id = 3;
proto = IPPROTO_ICMP;
break;
case 4: /* Troj_Trinoo */
sprintf(sbuf,"d1e []..Ks l44" );
header = LIBNET_UDP_H;
id = 41072;
dport = 34555;
proto = IPPROTO_UDP;
break;
case 5: /* Shaft, part one */
sprintf(sbuf,"alive tijgu hi 5 2621" );
header = LIBNET_UDP_H;
id = 41072;
dport = 18753;
proto = IPPROTO_UDP;
break;
case 0: /* Shaft, part two */
sprintf(sbuf,"end tijgu %s 5 2621",my_host );
header = LIBNET_UDP_H;
id = 41072;
dport = 18753;
proto = IPPROTO_UDP;
break;
}
if (antitype != 3 ) /* no payload for stach required */
{
data_len = strlen(sbuf );
for (p=0;p
if (verbose ) printf(" Payload is "%s"n Data length of %dn",data,data_len );
}
else if (verbose ) printf(" Payload is NULLn Data length of 0n" );
count = 0;
/* compute packet size */
packet_size = LIBNET_IP_H + header + data_len;
if (verbose ) printf(" Packet size is %dn",packet_size );
/* get mem for packet */
libnet_init_packet(packet_size, &packet );
if (packet == NULL )
{
libnet_error(LIBNET_ERR_FATAL, "unable to init packet memn" );
}
/* get network ready */
network = libnet_open_raw_sock(IPPROTO_RAW );
if (network == -1 )
{
libnet_error(LIBNET_ERR_FATAL, "unable to open network for sendingn" );
}
list = hostnames;
/* main sending loop */
while (list != NULL )
{
/* get the target address */
dst_ip = list->hostaddr;
/* build target section */
switch (proto )
{
case IPPROTO_ICMP:
libnet_build_icmp_echo(ICMP_ECHOREPLY,0,id,0,data,data_len,packet + LIBNET_IP_H );
break;
case IPPROTO_UDP:
libnet_build_udp(sport,dport,data,data_len,packet + LIBNET_IP_H );
break;
}
/* build IP section */
libnet_build_ip(header,0,id,0,64,proto,src_ip,dst_ip,NULL,0,packet );
timer = 1;
signal(SIGALRM, caughtsig );
alarm(flood );
while(timer )
{
/* send the packet */
i = libnet_write_ip(network, packet, packet_size );
if (i == -1 )
{
libnet_error(LIBNET_ERR_FATAL, "failed to write to networkn" );
}
if (i < packet_size )
{
libnet_error(LIBNET_ERR_FATAL, "only wrote %d bytesn", i );
}
if (verbose == 2 )
{
printf("Sent %d bytes for %sn", i, list->hostname );
}
count++;
/*
* 1/10 sec delay between packets to prevent overflowing the local
* interface
*/
usleep(10000 );
}
/* get next address, or NULL if done */
list = list->next;
}
/* clean things up */
if (libnet_close_raw_sock(network ) == -1 )
{
libnet_error(LIBNET_ERR_WARNING, "couldn't close the interface after sending" );
}
libnet_destroy_packet(&packet );
if (verbose ) printf(" %d packets sent in %d secondsn",count,flood );
}
/*
* usage
*/
void usage(char *prog )
{
fprintf(stderr,"USAGE:n" );
fprintf(stderr,"%s [-a 0-5] [-c class C] [-d dev] [-h] [-m host] [-s src] [-u udp] [-v] hostsnn",prog );
fprintf(stderr," -a antiddos type to kill:n" );
fprintf(stderr," 0 types 1-4 (default )n" );
fprintf(stderr," 1 trinoon" );
vfprintf(stderr," 2 tfnn" );
fprintf(stderr," 3 stacheldrahtn" );
fprintf(stderr," 4 trinoo on Windowsn" );
fprintf(stderr," 5 shaft (requires you use the -m option )n" );
fprintf(stderr," -c class C in x.x.x.0 formn" );
fprintf(stderr," -f time in seconds to send packets (default 1 )n" );
fprintf(stderr," -d grab local IP from dev (default eth0 )n" );
fprintf(stderr," -h this help screenn" );
fprintf(stderr," -m my host being flooded (used with -a 5 above, only one host )n" );
fprintf(stderr," -s spoofed source address (just in case )n" );
fprintf(stderr," -u UDP source port for trinoo (default 53 )n" );
fprintf(stderr," -v verbose mode (use twice for more verbosity )n" );
fprintf(stderr," host(s ) are target hosts (ignored if using -c )n" );
fprintf(stderr,"n" );
}
int main(int argc, char **argv )
{
char *prog;
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
char ch;
int spoof = 0, verbose = 0, setdev = 0;
int antitype = 0, class_c = 0, shaft = 0;
int flood = 1;
u_long src_ip;
char *my_host;
u_long dst_ip = 0;
u_long class_c_ip;
u_short sport = 53;
u_long CLASS_C_MASK = 0x00ffffff;
char *data[18];
char *dev;
struct libnet_link_int *l;
u_char *ebuf;
prog = argv[0];
dev = "eth0";
printf("Zombie Zapper v1.2 - DDoS killern" );
printf("Bugs/comments to [email]thegnome@razor.bindview.comn" );[/email]
printf("More info and free tools at http://razor.bindview.comn" );
printf("Copyright (c ) 2000 BindView Developmentnn" );
if(getuid( )!=0 )
{
fprintf(stderr, "=== You must be root to run %s!n", prog );
exit(-1 );
}
while ((ch = getopt(argc, argv, "hvc:a:m:u:f:" ) ) != EOF )
switch(ch )
{
case 'c':
dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE );
if (dst_ip == -1 )
{
printf("=== Invalid class C %sn", optarg );
usage(prog );
exit(-1 );
}
/* get the last part of the address */
class_c_ip = ((dst_ip | CLASS_C_MASK ) - CLASS_C_MASK );
/* if it is not zero make it zero */
if(class_c_ip ) dst_ip = dst_ip ^ class_c_ip;
class_c = 1;
break;
case 'd':
dev = optarg;
setdev = 1;
break;
case 'f':
flood = (int ) strtol(optarg, NULL, 10 );
if (flood < 1 ) flood = 1;
if (flood > 360 ) flood = 360;
break;
case 'h':
usage(prog );
exit(0 );
case 'a':
antitype = (int ) strtol(optarg, NULL, 10 );
break;
case 'm':
if (!(libnet_name_resolve(optarg, LIBNET_RESOLVE ) ) )
{
fprintf(stderr,"=== Unable to resolve hostname,n" );
fprintf(stderr,"=== try using the IP addressn" );
usage(prog );
exit(-1 );
}
if (strlen(optarg ) > 70 )
{
fprintf(stderr,"=== Very long hostname, try using just ann" );
fprintf(stderr,"=== IP address.n" );
usage(prog );
exit(-1 );
}
my_host = optarg;
shaft = 1;
break;
case 's':
if (!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE ) ) )
{
fprintf(stderr,"=== Unable to resolve source host,n" );
fprintf(stderr,"=== try spoofing with an IP addressn" );
usage(prog );
exit(-1 );
}
spoof = 1;
break;
case 'u':
sport = (int ) strtol(optarg, NULL, 10 );
break;
case 'v':
verbose++;
if (verbose > 2 ) verbose = 2;
break;
default:
usage(prog );
exit(-1 );
}
argc -= optind;
argv += optind;
/* post arg processing */
if ((!class_c ) && (!argv[0] || !strlen(argv[0] ) ) )
{
fprintf(stderr,"=== You must specify target(s ) or a class C to send ton" );
usage(prog );
exit(-1 );
}
if ((setdev ) && (spoof ) )
{
fprintf(stderr, "=== You cannot specify a device for a source IP addressn" );
fprintf(stderr, "=== and spoof your source IP address at the same time.n" );
usage(prog );
exit(-1 );
}
if (antitype > 5 || antitype < 0 )
{
fprintf(stderr,"=== Invalid or unsupported antiddos typen" );
usage(prog );
exit(-1 );
}
if (antitype == 5 && (!shaft ) )
{
fprintf(stderr,"=== You must specify a host with the -m option when usingn" );
fprintf(stderr,"=== the -a option of 5n" );
usage(prog );
exit(-1 );
}
if (!spoof )
{
src_ip = libnet_get_ipaddr(l, dev, ebuf );
if ((src_ip == -1 ) || (src_ip == 0 ) )
{
fprintf(stderr, "=== Grabbing address from %s failed,n",dev );
fprintf(stderr, "=== try a different device.n" );
usage(prog );
exit(-1 );
}
src_ip = htonl(src_ip );
}
/* end post arg processing */
if (verbose )
{
printf("Sending packets to stop these possible daemons from floodingnn" );
switch(antitype )
{
case 0:
printf("tTrinoo, TFN, Stacheldraht, Troj_Trinoonn" );
break;
case 1:
printf("tTrinoonn" );
break;
case 2:
printf("tTFNnn" );
break;
case 3:
printf("tStacheldrahtnn" );
break;
case 4:
printf("tTroj_Trinoonn" );
break;
case 5:
printf("tShaftnn" );
break;
}
}
/* build a class C full of addresses */
if (class_c ) build_class_c(dst_ip );
/* build target chain and get a count */
else process_targets(argv, verbose );
if (antitype == 0 || antitype == 1 )
{
if (verbose ) printf("Building anti-Trinoo packetsn" );
send_packets(src_ip,NULL,sport,1,flood,verbose );
}
if (antitype == 0 || antitype == 2 )
{
if (verbose ) printf("Building anti-TFN packetsn" );
send_packets(src_ip,NULL,sport,2,flood,verbose );
}
if (antitype == 0 || antitype == 3 )
{
if (verbose ) printf("Building anti-Stacheldraht packetsn" );
send_packets(src_ip,NULL,sport,3,flood,verbose );
}
if (antitype == 0 || antitype == 4 )
{
if (verbose ) printf("Building anti-Troj_Trinoo packetsn" );
send_packets(src_ip,NULL,sport,4,flood,verbose );
}
if (antitype == 5 )
{
if (verbose ) printf("Building first set of anti-Shaft packetsn" );
send_packets(src_ip,NULL,sport,5,flood,verbose );
if (verbose ) printf("Building second set of anti-Shaft packetsn" );
send_packets(src_ip,my_host,sport,0,flood,verbose );
}
if (verbose ) printf("Completen" );
exit(0 );
}
Saygýlar.