![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM4ATN48CXkl2LcR3cvB3Lc12bj5SZr5WY1Fnbh5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
漏洞發現人:Philip Pettersson
漏洞編号:CVE-2016-8655
漏洞危害:高危,低權限使用者利用該漏洞可以在Linux系統上實作本地提權。
影響範圍:Linux核心(2011年4月19日發行)開始就受影響了,直到2016年11月30日修複。
漏洞描述
Philip Pettersson在Linux (net/packet/af_packet.c)發現條件競争漏洞,可以讓低權限的程序獲得核心代碼執行權限。
這個bug最早出現于2011年4月19号的代碼中,詳細請參考:
它于2016年11月30号被修複,詳細請參考:
漏洞細節
建立AF_PACKE套接字你需要CAP_NET_RAW在你的網絡命名空間 ,然而系統中非權限的程序在非權限的命名空間可以獲得這個能力(Ubuntu, Fedora等發行版),這個漏洞可以在容器内觸發,進而入侵整個主機核心。在android上,有 gid=3004/AID_NET_RAW的程序可以建立AF_PACKET套接字 (mediaserver),進而觸發這個漏洞。
問題出在inside packet_set_ring() 和 packet_setsockopt()函數中,我們可以看到當套接字使用PACKET_RX_RING選項時候,packet_set_ring()會調用setsockopt()函數。
如果套接字的版本是TPACKET_V3,一個 timer_list對象将會在init_prb_bdqc()調用時被 packet_set_ring()初始化。
switch (po->tp_version) {
case TPACKET_V3:
if (!tx_ring)
init_prb_bdqc(po, rb, pg_vec, req_u);
break;
default:
break;
}
函數的流程如下:
packet_set_ring()->init_prb_bdqc()->prb_setup_retire_blk_timer()->prb_init_blk_timer()->prb_init_blk_timer()->init_timer()
當套接字關閉,packet_set_ring()會再次被調用,如果packet的版本> TPACKET_V2,會釋放和删除先前初始化的定時器。
if (closing && (po->tp_version > TPACKET_V2)) {
if (!tx_ring)
prb_shutdown_retire_blk_timer(po, rb_queue);
}
當packet版本為TPACKET_V1時,init_prb_bdqc()将會在packet_setsockopt()後被執行,在packet_set_ring() 函數前傳回。
ring buffer被初始化後,可以嘗試拒絕改變套接字版本。但是這樣的校驗是不完整的。
case PACKET_VERSION:
{
...
if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
return -EBUSY;
在 packet_set_ring()中init_prb_bdqc() 和 swap(rb->pg_vec, pg_vec) 之間的調用有足夠的空間來競争這條代碼路徑
當套接字關閉,packet_set_ring()将不會删除定時器,是以這時套接字的版本為TPACKET_V1,timer_list 結構體描述定時器對象定位在内部的packet_sock結構體中,套接字将調用kfree()釋放。
我們可以在通過UAF利用定時器對象上對SLAB配置設定器實作不同的中毒攻擊(我發現add_key()是最可靠的),這最終會導緻當定時器過期核心跳到處理函數。
通過在packet_setsockopt()中使用lock_sock(sk)來修複這個bug,同時鎖定packet版本。
漏洞驗證
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM4ATN48CXkl2LcR3cvB3Lc12bj5SZr5WY1Fnbh5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM4ATN48CXkl2LcR3cvB3Lc12bj5SZr5WY1Fnbh5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM4ATN48CXkl2LcR3cvB3Lc12bj5SZr5WY1Fnbh5yd3d3Lc9CX6MHc0RHaiojIsJye.jpg)
POC
國内網盤位址:
修複方法
各linux發行版自行更新核心到最新版本。
相關連結