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