Lucene search
+L

IP Forwarding Enabled - Active Check

🗓️ 24 Nov 2021 00:00:00Reported by Copyright (C) 2021 Greenbone Networks GmbHType 
openvas
 openvas
🔗 plugins.openvas.org👁 36 Views

IP Forwarding Enabled - Active Chec

Related
Code
ReporterTitlePublishedViews
Family
ibm
IBM Security Bulletins
Security Bulletin: Disable IP forwarding
8 May 202509:45
ibm
attackerkb
ATTACKERKB
CVE-1999-0511
1 Jan 199705:00
attackerkb
cve
CVE
CVE-1999-0511
4 Feb 200005:00
cve
cvelist
Cvelist
CVE-1999-0511
4 Feb 200005:00
cvelist
euvd
EUVD
EUVD-1999-0509
4 Feb 200005:00
euvd
f5
F5 Networks
K16430721: IP forwarding vulnerability CVE-1999-0511
21 Feb 202319:59
f5
nessus
Tenable Nessus
IP Forwarding Enabled
23 Nov 201000:00
nessus
ncsc
NCSC
Vulnerability fixed in Moxa NPort 5110 firmware
29 Apr 202100:00
ncsc
nvd
NVD
CVE-1999-0511
1 Jan 199705:00
nvd
ptsecurity
Positive Technologies
PT-1997-1145
1 Jan 199700:00
ptsecurity
Rows per page
# Copyright (C) 2021 Greenbone Networks GmbH
# 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-or-later
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

