上圖是我從《編譯系統透視:圖解編譯原理》裡面扣出來的,基本包括編譯原理的各個主要方面,從中可以對編譯原理有個大體認識。
專業點來講,編譯原理就是介紹編譯程式構造的一般原理和基本方法,內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、程式碼優化和目標程式碼生成。
之前在知乎上看到過一份視頻,講的是程式師編寫的程式碼如何被電腦識別,並在CPU上運行,如果你未曾學習編譯原理,推薦觀看一下(視頻時長11:34)。
污點分析是指將程式從外部獲取的數據標記為污點,然後觀察污點在程式執行過程中的傳播,從而得到程式中的信息流等資訊,裡面涉及編譯原理中的詞法語法分析會多一些,主要被應用於惡意軟件分析、攻擊程式碼檢測等軟件安全性分析研究中。
記得剛參加工作那會,經常到網上蒐索安全論文,發現很多資訊安全專業的學生大多有做過一份關於“污點分析”的畢業設計,你現在上CNKI就可以蒐索到很多,尤以碩士畢業論文居多。
當時我幾乎翻遍網上所有能找到的“污點分析”論文,最後我得出幾點結論:
- 不求效果,但求理論高深。之前搞flash xss檢測,花了幾天時間用一堆grep實現的檢測工具,挖不了不到大廠的漏洞,包括淘寶、京東這些電商;但也有同學花幾個月搞flashactionscript污點分析,雖然有點作用,但從工作效率和結果看,有時高深的理論不見得適合工業界,雖然我的幾行grep沒法拿來寫論文。
不求效果,但求理論高深。之前搞flash xss檢測,花了幾天時間用一堆grep實現的檢測工具,挖不了不到大廠的漏洞,包括淘寶、京東這些電商;但也有同學花幾個月搞flashactionscript污點分析,雖然有點作用,但從工作效率和結果看,有時高深的理論不見得適合工業界,雖然我的幾行grep沒法拿來寫論文。
- 千篇一律,天下文章一大抄。下載了一堆同主題方向的論文,發現有的內容改都沒改,互相亂抄。
千篇一律,天下文章一大抄。下載了一堆同主題方向的論文,發現有的內容改都沒改,互相亂抄。
- 以漏洞挖掘的主題居多,但最後總要以挖洞效果結尾,有0day自然最好,沒0day就找幾個歷史漏洞重現下(很多可能是特例化處理的),沒歷史漏洞就對比幾個主流開源的挖洞工具,對比效率、性能等等,最挫的就是連效果都沒有就收尾了。
以漏洞挖掘的主題居多,但最後總要以挖洞效果結尾,有0day自然最好,沒0day就找幾個歷史漏洞重現下(很多可能是特例化處理的),沒歷史漏洞就對比幾個主流開源的挖洞工具,對比效率、性能等等,最挫的就是連效果都沒有就收尾了。
有過此般經歷後,我已很少再去翻國內的安全論文了,學術論文可能還是以翻閱國外的為主。
污點分析科技最早是在1976被提出的,2005年左右開始,污點分析應用於二進位漏洞挖掘的研究火了好多年,其實科技已經相對成熟。
確實有一些人通過污點分析挖掘到不少有價值的主流軟件漏洞,但這項科技要落地為一款安全產品還是有很多問題的。
首要問題就是誤報率,之前有同學開發出基於污點分析的源碼稽核工具,每次外部報告漏洞的時候,複盤時總說能檢測出來,只是沒人工跟進。但是,檢測出來的有成千上萬條告警,需要消耗大量人力去排查這又有什麼價值呢,本質上,還是沒發現嘛!
這也算是安全運營的問題,深以為,凡是能檢測到,但無法人工或自動跟進推動問題解决的,都是徒勞的。
相信有很多公司都有出過污點分析的安全稽核工具,收費的或者開源的,國內的此類安全產品很多最後都不了了之,所以說成熟的科技不等於成熟的產品。
國外比較著名的商業源碼稽核工具就是Coverity和Fortify SCA,算做得最好的業界同款產品,但用過的人都知道,檢測出來的問題,還是需要投入很多人工成本的。
搞逆向的同學都知道IDA、JEB這些著名的逆向工具,平時在無源碼的情况下,我們直接通過它們來分析程式邏輯,無需知曉其中涉及各類反編譯科技。
反編譯算是編譯的逆過程,即將可執行程式轉換成程式源碼的過程,如果是轉換成組合語言,我們通常稱為反彙編;如果是其它語言的(比如C、Java、C#等等),我們統稱為反編譯。
不同語言的編譯過程還不一樣,比如Java是通過JVM虛擬機器將位元組碼轉換成CPU認識的指令,而C是直接由編譯器轉換機器碼供CPU執行的,囙此它們的反編譯過程也不一樣。
所以如果不懂編譯原理,又如何開發反編譯工具呢?
有了反編譯,自然就有了防反編譯的工具,囙此造就了各種加殼工具的出現。
未知攻,焉知防。要開發加固工具,就需要知道反編譯原理,要知道反編譯原理,又需要知道編譯原理。
編譯原理<--->反編譯原理<--->加固原理
搞檔案Fuzzing,我們可以在樣本(收集、篩選、精簡)和Fuzzer(策略、方向等)上面下功夫,甚至簡單地暴力fuzzing檔案都可以挖到漏洞。
但對於JavaScript、CSS、Flash ActionScript這些腳本呢,直接簡單地暴力變異檔案根本無法進入正常的解析,做的大多是無用功。
囙此我們需要一個能够準確生成程式碼的語法生成器,再用它生成fuzzing樣本,這裡主要涉及編譯原理中的語法分析。這方面有著名的開源工具funfuzz(https://github.com/MozillaSecurity/funfuzz)、domato(https://github.com/google/domato),下圖就domato生成js程式碼的語法範本片段:
除此之外,通過對clang/gcc等開源的編譯工具對目標源碼進行插樁,以幫助監控fuzz樣本的程式碼覆蓋率,迴響給fuzzer作改進,以進一步提高程式碼覆蓋率,這塊叫“驅動迴響(feedback-driven),比如著名工具就是afl、libfuzzer、honggfuzz,以後有機會可以專篇講解此科技。
還有通過編譯器新增防漏洞利用的機制,比如GS、CFG等安全機制,在對抗漏洞攻擊上也起到了不小的作用。
所以通過研究llvm、gcc等編譯項目,對漏洞攻防領域也是有一些可作為的地方。
編譯原理在逆向工程、漏洞攻防、軟體發展等諸多領域有所應用,有時就看你怎麼使用,也並不是每個人在安全工作領域中有機會運用到,但技多不壓身,不妨多儲備點知識,以免到了“書到用時方恨少”的地步。