中年DNS Server远程代码执行漏洞分析-SIGRed( 五 )

dns.exe中满足这三个条件的唯一函数是NsecWireRead 。 让我们检查一下从函数反编译中得到的代码片段:
RESOURCE_RECORD* NsecWireRead(PARSED_WIRE_RECORD *pParsedWireRecord, DNS_PACKET *pPacket, BYTE *pRecordData, WORD wRecordDataLength) { DNS_RESOURCE_RECORD *pResourceRecord unsigned BYTE *pCurrentPos unsigned int dwRemainingDataLength unsigned int dwBytesRead unsigned int dwAllocationSize DNS_COUNT_NAME countName pResourceRecord = NULL pCurrentPos = Name_PacketNameToCountNameEx(&ampcountName, pPacket, pRecordData, pRecordData + wRecordDataLength, 0) if (pCurrentPos) { if (pCurrentPos &gt= pRecordData // &lt-- Check #1 - Bounds check &amp&amp pCurrentPos - pRecordData &lt= 0xFFFFFFFF // &lt-- Check #2 - Same bounds check (?) &amp&amp wRecordDataLength &gt= (unsigned int)(pCurrentPos - pRecordData)) // &lt-- Check #3 - Bounds check { dwRemainingDataLength = wRecordDataLength - (pCurrentPos - pRecordData) dwBytesRead = countName.bNameLength + 2 // size := len(countName) + 2 + len(payload) dwAllocationSize = dwBytesRead + dwRemainingDataLength if (dwBytesRead + dwRemainingDataLength &gt= dwBytesRead // &lt-- Check #4 - Integer Overflow check (32 bits) &amp&amp dwAllocationSize &lt= 0xFFFF) // &lt-- Check #5 - Integer Overflow check (16 bits) { pResourceRecord = RR_AllocateEx(dwAllocationSize, 0, 0) if (pResourceRecord) { Name_CopyCountName(&amppResourceRecord-&gtdata, &ampcountName) memcpy(&amppResourceRecord-&gtdata + pResourceRecord-&gtdata-&gtbOffset + 2, pCurrentPos, dwRemainingDataLength) } } } } return pResourceRecord }
如您所见 , 这个函数包含许多安全检查 。 其中一项是16位溢出检查 , 它可以防止我们在该函数中的漏洞变体 。 我们还想指出 , 这个函数比dns中的函数有更多的安全检查 。 这让我们怀疑这个漏洞是否已经被注意到和修复 , 但只是在那个特定的函数 。
如上所述 , Microsoft在两个不同的模块中实现了DNS客户端和DNS服务器 。 虽然我们的漏洞确实存在于DNS服务器中 , 但我们想看看它是否也存在于DNS客户端中 。
中年DNS Server远程代码执行漏洞分析-SIGRed
本文插图
看来 , 不像dns.exe!SigWireRead, dnsapi.dll!Sig_RecordRead 它确实验证了Sig_RecordRead+D0传递给dnsapi.dll!Dns_AllocateRecordEx的值小于0xFFFF字节 , 从而防止了溢出 。
这个漏洞在dnsapi.dll中不存在 。 并且两个模块之间的命名约定不同 , 这使我们相信Microsoft管理DNS服务器和DNS客户端的两个完全不同的代码库 , 并且不会同步它们之间的bug补丁 。
Exploitation Plan
根据Microsoft的要求 , 我们决定保留有关漏洞利用原语的信息 , 以便给用户足够的时间来修补他们的DNS服务器 。 相反 , 我们将讨论应用于Windows Server 2012R2的利用方案 。 然而 , 我们相信这个方案也应该适用于其他版本的Windows Server 。
该dns.exe二进制文件是用控制流保护(CFG)编译的 , 这意味着在内存中重写函数指针的传统方法不足以利用这个漏洞 。 如果这个二进制文件不是用CFG编译的 , 利用这个漏洞将是非常简单的 , 因为很早就我们遇到了以下崩溃:
中年DNS Server远程代码执行漏洞分析-SIGRed
本文插图


推荐阅读