CVE-2020-16898 "Bad Neighbor " Windows TCP/IP遠(yuǎn)程代碼執(zhí)行漏洞分析
一、漏洞信息
1. 漏洞簡(jiǎn)述
- 漏洞名稱:Windows TCP/IP Remote Code Execution Vulnerability
- 漏洞編號(hào):CVE-2020-16898
- 漏洞類型:Design Weakness
- 漏洞影響:Code Execution
- CVSS評(píng)分:9.8
- 利用難度:Medium
- 基礎(chǔ)權(quán)限:不需要
2. 組件概述
TCP/IP是Internet上使用的通信協(xié)議。 在Windows的早期版本中,TCP/IP是一個(gè)單獨(dú)的可選組件,可以像其他任何協(xié)議一樣刪除或添加。從Windows XP/Server 2003開(kāi)始,TCP/IP成為操作系統(tǒng)的核心組件,無(wú)法刪除。 將TCP/IP作為Windows的核心組件是非常有意義的,因?yàn)樗墓δ茉贛icrosoft Windows Server上對(duì)網(wǎng)絡(luò)操作和Active Directory域環(huán)境尤為重要。 整個(gè)Active Directory架構(gòu)基于DNS層次結(jié)構(gòu),依賴于TCP/IP 傳輸協(xié)議 。
Microsoft Windows中的TCP/IP功能在內(nèi)核級(jí)別運(yùn)行,并由驅(qū)動(dòng)程序tcpip.sys提供。該驅(qū)動(dòng)程序處理所有傳入和傳出的TCP/IP通信信息,包括解析從網(wǎng)絡(luò)接口接收到的數(shù)據(jù)包,以及解釋此數(shù)據(jù)并將其傳遞給更高級(jí)別的組件。
3. 漏洞利用
該漏洞主要是由于Windows TCP/IP堆棧在處理選項(xiàng)類型為25(0x19,遞歸DNS服務(wù)器選項(xiàng))且長(zhǎng)度字段值為偶數(shù)的ICMPv6的路由廣播數(shù)據(jù)包時(shí),處理邏輯存在紕漏,導(dǎo)致存在遠(yuǎn)程代碼執(zhí)行漏洞。成功利用該漏洞的攻擊者可以在目標(biāo)機(jī)器(主機(jī)或服務(wù)器)上執(zhí)行任意代碼。
4. 漏洞影響
- Microsoft Windows 10 1709
- Microsoft Windows 10 1803
- Microsoft Windows 10 1809
- Microsoft Windows 10 1903
- Microsoft Windows 10 1909
- Microsoft Windows 10 2004
- Microsoft Windows Server 2019
- Microsoft Windows Server, version 1903
- Microsoft Windows Server, version 1909
- Microsoft Windows Server, version 2004
5. 解決方案
官方解決方案:微軟官方針對(duì)該漏洞已發(fā)布安全更新補(bǔ)丁,補(bǔ)丁地址:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16898
臨時(shí)解決方案:
管理員啟動(dòng)powershell或cmd,輸入以下命令檢查所有網(wǎng)絡(luò)IPv6接口的列表以及相應(yīng)的索引號(hào):
netsh int ipv6 sh int
樣例輸出如下:
確認(rèn)網(wǎng)絡(luò)接口的RDNSS功能開(kāi)啟情況:
netsh int ipv6 sh int Idx number
執(zhí)行以下命令關(guān)閉RDNSS功能(將Idx number替換為要關(guān)閉的網(wǎng)絡(luò)接口的Idx值):
netsh int ipv6 set int Idx number rabaseddnsconfig=disable
樣例輸出如下:
此時(shí)再次確認(rèn)接口的RDNSS開(kāi)啟情況,RDNSS功能已被關(guān)閉:
二、漏洞復(fù)現(xiàn)
1. 環(huán)境搭建
l 靶機(jī):Windows 10 1809 x64
l 靶機(jī)操作:無(wú)需任何操作,可正常與攻擊機(jī)通信即可
2. 復(fù)現(xiàn)過(guò)程
1. 通過(guò)各種手段獲取目標(biāo)主機(jī)的IPv6地址和MAC地址(具體方法可自行探索,較為簡(jiǎn)單)
2. 攻擊機(jī)python3運(yùn)行poc:
3. 靶機(jī)crash:
三、漏洞分析
1. 基本信息
- 漏洞文件:tcpip.sys
- 漏洞函數(shù):Ipv6pUpdateRDNSS()函數(shù)
- 漏洞對(duì)象:ICMPv6路由廣播中的option結(jié)構(gòu)
2. 背景知識(shí)
限于篇幅問(wèn)題,此處不對(duì)用于DNS配置的IPv6路由廣播進(jìn)行詳細(xì)介紹,更詳細(xì)資料可參考RFC8106。
1. 基本知識(shí)
IPv6 Router Advertisment (RA) options,也稱為DNS RA options,允許IPv6的路由器向IPv6的主機(jī)廣播DNS Recursive Server Address(DNS遞歸路由器地址)列表和DNS Search List(DNS搜索列表),其主要用途為在IPv6的主機(jī)上進(jìn)行DNS名稱解析以及域后綴的處理。
IPv6 Neighbor Discovery(ND,IPv6鄰居發(fā)現(xiàn))和IPv6 Stateless Address Autoconfiguratioin(SLAAC,IPv6無(wú)狀態(tài)地址自動(dòng)配置)提供了使用一個(gè)或多個(gè)IPv6地址,默認(rèn)路由器以及一些其他參數(shù)配置固定節(jié)點(diǎn)或移動(dòng)節(jié)點(diǎn)的方法。
當(dāng)漫游主機(jī)每次連接到另一個(gè)網(wǎng)絡(luò)時(shí),無(wú)法進(jìn)行手動(dòng)配置。 雖然可以進(jìn)行靜態(tài)配置,但是在諸如筆記本電腦之類的通用主機(jī)上通常不建議這樣操作。 例如,如果主機(jī)運(yùn)行直接連接到全局DNS的自己的遞歸名稱服務(wù)器,那么本地定義的名稱空間對(duì)主機(jī)來(lái)說(shuō)就不可用了。 訪問(wèn)DNS是幾乎所有主機(jī)的基本要求,因此IPv6 SLAAC在沒(méi)有任何DNS配置支持的情況下,不能在任何實(shí)際的網(wǎng)絡(luò)環(huán)境中單獨(dú)作為替代部署模型。
對(duì)于IPv4環(huán)境中的DNS服務(wù)器來(lái)說(shuō),這些問(wèn)題都很容易解決。但是對(duì)于IPv6的網(wǎng)絡(luò)環(huán)境,這些問(wèn)題顯得比較棘手。因此,RFC8106定義了一種基于DNS RA選項(xiàng)的機(jī)制,以允許IPv6主機(jī)執(zhí)行自動(dòng)DNS配置。
在通過(guò)IPv6 SLAAC自動(dòng)配置IPv6主機(jī)地址并且沒(méi)有DHCPv6基礎(chǔ)結(jié)構(gòu)或一些主機(jī)沒(méi)有DHCPv6客戶端的網(wǎng)絡(luò)環(huán)境中,可以使用基于RA的DNS配置作為替代。 但是,對(duì)于需要分發(fā)其他信息的網(wǎng)絡(luò),可能仍然會(huì)使用DHCPv6。 在這些網(wǎng)絡(luò)中,可能不需要基于RA的DNS配置。 基于RA的DNS配置允許IPv6主機(jī)獲取主機(jī)連接到的鏈接的DNS配置(即DNS遞歸服務(wù)器地址和DNSSL)。 此外,主機(jī)會(huì)從提供鏈接配置信息的同一RA消息中學(xué)習(xí)此DNS配置。
2. 名詞解釋
- Recursive DNS Server (RDNSS):遞歸DNS服務(wù)器,提供遞歸DNS解析服務(wù)的服務(wù)器,用于將域名轉(zhuǎn)換為IP地址或解析成RFC1034和RFC1035中定義的PTR記錄。
- RDNSS Option:一個(gè)用于向IPv6主機(jī)傳送RDNSS信息的IPv6的RA option【RFC4861】。
- DNS Search List (DNSSL):Pv6主機(jī)在執(zhí)行DNS查詢搜索時(shí)使用的DNS后綴域名列表,用于搜索簡(jiǎn)短的不合格域名。
- DNSSL Option:一個(gè)IPv6 RA選項(xiàng),用于將DNSSL信息傳遞到IPv6主機(jī)。
3. 詳細(xì)分析
1. 基礎(chǔ)分析
RFC8106標(biāo)準(zhǔn)化了RDNSS option,其中包含RDNSSes的地址。該信息使用現(xiàn)有ND message(例如RA)作為載體。IPv6主機(jī)可以通過(guò)RA消息配置一個(gè)或多個(gè)RDNSS的IPv6地址。
(1) 鄰居發(fā)現(xiàn)擴(kuò)展
RFC8106中定義的在鄰居發(fā)現(xiàn)中使用的IPv6 DNS配置算法需要用到2種ND options:RDNSS option和DNSSL option。與該漏洞相關(guān)的是RDNSS option,另外一種則與 CVE-2020-16899相關(guān)。
(2)RDNSS Option Structure
RDNSS option總體結(jié)構(gòu)如下:
對(duì)于Length字段,如果該選項(xiàng)中僅包含一個(gè)IPv6地址,則最小值為3。 每增加一個(gè)RDNSS地址,長(zhǎng)度就會(huì)增加2。接收的主機(jī)使用該字段來(lái)確定選項(xiàng)中IPv6地址的數(shù)量。
(3)Procedure in IPv6 Hosts
當(dāng)主機(jī)接收到RA消息中的DNS的options時(shí),其處理過(guò)程如下:
- 首先檢查L(zhǎng)engh字段的合法性:是否大于等于最小值3,以及是否滿足(Length - 1) % 2 == 0;
- 對(duì)于RDNSS option,還會(huì)檢查Address字段是否為一個(gè)單播地址;
- 如果以上驗(yàn)證通過(guò),則主機(jī)應(yīng)按順序?qū)⑦x項(xiàng)的值復(fù)制到DNS存儲(chǔ)庫(kù)和解析器存儲(chǔ)庫(kù)中。 否則,主機(jī)必須丟棄這些選項(xiàng)。
(4)Crash分析
首先分析dmp文件,查看crash現(xiàn)場(chǎng):
并沒(méi)有發(fā)現(xiàn)明顯的較為有價(jià)值的Call Stack信息,但是發(fā)現(xiàn)最終的crash原因的是GS機(jī)制的Security Cookie校驗(yàn)失敗,也就是說(shuō)該值被覆蓋掉了。那么很有可能是一個(gè)溢出。除此之外,只發(fā)現(xiàn)了tcpip!Ipv6pHandleRouterAdvertisement+0x1269函數(shù),再往后就直接報(bào)gsfailure了。
2. 靜態(tài)分析
分析使用的文件為Windows 10 1809 x64的tcpip.sys文件,版本為10.0.17763.316。
(1)函數(shù)調(diào)用鏈
根據(jù)crash現(xiàn)場(chǎng)信息,獲取到關(guān)鍵函數(shù)tcpip!Ipv6pHandleRouterAdvertisement(),首先確認(rèn)該函數(shù)到漏洞函數(shù)的前后調(diào)用鏈。
首先查看其交叉引用關(guān)系:
其上層調(diào)用函數(shù)為Icmpv6ReceiveDatagrams(),跟進(jìn),并查看交叉引用關(guān)系:
沒(méi)有再發(fā)現(xiàn)顯式的函數(shù)調(diào)用。轉(zhuǎn)而向tcpip!Ipv6pHandleRouterAdvertisement()的下層搜索:
發(fā)現(xiàn)漏洞函數(shù)調(diào)用。至此,函數(shù)調(diào)用鏈可以簡(jiǎn)單概括為:
- Icmpv6ReceiveDatagrams() -> tcpip!Ipv6pHandleRouterAdvertisement() -> Ipv6pUpdateRDNSS()
(2)漏洞函數(shù)分析
經(jīng)過(guò)簡(jiǎn)單分析可以明確,調(diào)用鏈的頂層函數(shù)Icmpv6ReceiveDatagrams()沒(méi)有發(fā)現(xiàn)實(shí)質(zhì)性的與該漏洞相關(guān)的處理代碼,而在tcpip!Ipv6pHandleRouterAdvertisement() 函數(shù)中發(fā)現(xiàn)了對(duì)漏洞函數(shù)Ipv6pUpdateRDNSS()的調(diào)用。根據(jù)crash分析,最后報(bào)了gsfailure,而且關(guān)鍵函數(shù)為tcpip!Ipv6pHandleRouterAdvertisement(),在該函數(shù)的起始位置確實(shí)發(fā)現(xiàn)了GS校驗(yàn):
那么很有可能是在漏洞函數(shù)Ipv6pUpdateRDNSS()中發(fā)生了溢出,導(dǎo)致了其調(diào)用函數(shù)tcpip!Ipv6pHandleRouterAdvertisement()的GS校驗(yàn)失敗。
進(jìn)入漏洞函數(shù)Ipv6pUpdateRDNSS():
首先獲取到RDNSS option結(jié)構(gòu),然后讀取Length字段來(lái)計(jì)算Address字段有幾個(gè)Address值。
確認(rèn)有多少Address之后,進(jìn)入循環(huán),對(duì)每個(gè)Address進(jìn)行處理,最關(guān)鍵的是分配合適的內(nèi)存。這里還有一個(gè)判斷,如果不是單播地址,直接忽略。
在進(jìn)行處理時(shí),存在一個(gè)問(wèn)題:假設(shè)Length的長(zhǎng)度為4,那么計(jì)算結(jié)束之后,AddressCount的值應(yīng)該為1。此時(shí),按照正常邏輯,Ipv6pUpdateRDNSS()函數(shù)應(yīng)該增加32字節(jié)(4*8)的緩沖區(qū),但是后續(xù)在分配緩沖區(qū)時(shí)只分配了24字節(jié):sizeof(ND_OPTION_RDNSS) + sizeof(IN6_ADDR) = 8 + 16 = 24,從而導(dǎo)致了緩沖區(qū)的溢出。
根據(jù)RFC8106的標(biāo)準(zhǔn),Length字段的值應(yīng)該滿足最小為3的奇數(shù)的情況。當(dāng)提供一個(gè)偶數(shù)Length值時(shí),Windows TCP/IP堆棧錯(cuò)誤地將buffer前進(jìn)了8個(gè)字節(jié)。這主要是因?yàn)槎褩T趦?nèi)部以16字節(jié)為增量進(jìn)行計(jì)數(shù),并且沒(méi)有使用非RFC兼容長(zhǎng)度值的處理代碼。這種不匹配導(dǎo)致堆棧將當(dāng)前選項(xiàng)的最后8個(gè)字節(jié)解釋為第二個(gè)選項(xiàng)的開(kāi)始,最終導(dǎo)致緩沖區(qū)溢出和潛在的RCE。
4. 利用思路
1. 利用條件
基本條件
- attacker需要獲取target的IPv6和MAC地址
觸發(fā)過(guò)程
- attacker需要搭配其他內(nèi)存泄漏或信息泄漏漏洞來(lái)實(shí)現(xiàn)RCE
- attacker需要想辦法繞過(guò)tcpip.sys的GS保護(hù)機(jī)制
2. 利用過(guò)程
attacker直接發(fā)送特制的ICMPv6路由廣播數(shù)據(jù)包給target:
[ Attacker ]
3. 攻擊向量
建立連接后,利用IPv6直接發(fā)送攻擊數(shù)據(jù)包即可。
5. 流量分析
因?yàn)樵撀┒粗苯幼叩腎Pv6,所以對(duì)于一些部署在IP層以上的防火墻方案就無(wú)法針對(duì)該漏洞進(jìn)行流量檢測(cè),但是具備IP層流量檢測(cè)的防火墻可以輕松檢測(cè)惡意流量:
在流量中可以明顯看出,第一個(gè)Option結(jié)構(gòu)的Address字段錯(cuò)誤識(shí)別計(jì)算了一個(gè)Recursive DNS Server的值:
第1個(gè)Recursive DNS Server的地址為0018-0027,后續(xù)的8個(gè)字節(jié)不應(yīng)該再進(jìn)行識(shí)別。選中第2個(gè)Recursive DNS Server時(shí)情況如下:
第2個(gè)Recursive DNS Server的地址為0028-0037。但是該16個(gè)字節(jié)中的后8個(gè)字節(jié)很明顯為下一個(gè)ICMPv6 Option結(jié)構(gòu)的內(nèi)容:
四、參考文獻(xiàn)
- https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16898
- https://tools.ietf.org/html/rfc8106
- https://www.mcafee.com/blogs/other-blogs/mcafee-labs/cve-2020-16898-bad-neighbor/













































