Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to transmit ICMP by bypassing firewall filtering rules

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

How to bypass firewall filtering rules to transmit ICMP, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.

ICMP and ICMPv6

ICMP and ICMPv6 are the main protocols of Internet. These protocols are designed for connection testing and error signaling when packets do not reach their destination. Receiving ICMP messages lets the application know the cause of the failure: the packet is too large, there are no available routes, and so on.

ICMP message

For different purposes, ICMP [V6] messages are identified by two values encoded as two bytes: their type and code. Each type has a different meaning. For example, ICMP has the following message:

1.Echo replies and requests (types 1 and 8)

two。 Destination unreachable (type 3)

3.Source quench (type 4)

4. Timestamp replies and requests (types 14 and 15)

When ICMPv6 has:

1. Destination unreachable (type 1)

two。 Packet too large (type 2)

3. Out of time (type 3)

4. Parameter problem (type 4)

5. Router inquiry and advertisement (types 133 and 134)

6. Neighbor inquiries and announcements (types 135 and 136)

Various message types have been deprecated in the past, while other message types are still in use. We can roughly classify ICMP messages into three categories according to their purpose:

1. Requests: they are generated by the host to query some information

two。 Replies: they are ICMP responses to the above ICMP request

3. Error: they are created by network devices or hosts when they are unable to process packets.

This article focuses on error messages. This category is interesting because its messages are sent as out-of-band traffic in response to layer 4 communication of another protocol.

For example, UDP grouping may generate ICMP errors. These errors are usually encapsulated in the ICMP payload, the IP header, plus the next 64 bytes of the violation packet. Figure 1 shows this behavior of host B rejecting packets on closed ports:

Known attacks and measures

As a signaling protocol, ICMP messages can change the behavior of the IP stack of the receiving system. For example, ICMP Redirect and ICMPv6 Router advertisements can change the routing table of a host.

A malicious user may abuse ICMP to disrupt network operations. Various ICMP-related attacks have been documented in the past:

1.ICMP punching [1] is the concept of traversing NAT with the help of ICMP messages. It requires the initiator to be behind the NAT

2.ICMP tunnel [2] misuses ICMP protocol to encapsulate arbitrary data on ICMP messages.

3.ICMP ECHO magnification [3] use broadcast to perform DoS

4. Network traffic can be slowed down by attacking the MTU discovery process or packet congestion [4] [5] [6] signaling.

5.ICMPv6 NDP attacks [7] (similar to ARP attacks in the IPv4 world)

6.ICMPv6 MLD discovers + DoS [8] (similar to IGMP attacks).

Most of these risks can be mitigated by properly configuring the operating system's IP stack. Interestingly, various ICMP protections (for example, sysctl,netsh,...) can be enabled without using the operating system firewall feature.

An example of using sysctl on Linux:

# sysctl-a-r'^ net\ .ipv [46]\. (icmp | conf\ .default\ .accept)'| cut-d =-F1

Net.ipv4.conf.default.accept_local

Net.ipv4.conf.default.accept_redirects

Net.ipv4.conf.default.accept_source_route

Net.ipv4.icmp_echo_ignore_all

Net.ipv4.icmp_echo_ignore_broadcasts

Net.ipv4.icmp_errors_use_inbound_ifaddr

Net.ipv4.icmp_ignore_bogus_error_responses

Net.ipv4.icmp_msgs_burst

Net.ipv4.icmp_msgs_per_sec

Net.ipv4.icmp_ratelimit

Net.ipv4.icmp_ratemask

Net.ipv6.conf.default.accept_dad

Net.ipv6.conf.default.accept_ra

Net.ipv6.conf.default.accept_ra_defrtr

Net.ipv6.conf.default.accept_ra_from_local

...

Net.ipv6.conf.default.accept_redirects

Net.ipv6.conf.default.accept_source_route

Net.ipv6.icmp.ratelimit

Ideally, dangerous ICMP messages should be blocked by each host's IP stack without the need for a firewall. In fact, security hardening is usually implemented by a firewall between WAN and restricted LAN. Here's a question: how do you filter ICMP and ICMPv6?

How do I filter ICMP? Content recommended by RFC

