Windows DNS Server遠(yuǎn)程代碼執(zhí)行漏洞分析
- CNNVD編號(hào):未知
- 危害等級(jí): 高危
- CVE編號(hào):CVE-2020-1350
- 漏洞類型: 遠(yuǎn)程代碼執(zhí)行
- 威脅類型:遠(yuǎn)程
- 廠 商:未知
- 漏洞來(lái)源:深信服
- 發(fā)布時(shí)間:2021-01-06
- 更新時(shí)間:2021-01-13
漏洞簡(jiǎn)介
Microsoft Windows Server操作系統(tǒng)自帶了一個(gè)DNS server,Windows自Windows 2000后提供了一些DNS API給應(yīng)用程序開(kāi)發(fā)者,允許他們通過(guò)這些API使用一些DNS方法(例如創(chuàng)建DNS查詢,比較記錄,查找name等)。
一種最簡(jiǎn)單的用戶和DNS Server的交互過(guò)程如下圖所示:
DNS查詢和響應(yīng)均通過(guò)DNS消息進(jìn)行傳輸,消息的結(jié)構(gòu)如下所示:
+---------------------+
| Header |
+---------------------+
| Question / Zone | the question / zone for the name server
+---------------------+
| Answer / Prereq | RRs answering the question / prereq
+---------------------+
| Authority / Updates | RRs pointing toward an authority / updates
+---------------------+
| Additional | RRs holding additional information
+---------------------+
此外,DNS還包含Dynamic Update消息類型,在結(jié)構(gòu)上類似于query/response,但是在Dynamic Update消息中的section的名稱有一定變化,如上面結(jié)構(gòu)所示,Question稱為Zone,Answer稱為Prerequisites,Authority稱為Updates。
DNS Header部分的結(jié)構(gòu)如下所示:
Field | Length(Bits) | Description |
ID | 16 | 匹配query和response消息的ID |
QR | 1 | 指明為Query(QR=0)還是Response(QR=1)的flag標(biāo)志 |
OPCODE | 4 | 指明query的類型,0表示為標(biāo)準(zhǔn)類型,5表示為Dynamic Update |
AA | 1 | Authoritative Answer,表明answer是否來(lái)自于authority |
TC | 1 | Truncation,指明是否因?yàn)閭鬏斚拗七M(jìn)行truncate |
RD | 1 | Recursion Desired,指明resolver是否遞歸執(zhí)行query |
RA | 1 | Recurision Available,指明resolver是否遞歸處理query |
Z | 3 | 未使用 |
RCODE | 4 | 指明錯(cuò)誤狀態(tài),0表示沒(méi)有錯(cuò)誤 |
QDCOUNT | 16 | Question/Zone Section中的entity數(shù)量 |
ANCOUNT | 16 | Answer/Prereq Section中的entity數(shù)量 |
NSCOUNT | 16 | Authority/Updates Section中的entity數(shù)量 |
ARCOUNT | 16 | Additional Section中的entity數(shù)量 |
所有多字節(jié)數(shù)據(jù)均以大端序進(jìn)行傳輸,上面提到的各個(gè)section都包含不定數(shù)量的Resource Records(RR),這些RR指定了DNS 資源和entity的詳細(xì)信息。RR的結(jié)構(gòu)如下:Field | Length(bytes) | Description |
Name | var | Owner Name,該domain屬于的node |
Type | 2 | 資源記錄type碼 |
Class | 2 | 資源記錄class碼 |
TTL | 4 | 記錄緩存的秒數(shù) |
RDLENGTH | 2 | RDATA字段的長(zhǎng)度 |
RDATA | var | 記錄數(shù)據(jù),格式取決于type和class |
對(duì)于Zone section來(lái)說(shuō),包含如上格式的RR,但是省略TTL,RDLENGTH,RDATA。
Name字段編碼了0個(gè)或多個(gè)DNS標(biāo)簽,標(biāo)簽以空字符結(jié)尾。每個(gè)標(biāo)簽為一個(gè)1字節(jié)固定長(zhǎng)度的字節(jié)字符串。例如,一個(gè)域名為www.example.com,會(huì)切分成3個(gè)標(biāo)簽,www,example以及com,然后進(jìn)行編碼組合到一起\x03www\x07example\x03com\x00?;蛘?,不使用按照長(zhǎng)度編碼為字節(jié)字符串,而是一個(gè)標(biāo)簽包含一個(gè)2字節(jié)的指針,前2個(gè)最重要的位設(shè)置為1,其他位存儲(chǔ)從DNS Header部分的未壓縮標(biāo)簽出現(xiàn)的位置的偏移(字節(jié)數(shù)),例如Zone包含一個(gè)Name為\x03www\x07example\x03com\x00的RR,然后其他的RR可以使用2字節(jié)的指針\xc0\xc0指向該name,0xc0是距Zone RR的Name字段出現(xiàn)的DNS數(shù)據(jù)包起點(diǎn)的偏移。
Dynamic Update是可以遠(yuǎn)程更新DNS記錄的一種功能,該功能允許經(jīng)過(guò)授權(quán)的更新者區(qū)域中的權(quán)威名稱server上增加和刪除資源記錄。通常情況下,Dynamic Update使用SIG或者TSIG對(duì)更新進(jìn)行簽名。
漏洞公示
在Windows系統(tǒng)中,DNS Client和DNS Server通過(guò)兩個(gè)不同的模塊進(jìn)行實(shí)現(xiàn):
- DNS Client:dnsapi.dll,負(fù)責(zé)處理DNS 解析- DNS Server:dns.exe,負(fù)責(zé)響應(yīng)DNS查詢在dns.exe中,實(shí)現(xiàn)針對(duì)各種支持的響應(yīng)類型的解析函數(shù):
dns!RR_DispatchFunctionForType()通過(guò)RRWireReadTable來(lái)確定對(duì)應(yīng)的處理功能。RRWireReadTable中包含的支持的響應(yīng)類型如下:
對(duì)于SIG 查詢的響應(yīng)類型也在其中。而處理 SIG 查詢的響應(yīng)類型的函數(shù)為dns!SigWireRead(),其匯編代碼如下:
也就是在接收到包含SIG RRd的Dynamic Update查詢后,dns!SigWireRead()函數(shù)被調(diào)用來(lái)進(jìn)行RR解析,并存儲(chǔ)到一個(gè)堆緩沖區(qū)中。在調(diào)用DNS!RR_AllocateEx()函數(shù)進(jìn)行堆區(qū)分配之前,首先調(diào)用dns!Name_PacketNameToCountNameEx()函數(shù)統(tǒng)計(jì)Signer's Name的長(zhǎng)度,然后按照如下公式進(jìn)行計(jì)算需要分配的緩沖區(qū)的大?。?/section>bsize (buffer size) = Length of uncompressed Signer's Name + 0x14 + Length of Signature
上面公式的計(jì)算過(guò)程使用的均為16位寄存器,然后在RR_AllocateEx()函數(shù)中進(jìn)行擴(kuò)展:
如果最后bsize的計(jì)算結(jié)果大于0xFFFF(16位寄存器能表示的最大值),那么在傳入RR_AllocateEx()函數(shù)進(jìn)行內(nèi)存分配操作時(shí),就會(huì)分配一個(gè)很小的緩沖區(qū):
從代碼中可以看到,在進(jìn)行內(nèi)存分配時(shí),實(shí)際分配的內(nèi)存大小為bsize + 0x4a,而且在進(jìn)行copy操作時(shí),將SIG RR的Signature字段copy到了偏移為L(zhǎng)ength of uncompressed Signer's Name+0x4c處的緩沖區(qū)中,這主要是為了確保Signature可以被copy到緩沖區(qū)的末尾位置。
正常情況下,bsize的計(jì)算結(jié)果會(huì)比0xFFFF小,原因如下:- DNS通過(guò)TCP傳輸?shù)膒acket的最大數(shù)據(jù)量為0xFFFF- DNS的packet一定包含一個(gè)12字節(jié)的Header- 對(duì)于root zone來(lái)說(shuō),一個(gè)最小的Zone RR大小為5字節(jié)- Signer's Name字段前的SIG RR的長(zhǎng)度為18個(gè)字節(jié)
因此,在正常情況下,Signer's Name和Signature長(zhǎng)度的和一定小于0xFFFF - 12 - 5 - 18 = 0xFFDC,那么也就說(shuō)明bsize的長(zhǎng)度不會(huì)大于0xFFF0(0xFFDC + 0x14)。
但是,仍然有可能構(gòu)造一個(gè)惡意的Signer's Name來(lái)使得bsize的大小超過(guò)0xFFFF來(lái)造成溢出。因?yàn)镾IG RR的前18個(gè)字節(jié)在調(diào)用memcpy()函數(shù)之前都不會(huì)被處理,從而可以任意使用這些字節(jié)來(lái)存儲(chǔ)一個(gè)DNS name,而且,構(gòu)造的DNS name的最后2個(gè)字節(jié)可以指向Zone RR的Name字段。例如,Name的前18個(gè)字節(jié)如下:\x0FAAAAAAAAAAAAAAA\xc0\x0c
使用嵌套指針在SIG RR的18個(gè)字節(jié)中構(gòu)造一個(gè)Name,如下所示:
Label1 = <Label1_Length> <Label1_Name> \xc0\x0c
Crafted_Name = <Label2_Length> <Label1> <Pointer1>
Pointer1指向Label1_Length處的字節(jié)。請(qǐng)注意,Crafted_Name包含一個(gè)指向Label1的指針Pointer1,Label1本身包含在Crafted_Name中。由于Label1的指向\xc0\x0c后綴(即Zone RR的Name字段),因此不會(huì)導(dǎo)致無(wú)限遞歸,而是通過(guò)添加作為名稱子集的后綴來(lái)延長(zhǎng)Crafted_Name 。以一個(gè)例子來(lái)說(shuō)明該種方案:Label1 = \x0cAAAAAAAAAAAA\xc0\x0c
Crafted_Name = \x11\x0cAAAAAAAAAAAA\xc0\x0c\xc0XX
其中,Zone假設(shè)為example.com,XX指向Label1。Crafted_Name就變成\x0CAAAAAAAAAAAA\xC0\x0C.AAAAAAAAAAAA.example.com,長(zhǎng)度由原來(lái)的18字節(jié)變?yōu)?0字節(jié)。通過(guò)嵌套指針,使得長(zhǎng)度變?yōu)榱嗽瓉?lái)的2倍。如果Signer's Name指向Crafted_Name,那么就可能實(shí)現(xiàn)bsize大于0xFFFF,從而觸發(fā)漏洞。
補(bǔ)丁
1、微軟官方補(bǔ)丁
微軟官方目前已發(fā)布針對(duì)此漏洞的安全更新補(bǔ)丁,千里目實(shí)驗(yàn)室建議廣大用戶及時(shí)確認(rèn)所用Windows版本,并下載對(duì)應(yīng)版本安全補(bǔ)丁進(jìn)行更新:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1350
微軟官方對(duì)于無(wú)法及時(shí)安裝安全更新的用戶提供了臨時(shí)的緩解措施:
通過(guò)注冊(cè)表編輯器,限制tcp包的長(zhǎng)度
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters DWORD = TcpReceivePacketSize
Value = 0xFF00
注意:需要重新啟動(dòng)DNS服務(wù)才能生效。
移除此臨時(shí)緩解措施:
管理員可以移除值 TcpReceivePacketSize 及其數(shù)據(jù),使注冊(cè)表項(xiàng) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters 下的所有其他內(nèi)容恢復(fù)原來(lái)的狀態(tài)。
【深信服下一代防火墻】
可輕松防御此漏洞,建議部署深信服下一代防火墻的用戶更新至最新的安全防護(hù)規(guī)則,可輕松抵御此高危風(fēng)險(xiǎn)。【深信服EDR】
深信服EDR已完成漏洞規(guī)則庫(kù)更新,支持該漏洞的檢測(cè)及補(bǔ)丁分發(fā)。EDR3.2.10及以上版本需要升級(jí)相應(yīng)的SP包,更新漏洞補(bǔ)丁規(guī)則庫(kù)版本到20200722103111及以上版本,即可檢測(cè)漏洞并分發(fā)補(bǔ)丁進(jìn)行漏洞修復(fù)。聯(lián)網(wǎng)用戶可直接在線更新,離線升級(jí)包及漏洞補(bǔ)丁規(guī)則庫(kù)已上傳至深信服社區(qū),有需要的用戶請(qǐng)到深信服社區(qū)下載。【深信服云盾】
已第一時(shí)間從云端自動(dòng)更新防護(hù)規(guī)則,云盾用戶無(wú)需操作,即可輕松、快速防御此高危風(fēng)險(xiǎn)。【深信服安全感知平臺(tái)】
可檢測(cè)利用該漏洞的攻擊,實(shí)時(shí)告警,并可聯(lián)動(dòng)【深信服下一代防火墻等產(chǎn)品】實(shí)現(xiàn)對(duì)攻擊者ip的封堵。【深信服安全運(yùn)營(yíng)服務(wù)】
深信服云端安全專家提供7*24小時(shí)持續(xù)的安全運(yùn)營(yíng)服務(wù)。在漏洞爆發(fā)之初,對(duì)存在漏洞的用戶,檢查并更新了客戶防護(hù)設(shè)備的策略,確保客戶防護(hù)設(shè)備可以防御此漏洞風(fēng)險(xiǎn)。https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1350