CVE-2016-7912 分析報告
CVE-2016-7912
背景介紹
在內核USB驅動中,進行異步讀取或寫入時,調用ki_complete(),會提前釋放kiocb結構體,從而造成UAF漏洞,但經過分析,發現無法利用此漏洞進行攻擊。
漏洞影響
1.影響版本鏈接: https://www.securityfocus.com/bid/94197
漏洞詳情
以4.5.2版本內核為例進行分析
相關結構體如下:
struct aio_kiocb { struct kiocb common; struct kioctx *ki_ctx; kiocb_cancel_fn *ki_cancel; struct iocb __user *ki_user_iocb; /* user‘s aiocb */ __u64 ki_user_data; /* user‘s data for completion */ struct list_head ki_list; /* the aio core uses this * for cancellation */ /* * If the aio_resfd field of the userspace iocb is not zero, * this is the underlying eventfd context to deliver events to. */ struct eventfd_ctx *ki_eventfd; }; struct kiocb { struct file *ki_filp; loff_t ki_pos; void (*ki_complete)(struct kiocb *iocb, long ret, long ret2); void *private; int ki_flags; };
漏洞代碼如下:
/* /drivers/usb/gadget/function/f_fs.c/ */ static void ffs_user_copy_worker(struct work_struct *work) { struct ffs_io_data *io_data = container_of(work, struct ffs_io_data, work); int ret = io_data->req->status ? io_data->req->status : io_data->req->actual; if (io_data->read && ret > 0) { use_mm(io_data->mm); ret = copy_to_iter(io_data->buf, ret, &io_data->data); if (iov_iter_count(&io_data->data)) ret = -EFAULT; unuse_mm(io_data->mm); } io_data->kiocb->ki_complete(io_data->kiocb, ret, ret);// (1) if (io_data->ffs->ffs_eventfd && !(io_data->kiocb->ki_flags & IOCB_EVENTFD)) eventfd_signal(io_data->ffs->ffs_eventfd, 1); usb_ep_free_request(io_data->ep, io_data->req); io_data->kiocb->private = NULL;// (2) if (io_data->read) kfree(io_data->to_free); kfree(io_data->buf); kfree(io_data); }
其中在(1)處調用函數為:static void aio_complete(struct kiocb *kiocb, long res, long res2),其實現大體如下(忽略掉無關代碼):
static void aio_complete(struct kiocb *kiocb, long res, long res2)
{
struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, common);//(3)
//無關代碼省略
kiocb_free(iocb);//(4)
//無關代碼省略
}
可以看出,在(4)處,釋放掉了kiocb結構,而在(2)處,又對其進行寫操作.造成UAF漏洞.
但是我們不能通過提前布局釋放掉的kiocb結構,進行利用。因為在這之後,不能通過其更改CPU的執行路徑,進而發起攻擊。也無法通過其進行任意內存讀寫。所以無法進行漏洞利用。但是可以利用條件競爭,破壞下一個申請該內存的結構,造成DOS
調試環境搭建
環境搭建參考:http://blog.nsfocus.net/gdb-kgdb-debug-application
目標機上通過: modprobe usb_f_fs,加載相應模塊.然後通過VMware虛擬機的USB功能,插入USB設備.
此時通過 cat /proc/modules | grep usb_f_fs 獲得對應模塊地址
獲得地址後,可以通過客戶機下斷點。
然後在目標機上編寫usb 異步寫程序,使目標機進入ffs_user_copy_worker函數,進行跟蹤與調試
修復建議
建議所有受影響用戶,及時進行安全更新,可選方式如下:
1、相關Linux發行版已經提供了安全更新,請通過 yum 或 apt-get 的形式進行安全更新。
2、自定義內核的用戶,請自行下載對應源碼補丁進行安全更新。 補丁鏈接:
建議所有受影響用戶,及時進行安全更新,可選方式如下:
1、相關Linux發行版已經提供了安全更新,請通過 yum 或 apt-get 的形式進行安全更新。
2、自定義內核的用戶,請自行下載對應源碼補丁進行安全更新。 補丁鏈接:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=38740a5b87d53ceb89eb2c970150f6e94e00373a
參考文檔
- https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/?id=38740a5b87d53ceb89eb2c970150f6e94e00373a
- http://appscan.360.cn/blog/?p=171
- https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-7912
CVE-2016-7912 分析報告