It is not possible to block all message types when filtering ICMP messages. It reduces the overall user experience. For example, blocking "packet too large" can actually completely prevent IPv6 from working and may significantly degrade IPv4 performance.

RFC4890 [10] (2007) says that ICMPv6 error messages are allowed in Chapter 4.3.1. Traffic that cannot be discarded:

Error messages that are critical to building and building

Communication maintenance:

-destination unreachable (type 1)-all codes

-packet is too large (type 2)

-time elapsed (type 3)-Code 0 only

-Parameter problem (type 4)-codes 1 and 2 only

The (expired) draft "recommendations for filtering ICMP messages" [9] (2013) provides two tables summarizing which ICMP and ICMPv6 messages should be accepted, speed-limited, or rejected when the device acts as a gateway or firewall. The draft proposes to allow (accept or restrict) the following messages:

1. ICMPv4Mutual unreachable-(net | host | frag-needed | admin)

2. ICMPv4Mustimed-(ttl | reass)

3. ICMPv6-unreach- (no-route | admin-prohibited | addr | port | reject-route)

4.ICMPv6 's is too big.

5. ICMPv6-timed- (hop-limit | reass) of

Parameters for 6.ICMPv6-UNREC option

7. ICMPv6 Murrel-expanded.

It seems that people have different views on what secure ICMP traffic is. It is generally believed that the firewall should block all inbound ICMP and ICMPv6 packets from the WAN (except NDP) unless they are related to a known existing connection and can be tracked through the stateful firewall.

Firewall status and related traffic

In fact, stateful firewalls implement the concept of related packets. These related packets are packets that match out-of-band traffic attached to existing connections. Related concepts are used with ICMP and also with other protocols, such as FTP, which can use auxiliary TCP streams.

With regard to ICMP, the association between in-band and out-of-band traffic is accomplished by extracting the "status identifier" from the IP packet encapsulated in the ICMP error message. If the connection is known, this identifier is used to look up in the table.

To illustrate this concept, let's consider the following example. In a simple network, we want to allow only hosts on LAN to contact any host on WAN through UDP on port 1234. But we still want A to receive out-of-band errors. In this case, the following advanced firewall configuration will be used:

1. Allow input from LAN to WAN udp port 1234

two。 Allow input from WAN to LAN if the packet is related to an existing allowed connection

3. Stop everything.

Outgoing in-band UDP traffic will match the rules:

1. Incoming out-of-band ICMP error messages will match the rule

two。 As shown in figure 2, and any other packets will be rejected by Rule 3.

In fact, the semantics of the firewall configuration are different, and rule 2 may be implicit in some implementations.

What is the connection status?

So far, we know that stateful firewalls infer states from ICMP (or ICMPv6) errors. But the remaining question is, what information is actually extracted from internal IP packets?

Because layer 4 protocols have different semantics, each protocol has its own extractor, but we observe the following in packet filters and nftables derivatives:

For TCP, the following fields are used for construction status:

1. Internal IP source and destination

two。 Internal source and destination port

The 3.SEQ and ACK fields are used only for packet filters, but not for nftables.

For UDP, the following fields are used for construction status:

1. Internal IP source and destination

two。 Internal source and destination ports.

For ICMP, the following fields are used for construction status:

1. Internal IP source and destination

two。 The various ICMP fields depend on the type.

For other protocols:

1. Internal IP source and destination

two。 Id of the protocol

3. If the firewall supports them, the properties provided by the protocol (for example: SCTP or UDP-Lite port) will be used (nftables can, Packet Filter cannot).

A quick review

In summary, when the firewall receives an out-of-band ICMP error, it does the following:

1. Decode IP / ICMP or IPv6 / ICMPv6 headers

two。 Extract status from encapsulated IP or IPv6 packets

3. Try to match the status Identifier in the existing status list

4. If the internal IP packet state matches the existing state, the packet is marked as relevant.

ICMP- reachability problem

We found that when the internal packet is extracted to find the state, the correlation with the external packet is lost. This means that as long as the encapsulated packet can be associated with an existing connection, the entire packet is marked as relevant. Then, in most cases, the packet is allowed to pass.

This behavior can be abused using maliciously crafted ICMP [V6] packets that target filtered hosts while encapsulating packets that match the legitimate state, as follows:

