Lucene search

K
openvasCopyright (C) 2011 Greenbone AGOPENVAS:1361412562310108041
HistorySep 06, 2011 - 12:00 a.m.

HTTP Brute Force Logins With Default Credentials

2011-09-0600:00:00
Copyright (C) 2011 Greenbone AG
plugins.openvas.org
700

7.3 High

AI Score

Confidence

Low

A number of known default credentials are tried for the login
via HTTP Basic Auth.

As this VT might run into a timeout the actual reporting of this vulnerability takes place in the
VT

# SPDX-FileCopyrightText: 2011 Greenbone AG
# Some text descriptions might be excerpted from (a) referenced
# source(s), and are Copyright (C) by the respective right holder(s).
#
# SPDX-License-Identifier: GPL-2.0-only

if(description)
{
  script_oid("1.3.6.1.4.1.25623.1.0.108041");
  script_version("2024-06-25T05:05:27+0000");
  script_tag(name:"cvss_base", value:"0.0");
  script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:N/I:N/A:N");
  script_tag(name:"last_modification", value:"2024-06-25 05:05:27 +0000 (Tue, 25 Jun 2024)");
  script_tag(name:"creation_date", value:"2011-09-06 14:38:09 +0200 (Tue, 06 Sep 2011)");
  script_name("HTTP Brute Force Logins With Default Credentials");
  script_category(ACT_ATTACK);
  script_family("Brute force attacks");
  script_copyright("Copyright (C) 2011 Greenbone AG");
  # nb: sw_web_app_scanning_consolidation.nasl pulls in the VTs setting a /content/auth_required
  script_dependencies("find_service.nasl", "no404.nasl", "webmirror.nasl",
                      "DDI_Directory_Scanner.nasl", "gb_default_credentials_options.nasl",
                      "sw_web_app_scanning_consolidation.nasl");
  script_require_ports("Services/www", 80);
  script_mandatory_keys("www/content/auth_required");
  script_exclude_keys("default_credentials/disable_brute_force_checks");

  script_timeout(1800);

  script_tag(name:"summary", value:"A number of known default credentials are tried for the login
  via HTTP Basic Auth.

  As this VT might run into a timeout the actual reporting of this vulnerability takes place in the
  VT 'HTTP Brute Force Logins With Default Credentials Reporting' (OID:
  1.3.6.1.4.1.25623.1.0.103240).");

  script_tag(name:"vuldetect", value:"Tries to login with a number of known default credentials via
  HTTP Basic Auth.");

  script_tag(name:"qod_type", value:"remote_active");

  exit(0);
}

# If optimize_test = no
if( get_kb_item( "default_credentials/disable_brute_force_checks" ) )
  exit( 0 );

include("http_func.inc");
include("http_keepalive.inc");
include("port_service_func.inc");
include("list_array_func.inc");
include("misc_func.inc");
include("default_credentials.inc");

# @brief Checks the passed HTTP response for specific constraints described below
#
# @param res The HTTP response to check
#
# @note More info on HTTP status code available at e.g. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
#
# @return TRUE if the data contains a valid HTTP response and doesn't match one of the following:
#
#         - 500, 502, 503 or 504 HTTP status code responses (Server error responses)
#         - 400, 401, 403, 408, 429 HTTP status code responses (Client error responses)
#         - two application / web server specific response text parts
#
#         or FALSE otherwise.
#
function _check_response( res ) {

  local_var res;

  if( res && ! isnull( res ) &&

      # nb: Basic HTTP status code response check
      ( res =~ "^HTTP/1\.[01] [0-9]+" ) &&   # nb: Just to be sure that we received a valid HTTP response...
      ( res !~ "^HTTP/1\.[01] 50[0234]" ) &&
      ( res !~ "^HTTP/1\.[01] 40[0138]" ) &&
      ( res !~ "^HTTP/1\.[01] 429" ) &&      # nb: Too Many Requests (RFC 6585)

      # nb: Some systems have been seen responding with something like this on wrong credentials
      # but with a 200 status code (possibly also via a 30x redirect to authorizationrequired.htm).
      # While this is a misconfiguration on target side we're still trying to work around such
      # issues here.
      ( "<title>Authorization Required</title>" >!< res ) &&
      ( res !~ "<p>\s*This server could not verify that you are authorized to access the document requested\. Either you supplied\s*<br>" ) ) {
    return TRUE;
  }

  return FALSE;
}

port = http_get_port( default:80 );
kb_host = http_host_name( dont_add_port:TRUE );

if( ! urls = http_get_kb_auth_required( port:port, host:kb_host ) )
  exit( 0 );

set_kb_item( name:"default_http_auth_credentials/started", value:TRUE );

# nb: There are various VTs setting a /content/auth_required. This
# makes sure we're not testing URLs which are set multiple times.
urls = make_list_unique( urls );

host = http_host_name( port:port );
useragent = http_get_user_agent();

foreach url( urls ) {

  req = http_get( item:url, port:port );
  res = http_keepalive_send_recv( port:port, data:req, bodyonly:FALSE );
  if( ! res || res !~ "^HTTP/1\.[01] 401" )
    continue; # just to be sure

  c = 0;

  foreach credential( credentials ) {

    # to many successful logins. something is wrong...
    if( c > 10 ) {
      set_kb_item( name:"default_http_auth_credentials/" + kb_host + "/" + port + "/too_many_logins", value:c );
      exit( 0 );
    }

    # Handling of user uploaded credentials which requires to escape a ';' or ':'
    # in the user/password so it doesn't interfere with our splitting below.
    credential = str_replace( string:credential, find:"\;", replace:"#sem_legacy#" );
    credential = str_replace( string:credential, find:"\:", replace:"#sem_new#" );

    user_pass_type = split( credential, sep:":", keep:FALSE );
    if( isnull( user_pass_type[0] ) || isnull( user_pass_type[1] ) ) {
      # nb: ';' was used pre r9566 but was changed to ':' as a separator as the
      # GSA is stripping ';' from the VT description. Keeping both in here
      # for backwards compatibility with older scan configs.
      user_pass_type = split( credential, sep:";", keep:FALSE );
      if( isnull( user_pass_type[0] ) || isnull( user_pass_type[1] ) )
        continue;
    }

    # nb: Check the type defined in default_credentials.inc if the
    # credentials should be used by this VT.
    type = user_pass_type[3];
    if( "all" >!< type && "http" >!< type )
      continue;

    user = chomp( user_pass_type[0] );
    pass = chomp( user_pass_type[1] );

    user = str_replace( string:user, find:"#sem_legacy#", replace:";" );
    pass = str_replace( string:pass, find:"#sem_legacy#", replace:";" );
    user = str_replace( string:user, find:"#sem_new#", replace:":" );
    pass = str_replace( string:pass, find:"#sem_new#", replace:":" );

    if( tolower( pass ) == "none" )
      pass = "";

    if( tolower( user ) == "none" )
      user = "";

    userpass = user + ":" + pass;
    userpass64 = base64( str:userpass );

    req = string( "GET ", url, " HTTP/1.1\r\n",
                  "Host: ", host, "\r\n",
                  "User-Agent: ", useragent, "\r\n",
                  "Authorization: Basic ", userpass64, "\r\n",
                  "\r\n" );
    res = http_keepalive_send_recv( port:port, data:req, bodyonly:FALSE );
    if( res && res =~ "^HTTP/1\.[01] 30[0-8]" ) {

      url = http_extract_location_from_redirect( port:port, data:res, current_dir:url );
      if( url ) {

        req = http_get( item:url, port:port );
        res = http_keepalive_send_recv( port:port, data:req, bodyonly:FALSE );
        if( res && res =~ "^HTTP/1\.[01] 401" ) {

          req = string( "GET ", url, " HTTP/1.1\r\n",
                        "Host: ", host, "\r\n",
                        "User-Agent: ", useragent, "\r\n",
                        "Authorization: Basic ", userpass64, "\r\n",
                        "\r\n" );
          res = http_keepalive_send_recv( port:port, data:req, bodyonly:FALSE );

          if( _check_response( res:res ) ) {
            statuscode = egrep( pattern:"^HTTP/1\.[01] [0-9]+( |$)", string:res );
            c++;
            set_kb_item( name:"default_http_auth_credentials/" + kb_host + "/" + port + "/credentials", value:url + "#-----#" + user + ":" + pass + ":" + chomp( statuscode ) );
          }
        }
      }
    } else if( _check_response( res:res ) ) {
      statuscode = egrep( pattern:"^HTTP/1\.[01] [0-9]+( |$)", string:res );
      c++;
      set_kb_item( name:"default_http_auth_credentials/" + kb_host + "/" + port + "/credentials", value:url + "#-----#" + user + ":" + pass + ":" + chomp( statuscode ) );
    }
  }
}

exit( 0 );

7.3 High

AI Score

Confidence

Low