資安研究人員往往要耗費大量時間,才能挖掘出一個漏洞,而他們有時也會藉由替漏洞申請CVE編號來證實自己的能力,而今天開始將會用兩天的時間來介紹一個漏洞要符合哪些資格,才能申請到CVE編號。如同之前在Day 1提到的,對於MITRE來說,必須要符合8個條件才能夠有資格申請CVE編號,其中3個是判斷通報的弱點中包含幾個漏洞,有5個是判斷漏洞是否能夠發給CVE編號,今天就先來介紹前3項吧,別看3項比5項少,要處理這3個項目可以要花遠比後面5項好幾倍的時間呢。
這一項堪稱最複雜的一項,首先要先了解MITRE對一個錯誤 (Bug)的定義,前提當然是錯誤是一個程式邏輯的錯誤,而在這裏我們還不會考慮這個錯誤會不會造成安全風險,單純要驗證報告中的這段程式碼存在幾個錯誤。依現行規範,當修改一段程式碼只會修補一個錯誤時,我們會將其視為一個合格的錯誤;如果修改一段程式碼可以不能只修好一個錯誤,勢必會同時修補到其他的錯誤,那我們就必須把這幾個錯誤合併為一個錯誤來看;如果分不清楚多個錯誤是不是屬於同一個錯誤,則將其合併成一個錯誤來看,是不是覺得頭昏了呢?
大家想像一下,假設每個錯誤都是不同造型的發光燈泡,我現在要想辦法把這些燈泡都關掉,而牆上有可以關掉這些燈泡的開關,當我按下一個開關只會關掉其中一個燈泡的時候,可以將這個燈泡視為獨立錯誤,但如果有個大開關裡藏著一個小開關,我按下大開關想關掉其中一個燈泡,卻無法避免同時關掉小開關所連接的燈泡時,就必須將這兩個燈泡視為同一個錯誤。
以下面這段程式碼為例,裡面的兩個strcpy(str, long_input)因為沒有限制字串長度,可能會導致Buffer Overflow的錯誤。
if (strcmp(cmd, "show") == 0) {
strcpy(str, long_input);
process_show_command(str); }
elseif (strcmp(cmd, "clear") == 0) {
strcpy(str, long_input);
process_clear_command(str); }
在這種狀況下有兩種方式可以把這個錯誤修補,第一個是在if跟elseif裡面分別限制str的長度,第二個則是在if的前面加入一個預先判斷式,避免錯誤發生,但不論是哪種處理方式,兩個錯誤都是獨立被修補的,也就是說,MITRE並不在意你用多少的程式碼修補漏洞,他的精神是兩個錯誤是不是可以被獨立處理的。
如果以下面這段程式碼為例,裡面的strcpy(str, long_input)一樣因為沒有限制字串長度,可能會導致Buffer Overflow的錯誤。
strcpy(arg, long_input);
if (strcmp(cmd, "show") == 0) {
process_show_command(arg); }
elseif (strcmp(cmd, "clear") == 0) {
process_show_command(arg); }
在這種狀況下就只有一種解法,就是在呼叫stcpy前進行字串長度限制,而在這種狀況下,if跟elseif的錯誤都會同時被修補,所以只能將其算做一個錯誤。
透過這樣的方式,在CNT1中我們可以計算有資格進到下一項考驗的錯誤有幾個,但由於當一個研究人員把他挖掘到的漏洞提報給CNA (有權力發CVE編號的單位)時,研究人員通常並不會擁有有錯誤產品的程式碼,除非是開源產品,不然產品開發單位也不一定願意將程式碼提供研究人員,所以在這一項中可能都只能由產品開發商自行決定研究人員所提報的錯誤是否可合併或分割。
還記得我們在第一天講過還記得我們在第一天講過,CVE對於漏洞的定義為一存在於軟硬體元件運算邏輯(例如程式碼)中的弱點,當弱點被利用時,會導致資料的機密性、完整性或可用性產生負面影響,所以在這個步驟,我們必須確認通過CNT1的錯誤是會對安全性產生負面影響的,例如在CNT1中舉的Buffer Overflow例子,假設這個功能是用在一個手機計算機程式,這個錯誤可能只會造成計算結果錯誤,但並不會對安全性產生負面影響,這種狀況下就不能將這個錯誤是為漏洞;反之,如果這個功能是用在寫入資料庫功能,就有可能會造成資料庫錯誤,並進一步被攻擊者利用,對安全性造成負面影響,在這種狀況下就可以將錯誤是為漏洞。
但是要由誰來決定這個錯誤是不是漏洞呢?可以由CNA自己決定要相信提報錯誤的研究人員,或是驗證錯誤的廠商,還是靠自己決定。以部分對於修補漏洞沒什麼興趣的廠商來說,能少一件事是一件事,所以有可能會出現廠商不願意證實錯誤具有安全性風險的狀況,在這種狀況下,CNA可以選擇相信提報漏洞的研究人員,若研究人員的報告夠精確可以證明該錯誤是個漏洞,或是CNA自己發現該錯誤的確違反了廠商的安全政策(就算廠商不承認),都可以視為通過CNT2。
在這個階段中,必須確認產生錯誤的產品程式碼來源,如果來源是廠商自行撰寫,或是引用了共用程式庫,例如是一段從Stackoverflow上複製下來的一段程式碼,雖然可能很多人都複製到同樣的一段程式碼來用,但可以將漏洞是為屬於該產品的,而且每個用到這段程式碼的不同產品都可以算作是不同漏洞;如果程式碼是來自引用外部的函式庫,或是使用某一個協定造成的,則會把漏洞視為該外部函式庫或是協定的,例如寫程式時因為引用了PHP內建的某個函式導致產生漏洞,則這個漏洞會算在PHP頭上,而不是產品身上。但要注意的是,如果不是因為直接使用協定,而且因為自己寫程式來實作出協定而產生的漏洞,則要算在產品自己頭上。
通過了以上3項,我們可以確定錯誤數量、錯誤有沒有資格可以被稱作漏洞,以及漏洞是要算在誰的頭上,明天會繼續接紹接下來的5項條件,就敬請期待囉。
參考資料:
[1] https://cveproject.github.io/docs/cna/training_slides/index.html