ICMP-Reachable packet:

[IP src=@M dst=@H type=ICMP]

[ICMP type=@Type code=@Code]

[IP src=@B dst=@A]

[UDP sport=@Pb dport=Pa]

M: the attacker IP

H: the destination IP on which ICMP should be filtered

A: host IP from which the attacker knows an existing session with B

B: host IP from which the attacker knows an existing session with A

Pa: the port used by An its UDP session with B

Pb: the port used by B its UDP session with A

Type: the ICMP type of an out-of-band error packet (example 3)

Code: the ICMP code of an out-of-band error packet (example 3)

In this case, malicious ICMP [V6] packets will be allowed to pass. Both nftables and Packet Filter implementations are affected by this behavior.

The following sections will cover the implementation details of Linux and OpenBSD to understand where the correlation is lost.

NFTABLES implementation and details

Linux implements the concept of related packets in the netfilter conntrack module.

It starts in netfilter/nf_conntrack_core.c with the function nf_conntrack_in, which handles each input packet passed in the parameter skb. Deal with layer 4 protocol and extraction of ICMP and ICMPv6 in nf_conntrack_handle_icmp.

Unsigned int

Nf_conntrack_in (struct sk_buff * skb, const struct nf_hook_state * state)

{

/ /..

L4proto = _ _ nf_ct_l4proto_find (protonum)

If (protonum = = IPPROTO_ICMP | | protonum = = IPPROTO_ICMPV6) {

Ret = nf_conntrack_handle_icmp (tmpl, skb, dataoff

Protonum, state)

If (ret _ nfct)

Goto out

}

/ /...

}

Nf_conntrack_handle_icmp then calls nf_conntrack_icmpv4_error () or nf_conntrack_icmpv6_error () depending on the version of ICMP. These features are very similar, so let's focus on ICMP.

If the type is one of the following, nf_conntrack_icmpv4_error validates the ICMP header and calls icmp_error_message:ICMP_DEST_UNREACH,ICMP_PARAMETERPROB,ICMP_REDIRECT,ICMP_SOURCE_QUENCH,ICMP_TIME_EXCEEDED:

/ * Small and modified version of icmp_rcv * /

Int nf_conntrack_icmpv4_error (struct nf_conn * tmpl

Struct sk_buff * skb, unsigned int dataoff

Const struct nf_hook_state * state)

{

Const struct icmphdr * icmph

Struct icmphdr _ ih

/ * Not enough header? * /

Icmph = skb_header_pointer (skb, ip_hdrlen (skb), sizeof (_ ih), & _ ih)

If (icmph = = NULL) {

Icmp_error_log (skb, state, "short packet")

Return-NF_ACCEPT

}

/ /...

If (icmph- > type > NR_ICMP_TYPES) {

Icmp_error_log (skb, state, "invalid icmp type")

Return-NF_ACCEPT

}

/ * Need to track icmp error message? * /

If (icmph- > type! = ICMP_DEST_UNREACH & &

Icmph- > type! = ICMP_SOURCE_QUENCH & &

Icmph- > type! = ICMP_TIME_EXCEEDED & &

Icmph- > type! = ICMP_PARAMETERPROB & &

Icmph- > type! = ICMP_REDIRECT)

Return NF_ACCEPT

Return icmp_error_message (tmpl, skb, state)

}

The icmp_error_message is then responsible for extracting and identifying the matching status:

/ * Returns conntrack if it dealt with ICMP, and filled in skb fields * /

Static int

Icmp_error_message (struct nf_conn * tmpl, struct sk_buff * skb

Const struct nf_hook_state * state)

