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