if (description)
{
  script_oid("1.3.6.1.4.1.25623.1.0.147205");
  script_version("2021-12-03T08:27:06+0000");
  script_tag(name:"last_modification", value:"2021-12-03 08:27:06 +0000 (Fri, 03 Dec 2021)");
  script_tag(name:"creation_date", value:"2021-11-24 07:35:11 +0000 (Wed, 24 Nov 2021)");
  # nb: CVE linked below has a severity but is very broad, using a severity would cause too many
  # false positives as we're not able to determine if a system has IP Forwarding enabled on purpose
  # (e.g. a Router/Firewall) or not. This needs to be inspected manually.
  script_tag(name:"cvss_base", value:"0.0");
  script_tag(name:"cvss_base_vector", value:"AV:A/AC:L/Au:N/C:N/I:N/A:N");

  script_cve_id("CVE-1999-0511");

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

  script_name("IP Forwarding Enabled - Active Check");

  script_category(ACT_GATHER_INFO);

  script_copyright("Copyright (C) 2021 Greenbone Networks GmbH");
  script_family("General");
  script_dependencies("global_settings.nasl", "smtp_settings.nasl"); # nb: The setting for get_3rdparty_domain() is currently located in this VT.
  script_mandatory_keys("keys/islocalnet");
  script_exclude_keys("keys/islocalhost");

  script_tag(name:"summary", value:"Checks if the remote host has IP forwarding enabled.");

  script_tag(name:"vuldetect", value:"Sends a crafted Local Link Layer (LLL) frame and checks the
  response.");

  exit(0);
}

include("misc_func.inc");
include("string_hex_func.inc");
include("version_func.inc");
include("dump.inc");
include("network_func.inc");
include("byte_func.inc");
include("smtp_func.inc");

# nb: Available since GOS 21.04.10 / openvas-scanner 21.04.4
if (!defined_func("get_local_mac_address_from_ip") ||
    !defined_func("send_arp_request") ||
    !defined_func("forge_frame") ||
    !defined_func("send_frame") ||
    !defined_func("dump_frame"))
  exit(0);

if (islocalhost())
  exit(0);

if (!islocalnet())
  exit(0);

debug = 0;
src_ip = this_host();
dst_ip = get_host_ip();
ext_host = get_3rdparty_domain();
ext_ips = resolve_hostname_to_multiple_ips(hostname: ext_host);

# nb: Loop over the list (e.g. if IPv4 and IPv6 IPs are returned) and pick out the first IP matching
# the used IP version.
foreach _ext_ip (ext_ips) {
  if (TARGET_IS_IPV6()) {
    if (":" >< _ext_ip) {
      ext_ip = _ext_ip;
      break;
    }
  } else {
    if (":" >!< _ext_ip) {
      ext_ip = _ext_ip;
      break;
    }
  }
}

# nb: Just a fallback if anything has gone wrong (e.g. we're scanning an IPv4 target but the
# as external defined host is only reachable via IPv6).
if (!ext_ip)
  ext_ip = resolve_host_name(hostname: ext_host);

src_mac = get_local_mac_address_from_ip(src_ip);
if (isnull(src_mac)) {
  if (debug) display("DEBUG: get_local_mac_address_from_ip() call failed for IP '", src_ip, "'");
  exit(0);
}

dst_mac = send_arp_request(host: dst_ip);
if (isnull(dst_mac)) {
  if (debug) display("DEBUG: send_arp_request() call failed for IP '", dst_ip, "'");
  exit(0);
}

if (debug) display("DEBUG:\nSource IP:       ", src_ip, "\nSource MAC:      ", src_mac, "\nDestination IP:  ", dst_ip, "\nDestination MAC: ", dst_mac, "\nExternal IP:     ", ext_ip, " (", ext_host, ")");

split = split(src_mac, sep: ":", keep:FALSE);
for (i = 0; i < max_index(split); i++)
  src_mac_raw += hex2raw(s: split[i]);

split = split(dst_mac, sep: ":", keep:FALSE);
for (i = 0; i < max_index(split); i++)
  dst_mac_raw += hex2raw(s: split[i]);

function create_packet(src_ip, ext_ip, ip_proto, src_mac_raw, debug) {

  local_var src_ip, ext_ip, ip_proto, src_mac_raw, debug;
  local_var ret_arry, vt_strings, data, src_port, dst_port, dst_ip, IPV6_VERSION, ip_packet, tcp_packet, filter, ether_proto;
  local_var ICMP6_ECHO_REQ_TYPE, ICMP6_ECHO_RES_TYPE, ICMP_ID, ICMP_ID_REVERSE, icmp_packet;
  local_var ICMP_ECHO_REQ_TYPE, ICMP_ECHO_RES_TYPE;

  ret_arry = make_array();
  vt_strings = get_vt_strings();
  data = vt_strings["default_rand"];
  src_port = (rand() + 1024) % 65535;
  dst_port = (rand() + 1024) % 65535;

  # nb: On TCP we're setting src_ip = dst_ip, on ICMP we're trying to sent an ICMP ECHO REQUEST to
  # an external system.
  if (ip_proto == IPPROTO_TCP)
    dst_ip = src_ip;
  else
    dst_ip = ext_ip;

  if (TARGET_IS_IPV6()) {

    # nb: Previous versions had calculated a wrong IPv6 flow label
    # (see https://github.com/greenbone/openvas/pull/545) which
    # requires this workaround here.
    # TODO: Remove once all GOS/GVM versions < 20.8.0 are EOL.
    if (version_is_less(version: OPENVAS_VERSION, test_version: "20.8.0"))
      IPV6_VERSION = 0x60;
    else
      IPV6_VERSION = 6;

    # TODO: Use forge_ip_v6_packet once all GOS/GVM versions < 20.8.0 are EOL.
    ip_packet = forge_ipv6_packet(ip6_v    : IPV6_VERSION,
                                  ip6_p    : ip_proto,
                                  ip6_src  : src_ip,
                                  ip6_dst  : dst_ip,
                                  # nb: Those are the defaults from (see note in function description on the reason):
                                  # https://github.com/greenbone/openvas-scanner/blob/v21.4.2/nasl/nasl_packet_forgery_v6.c#L112-L126
                                  ip6_tc   : 0,
                                  ip6_fl   : 0,
                                  ip6_hlim : 64);

    if (!ip_packet) {
      if (debug) display("DEBUG: forge_ipv6_packet() call failed.");
      return NULL;
    }

    if (debug) { display("---[ Crafted IPv6 packet ]---"); dump_ipv6_packet(ip_packet); }

    if (ip_proto == IPPROTO_TCP) {

      tcp_packet = forge_tcp_v6_packet(ip6           : ip_packet,
                                       data          : data,
                                       th_sport      : src_port,
                                       th_dport      : dst_port,
                                       # nb: Those are the defaults from (see note in function description on the reason):
                                       # https://github.com/greenbone/openvas-scanner/blob/v21.4.2/nasl/nasl_packet_forgery_v6.c#L520-L538
                                       th_seq        : rand(),
                                       th_ack        : 0,
                                       th_x2         : 0,
                                       th_off        : 5,
                                       th_flags      : 0,
                                       th_win        : 0,
                                       th_urp        : 0,
                                       update_ip_len : TRUE);

      if (!tcp_packet) {
        if (debug) display("DEBUG: forge_tcp_v6_packet() call failed.");
        return NULL;
      }

      ret_arry["packet"] = tcp_packet;

      if (debug) { display("---[ Crafted TCP packet ]---"); dump_tcp_v6_packet(tcp_packet); }

      filter = string("ether dst ", hexstr(src_mac_raw), " and dst port ", dst_port);
      ret_arry["filter"] = filter;

    } else {

      ICMP6_ECHO_REQ_TYPE = 128;
      ICMP6_ECHO_RES_TYPE = 129;
      ICMP_ID = rand() % 65536;

      # nb: See description on the filter below
      set_byte_order(BYTE_ORDER_LITTLE_ENDIAN);
      ICMP_ID_REVERSE = mkdword(ICMP_ID);
      # nb: Reset to the default of byte_func.inc
      set_byte_order(BYTE_ORDER_BIG_ENDIAN);
      ICMP_ID_REVERSE = getword(blob: ICMP_ID_REVERSE);

      icmp_packet = forge_icmp_v6_packet(ip6       : ip_packet,
                                         icmp_type : ICMP6_ECHO_REQ_TYPE,
                                         icmp_code : 0,
                                         icmp_seq  : 1,
                                         icmp_id   : ICMP_ID,
                                         data      : data);

      if (!icmp_packet) {
        if (debug) display("DEBUG: forge_icmp_v6_packet() call failed.");
        return NULL;
      }

      ret_arry["packet"] = icmp_packet;

      if (debug) { display("---[ Crafted ICMPv6 packet ]---"); dump_icmp_v6_packet(icmp_packet); }

      # nb: Some older pcap versions seems do not support the following syntax:
      # filter = string("ether dst ", hexstr(src_mac_raw), " and icmp6[0] = ", ICMP6_ECHO_RES_TYPE, " and icmp6[4:2] = ", ICMP_ID);
      # and are throwing a "pcap_compile : IPv6 upper-layer protocol is not supported by proto[x]" message so we're parsing the type and id directly
      # from the IPv6 payload to work around this.
      # Note that icmp6[4:2] seems to be able to handle Big vs. Little Endian where ip6[44:2] isn't so we're using "ICMP_ID_REVERSE" and "ICMP_ID" here "just to be safe".
      filter = string("ether dst ", hexstr(src_mac_raw), " and ip6[40] = ", ICMP6_ECHO_RES_TYPE, " and ( ip6[44:2] = ", ICMP_ID, " or ip6[44:2] = ", ICMP_ID_REVERSE, " )");
      ret_arry["filter"] = filter;

    }

    ether_proto = get_ethertype_proto_value(proto: "ipv6");
    ret_arry["ether_proto"] = ether_proto;
    return ret_arry;
  } else {

    ip_packet = forge_ip_packet(ip_v   : 4,
                                ip_hl  : 5,
                                ip_tos : 0,
                                ip_len : 20,
                                ip_id  : rand() % 65535,
                                ip_p   : ip_proto,
                                ip_ttl : 255,
                                ip_off : 0,
                                ip_src : src_ip,
                                ip_dst : dst_ip);

    if (!ip_packet) {
      if (debug) display("DEBUG: forge_ip_packet() call failed.");
      return NULL;
    }

    if (debug) { display("---[ Crafted IPv4 packet ]---"); dump_ip_packet(ip_packet); }

    if (ip_proto == IPPROTO_TCP) {

      tcp_packet = forge_tcp_packet(ip       : ip_packet,
                                    th_ack   : 0,
                                    th_dport : dst_port,
                                    th_flags : TH_SYN,
                                    th_sport : src_port,
                                    th_x2    : 0,
                                    th_off   : 5,
                                    th_win   : 1024,
                                    th_urp   : 0,
                                    data     : data);

      if (!tcp_packet) {
        if (debug) display("DEBUG: forge_tcp_packet() call failed.");
        return NULL;
      }

      ret_arry["packet"] = tcp_packet;

      if (debug) { display("---[ Crafted TCP packet ]---"); dump_tcp_packet(tcp_packet); }

      filter = string("ether dst ", hexstr(src_mac_raw), " and dst port ", dst_port);
      ret_arry["filter"] = filter;

    } else {

      ICMP_ECHO_REQ_TYPE = 8;
      ICMP_ECHO_RES_TYPE = 0;
      ICMP_ID = rand() % 65536;

      icmp_packet = forge_icmp_packet(icmp_type : ICMP_ECHO_REQ_TYPE,
                                      icmp_code : 0,
                                      icmp_seq  : 1,
                                      icmp_id   : ICMP_ID,
                                      data      : data,
                                      ip        : ip_packet);

      if (!icmp_packet) {
        if (debug) display("DEBUG: forge_icmp_packet() call failed.");
        return NULL;
      }

      ret_arry["packet"] = icmp_packet;

      if (debug) { display("---[ Crafted ICMP packet ]---"); dump_icmp_packet(icmp_packet); }

      filter = string("ether dst ", hexstr(src_mac_raw), " and icmp[0] = ", ICMP_ECHO_RES_TYPE, " and icmp[4:2] = ", ICMP_ID);
      ret_arry["filter"] = filter;

    }

    ether_proto = get_ethertype_proto_value(proto: "ipv4");
    ret_arry["ether_proto"] = ether_proto;
    return ret_arry;
  }
}

if (TARGET_IS_IPV6()) {
  # nb: This variable was added in GOS/GVM 20.8.0, see:
  # https://github.com/greenbone/openvas/pull/549
  # TODO: Remove once all GOS/GVM versions < 20.8.0 are EOL.
  if (!IPPROTO_ICMPV6)
    IPPROTO_ICMPV6 = 58;
  ip_protos = make_list(make_list(IPPROTO_TCP, IPPROTO_ICMPV6));
} else {
  ip_protos = make_list(make_list(IPPROTO_TCP, IPPROTO_ICMP));
}

# nb: Some systems (have seen this on a Palo Alto PA-220 doesn't forward the crafted TCP request but
# using an ICMP ECHO request sent to an external system works so we're checking both cases just to be sure.
foreach ip_proto (ip_protos) {

  packet_info = create_packet(src_ip: src_ip, ext_ip: ext_ip, ip_proto: ip_proto, src_mac_raw: src_mac_raw, debug: debug);
  if (!packet_info)
    continue;

  payload = packet_info["packet"];
  ether_proto = packet_info["ether_proto"];

  frame = forge_frame(src_haddr: src_mac_raw, dst_haddr: dst_mac_raw, ether_proto: ether_proto, payload: payload);
  if (!frame) {
    if (debug) display("DEBUG: forge_frame() call failed.");
    continue;
  }

  if (debug) { display("---[ Crafted Ethernet Frame ]---"); dump_frame(frame: frame); }

  filter = packet_info["filter"];

  if (debug) display("---[ Used PCAP filter ]---", "\n", filter);

  recv = send_frame(frame: frame, pcap_filter: filter, timeout: 10);

  if (!recv) {
    if (debug) display("DEBUG: No answer received with send_frame().");
    continue;
  } else {
    if (debug) { display("---[ Received Ethernet Frame ]---"); dump_frame(frame: recv); }
  }

  if (recv) {
    if (ip_proto == IPPROTO_TCP)
      report_proto = "a TCP";
    else
      report_proto = "an ICMP";
    report = "It was possible to route " + report_proto + " packet through the target host and received an answer which means IP forwarding is enabled.";
    log_message(port: 0, data: report);
    exit(0);
  }
}

exit(0);

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

03 Dec 2021 00:00Current
7.2High risk
Vulners AI Score7.2
CVSS 27.5
CVSS 3.19.1
EPSS0.06964
SSVC
36