{

/ /...

WARN_ON (skb_nfct (skb))

Zone = nf_ct_zone_tmpl (tmpl, skb, & tmp)

/ * Are they talking about one of our connections? * /

If (! nf_ct_get_tuplepr (skb

Skb_network_offset (skb) + ip_hdrlen (skb)

+ sizeof (struct icmphdr)

PF_INET, state- > net, & origtuple) {

Pr_debug ("icmp_error_message: failed to get tuple\ n")

Return-NF_ACCEPT

}

/ * rcu_read_lock () ed by nf_hook_thresh * /

Innerproto = _ _ nf_ct_l4proto_find (origtuple.dst.protonum)

/ * Ordinarily, we'd expect the inverted tupleproto, but it's

Been preserved inside the ICMP. , /

If (! nf_ct_invert_tuple (& innertuple, & origtuple, innerproto)) {

Pr_debug ("icmp_error_message: no match\ n")

Return-NF_ACCEPT

}

Ctinfo = IP_CT_RELATED

H = nf_conntrack_find_get (state- > net, zone, & innertuple)

If (! h) {

Pr_debug ("icmp_error_message: no match\ n")

Return-NF_ACCEPT

}

If (NF_CT_DIRECTION (h) = = IP_CT_DIR_REPLY)

Ctinfo + = IP_CT_IS_REPLY

/ * Update skb to refer to this connection * /

Nf_ct_set (skb, nf_ct_tuplehash_to_ctrack (h), ctinfo)

Return NF_ACCEPT

}

1. First, the network area of the packet skb is calculated using nf_ct_zone_tmpl. Nftables has the concept of network conntrack area. These areas allow virtualized connection tracking to handle multiple connections with the same identity in conntrack and NAT. Unless there are clear rules, all packets will enter zone 0 (see the man page of the target CT)

two。 Nf_ct_get_tuplepr is then used to extract the ip connection status origtuple from the IP Datagram within the ICMP layer

3.nf_ct_invert_tuple performs a source / destination exchange of state because it references the original outbound packet but the firewall wants to check the inbound packet

4.nf_conntrack_find_get looks for a known state that matches the extracted state. At this point we see that the outer IP layer is not considered for lookup status

5. If a state is found, nf_ct_set marks a sbk packet with an associated state (IP_CT_RELATED).

For ICMPv6, we have a similar implementation for messages of type less than 128.

Packet filter implementation and details

In the packet filter, the relevant concepts are actually implicit and implemented under the concept of state. The overall design of packet filtering is as follows:

Can packets be associated with status?

1. If so, the packet is allowed to pass

two。 If not, the grouping is tested according to the filtering rules. If the matching rule allows the packet to pass, a state may be created.

The whole logic is implemented in the function pf_test in / sys/net/pf.c. The next excerpt shows this handling of ICMP [V6] (some of the code has been stripped for clarity):

Pf_test (sa_family_t af, int fwdir, struct ifnet * ifp, struct mbuf * * M0)

{

/ /...

Switch (pd.virtual_proto) {

Case IPPROTO_ICMP: {

/ / look for a known state

Action = pf_test_state_icmp (& pd, & s, & reason)

S = pf_state_ref (s)

If (action = = PF_PASS | | action = = PF_AFRT) {

/ / if a valid state is found the packet might go there

/ / without being tested against the filtering rules

R = s-> rule.ptr

A = s-> anchor.ptr

Pd.pflog | = s-> log

} else if (s = = NULL) {

/ / if no state is found the packet is tested

Action = pf_test_rule (& pd, & r, & s, & a, & ruleset, & reason)

S = pf_state_ref (s)

}

Break

}

Case IPPROTO_ICMPV6: {

/ / look for a known state

Action = pf_test_state_icmp (& pd, & s, & reason)

S = pf_state_ref (s)

If (action = = PF_PASS | | action = = PF_AFRT) {

/ / if a valid state is found the packet might go there

/ / without being tested against the filtering rules

R = s-> rule.ptr

A = s-> anchor.ptr

Pd.pflog | = s-> log

} else if (s = = NULL) {

/ / if no state is found the packet is tested

Action = pf_test_rule (& pd, & r, & s, & a, & ruleset, & reason)

S = pf_state_ref (s)

}

Break

}

/ /...

}

Pf_test_state_icmp () is a function that attempts to find the relationship between this packet and a known connection. It uses a call to pf_icmp_mapping () to know whether the packet is in-band or out-of-band. In the latter case, the internal IP packet and its layer 4 protocol are extracted to find the state. This is shown in the following excerpt:

Int pf_test_state_icmp (struct pf_pdesc * pd, struct pf_state * * state, u_short * reason) {

/ /...

If (pf_icmp_mapping (pd, icmptype, & icmp_dir, & virtual_id, & virtual_type) = = 0) {/ /

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report