Linux漏洞分析入門筆記-CVE-2015-0235
Ubuntu 12.04 32位
ida 7.0
0x00:漏洞描述
1.glibc的__nss_hostname_digits_dots存在緩衝區溢位漏洞,導致使用gethostbyname系列函式的某些軟體存在程式碼執行或者資訊洩露的安全風險。
通過gethostbyname()函式或gethostbyname2()函式,將可能產生一個堆上的緩衝區溢位。經由gethostbyname_r()或gethostbyname2_r(),則會觸發呼叫者提供的緩衝區溢位, 漏洞產生時至多sizeof(char* )個位元組可被覆蓋(因為char*指標的大小,即32位系統上為4個位元組,64位系統為8個位元組)。
0x01:漏洞分析
1.先靜態分析glibc原始碼中的__nss_hostname_digits_dots函式流程,如圖1所示。
圖1
圖1程式碼大致流程就是在__nss_hostname_digits_dots中,計算了size_needed,當size_needed > buff_size時,會呼叫realloc重新申請size_needed的空間。
圖2
圖2程式碼流程在計算size_need時,少加了一個sizeof(*h_alias_ptr),少算了4個位元組,所以當name全為數字或者.號時,會將name拷貝到buff的hostname,造成一個指標大小位元組的堆溢位。
所以要觸發成功需要滿足的條件為,size_need足夠大,讓其呼叫realloc重新分配。name全為數字或者.號。
2.選擇一個受漏洞影響的程式clockdiff來除錯分析,在IDA中對__nss_hostname_digits_dots下好斷點,如圖3所示:
圖3
F9執行,第一次斷下無用不是處理我們自己輸入的引數,直接跳過。第二次斷下,發現gethostbyname的引數為我們輸入的引數。Gethostbyname中呼叫__nss_hostname_digits_dots,其中緩衝區的大小預設為0x400。在呼叫realloc處下斷點,此時buffer_size= 0x41B,剛好是輸入引數的長度,因為size_need大於buffer_size所以須要重新分配空間。
圖4
通過上面的判斷與計算空間大小後執行到stcpy處(溢位點),通過前面空間的計算,加上字串結尾的空位元組,剛好溢位了一個指標位元組。
0x02:總結
1.產生漏洞的條件是當gethostbyname()函靈敏被呼叫時且滿足下面兩個條件。
a.size_need足夠大,讓其呼叫realloc重新分配。
b.name全為數字或者.號