安全動態(tài)

Apple syslogd提權(quán)漏洞,影響眾多iOS、OSX版本(CVE-2016-1722)

來源:聚銘網(wǎng)絡(luò)    發(fā)布時間:2016-02-03    瀏覽次數(shù):
 

信息來源:紅黑聯(lián)盟  


這次iOS 9.2.1最新更新中蘋果修復(fù)了一個代碼執(zhí)行漏洞,是由Zimperium zLabs的兩位研究員Nikias Bassen和Joshua J. Drake在syslogd里的發(fā)現(xiàn)的。

在這篇文章里,我們將分享如何確定該漏洞以及漏洞背后可以讓攻擊者以Root權(quán)限在6.0到9.2版本的iOS設(shè)備上執(zhí)行代碼的技術(shù)細節(jié)。

起初,我們在檢查過程中發(fā)現(xiàn)模糊測試器跳過了syslog的代碼,但一當(dāng)我們調(diào)查測試崩潰的問題時,它就對syslogd的開源部分進行了全面審查。因此我們才從中確定了syslogd代碼的bug并確實成功地觸發(fā)了崩潰。然后我們通知蘋果公司并與其安全團隊共同合作來解決問題。蘋果公司迅速作出反應(yīng)。 完整的安全公告是如下:

?
1
iOS / OS X的syslogd堆緩沖區(qū)溢出

受影響的組件

?
1
/usr/sbin/syslogd

受影響的平臺和版本:

?
1
2
iOS 6.0 到 9.2
OS X 10.9 到 10.11.2

供應(yīng)商

?
1
Apple, Inc.

CVE:

?
1
CVE-2016-1722

最新公開的源代碼版本:

?
1
syslog-267 (OS X 10.10.5)

披露時間

?
1
2
3
錯誤發(fā)現(xiàn)并證實:2015年10月26日
通知:2015年11月25日
漏洞修補:2016年1月14日與iOS 9.2.1

概要

內(nèi)存重新分配過程中大小計算錯誤導(dǎo)致在建立多個客戶端連接的時候syslogd的堆緩沖區(qū)溢出。

影響

本地權(quán)限提升,遠程代碼執(zhí)行(WiFi下信任的設(shè)備)或DoS攻擊

介紹

Syslogd進程是通過iOS的root權(quán)限運行的。我們發(fā)現(xiàn)一個堆溢出漏洞會導(dǎo)致內(nèi)存受到破壞,并且在某些情況下可能會導(dǎo)致任意代碼的執(zhí)行。超出堆緩沖區(qū)邊界的數(shù)據(jù)會被文件描述符的值覆蓋。而且有一些操作也會允許對寫入值的控制。不過想要利用這個漏洞可不簡單。

背景

在設(shè)備上運行的軟件可以以USB接口的方式或者通過將設(shè)備設(shè)置在相同WiFi網(wǎng)絡(luò)上遠程連接到syslog中繼服務(wù)(com.apple.syslog_relay)來訪問該設(shè)備的系統(tǒng)日志(syslog)。不過前提是無論使用哪個媒體,設(shè)備必須被配置為信任機才可以連接到服務(wù)。也就是說,必須要先“配對”。

由于密碼鎖定的設(shè)備只能在解鎖的情況下才與一臺電腦配對,那么在不受信任的設(shè)備上利用這個漏洞就需要密碼。而且設(shè)備上運行的第三方應(yīng)用程序也沒有辦法直接與syslogd連接。

細節(jié)

這個漏洞的根本原因在于源文件syslogd.tproj / dbserver.c的add_lockdown_session函數(shù)中。在執(zhí)行這個函數(shù)的時候,程序員需要給數(shù)組重新分配內(nèi)存大小。下圖是代碼有問題的一部分:


第170行是問題的根源。傳遞給reallocf函數(shù)的大小算錯了。這個代碼應(yīng)該是為每一個新的連接生成四個字節(jié)的時域文件描述符數(shù)組,但從運算符優(yōu)先級規(guī)則角度看計算出錯了。代碼應(yīng)改為:


原代碼里是把整型數(shù)據(jù)字節(jié)數(shù)增加到時域數(shù)量,而上面代碼行是在時域數(shù)量后先加了1,然后再乘以sizeof(int)。這樣意義就不一樣了。

由于新版iOS和OS X的源代碼還無法獲得。我們需要通過二進制文件的反匯編來證明出現(xiàn)在最新版本中的這個問題。而且隨著運算符優(yōu)先級規(guī)則的應(yīng)用和代碼在操作上進行的優(yōu)化,反匯編讓問題變得更加顯而易見了。下圖是iOS 9.0.2的syslogd二進制反匯編:


同樣的問題也在OS X的syslogd二進制文件里和iOS 9.1里發(fā)現(xiàn),iOS 9.1甚至不需要多次連接到com.apple.syslog_relay服務(wù)來檢查二進制文件就可以確認了。只要堆內(nèi)重要的數(shù)據(jù)被破壞了,syslogd就會崩潰。下圖是OS X 10.11.1的syslogd二進制反匯編:


請注意一下編譯器在這兩個版本中如何將“1 *sizeof(int)”簡化為“sizeof(int)”,這使漏洞更加明顯。

當(dāng)一個新的客戶端連接時,函數(shù)被第一次調(diào)用,執(zhí)行時這個函數(shù)給初始緩沖器分配了第一個用于連接的文件描述符。因為sizeof(int)的值一直是定值4,第一次 global.lockdown_session_count值為0,計算出的大小是正確的4個字節(jié)。但是當(dāng)?shù)诙€新的客戶端連接時,global.lockdown_session_count值變成了1,緩沖區(qū)大小就會被錯誤地計算為5個字節(jié)。以此類推,第三個連接的大小是6個字節(jié)。

如果開發(fā)商把新的連接的文件描述符存儲在global.lockdown_session_fds數(shù)組里,隨著字節(jié)數(shù)越來越大就會發(fā)生實際的堆溢出。下圖是syslogd中的syslogd.tproj / dbserver.c源文件代碼摘錄:


第179行的代碼,同時也是上面反匯編的最后一行,表示了代碼在沒有足夠內(nèi)存分配的緩沖器里溢出寫入4個字節(jié)。由于內(nèi)存分配通常會四舍五入為8個字節(jié),所以建立兩個連接不會破壞內(nèi)存。而創(chuàng)建第三個連接后,文件描述符就會寫出界然后可能導(dǎo)致堆內(nèi)存的損壞。


當(dāng)然,有時內(nèi)存損壞發(fā)生可能需要不止三個連接才能使syslogd崩潰。但是,這取決于堆塊后的數(shù)據(jù)在利用后是否或如何被破壞。在我們的測試中syslogd中止執(zhí)行是因為remove_lockdown_session函數(shù)中堆損壞。


 
 

上一篇:Chrome惡意擴展程序可監(jiān)控用戶上網(wǎng)行為

下一篇:泡沫退去 看中國大數(shù)據(jù)四大如何鎖定商業(yè)模式