SentinelLab研究人員發(fā)現(xiàn)Linux Kernel TIPC(Transparent Inter Process Communication,透明進程間通信)模塊中的一個安全漏洞,攻擊者利用該漏洞可以在本地或遠程區(qū)塊下在kernel內(nèi)執(zhí)行任意代碼,并完全控制有漏洞的機器。
Linux TIPC協(xié)議
TIPC協(xié)議是允許集群中節(jié)點在存在大量節(jié)點容錯的情況下進行通信的協(xié)議。該協(xié)議在Linux kernel模塊中實現(xiàn),并包含在大多數(shù)Linux發(fā)行版中。當用戶加載時,TIPC可以用作socket并可以使用netlink在接口上進行配置。TIPC可以配置為在Ethernet或UDP協(xié)議之上運行。但是低權限的用戶是無法創(chuàng)建Ethernet幀,因此使用UDP更容易實現(xiàn)本地漏洞利用。
雖然TIPC是在這些協(xié)議之上運行的,但有獨立的地址方案,節(jié)點可以選擇自己的地址。TIPC協(xié)議以對用戶透明的方式工作。所有的消息構造和分析都是在kernel中進行的。每個TIPC消息都有相同的通用header格式和消息特定的header。
對該漏洞來說,通用header最重要的部分是Header Size和message size。TIPC消息header如下所示:
TIPC消息header
這兩個size大小是由tipc_msg_validate函數(shù)來進行驗證的:
TIPC漏洞
2020年9月引入了一個新的用戶消息類型——MSG_CRYPTO,該消息類型允許節(jié)點發(fā)送加密的秘鑰。該消息結構如下所示:
struct tipc_aead_key {
char alg_name[TIPC_AEAD_ALG_NAME];
unsigned int keylen; /* in bytes */
char key[];
};
其中 TIPC_AEAD_ALG_NAME是32位的宏。消息接收后,TIPC kernel模塊需要復制該信息到該節(jié)點來存儲:
/* Allocate memory for the key */
skey = kmalloc(size, GFP_ATOMIC);
/* … */
/* Copy key from msg data */
skey->keylen = ntohl(*((__be32 *)(data + TIPC_AEAD_ALG_NAME)));
memcpy(skey->alg_name, data, TIPC_AEAD_ALG_NAME);
memcpy(skey->key, data + TIPC_AEAD_ALG_NAME + sizeof(__be32),
skey->keylen);
用來分配的size大小與message payload的size大小是相同的。密鑰算法和密鑰本身也都會被復制。
從上面的代碼可以看出,Header Size和message size大小都會與真實的包大小來對比驗證有效性。如果這兩個值都在真實包大小的范圍內(nèi),MSG_CRYPTO 消息的keylen或密鑰算法本身都不會再去檢查message大小。也就是說,攻擊者可以創(chuàng)建一個size大小比較小的包來分配堆內(nèi)存,然后用keylen屬性中的任意大小來在該位置的邊界外進行寫操作:
可以觸發(fā)該漏洞的MSG_CRYPTO消息示例
漏洞利用
該漏洞可以在本地或遠程利用。由于對kernel堆中分配的對象的控制更多,因此本地利用更加容易一些。如下所示,攻擊者可以創(chuàng)建一個20字節(jié)的包,并設置message size為10字節(jié),并繞過檢查:
目前補丁也已經(jīng)發(fā)布,完整技術細節(jié)參見:
https://www.sentinelone.com/labs/tipc-remote-linux-kernel-heap-overflow-allows-arbitrary-code-execution/