2021看雪SDC議題回顧 | SaTC:一種全新的物聯網設備漏洞自動化挖掘方法

https://zhuanlan.zhihu.com/p/431335767

隨着物聯網技術的日新月異,未來物聯網的應用將越來越廣泛,但它同樣也會帶來大量安全漏洞。而當下IoT漏洞挖掘技術尚未完全成熟,許多人的信息安全意識不夠強,技術革新面臨着巨大的安全隱患。

來自上海交通大學的陳力波老師所提出的SaTC:一種全新IoT漏洞自動化挖掘方法,相應的學術論文已發表在國際安全頂會 USENIX Security 2021 上,並經歷了充分的實際數據校驗,在6個知名廠商的39款設備中找到了33個漏洞。實際應用效果突出,對物聯網安全領域具有極爲重要的意義。

 

下面就讓我們來回顧2021看雪第五屆安全開發者峯會《SaTC:一種全新的物聯網設備漏洞自動化挖掘方法》此議題的精彩內容。

 

 

演講嘉賓

 

【陳力波-上海交大網安學院創新實踐教研室副主任】

 

陳力波:上海交通大學網絡空間安全學院創新實踐教研室副主任

畢業於清華大學NISL實驗室,是著名安全戰隊“Blue-Lotus”藍蓮花的初創成員,具備多年網絡安全攻防經驗。主要擅長漏洞挖掘和利用、滲透測試,在IoT、區塊鏈等領域開展安全前沿技術研究。

 

 

演講內容

 

以下爲速記全文:

 

各位嘉賓大家下午好,我是來自上海交通大學網絡安全學院的陳力波,我今天給大家介紹一下我們最近的一個工作,發表在USENIX Security2020上面,是一個關於物聯網設備漏洞自動化挖掘的方法。

 

我們都知道物聯網現在在我們的日常生活中已經非常的普及和應用,它在智能家居、手機移動端,還有車聯網、工業物聯網等場景中。據統計,到2020年爲止的話,有580億的終端在用,我們可以看到它在我們生活中的各個角落裏面都廣泛的部署着各種的物聯網終端設備。同時我們通過公開的研究報道,可以發現其實大量的IoT設備存在着中高危的安全漏洞,給互聯網帶來了非常大的安全威脅。

 

主要有以下這麼幾點:第一個是IoT終端的數量非常巨大,第二個是大部分缺乏安全防護,還有很多終端連接互聯網,所以很有可能會成爲一個互聯網上面的殭屍的節點。

 

 

我們可以看到像Mirai這種影響非常廣泛的殭屍網絡,對美國東部DNS服務照成大面積癱瘓的一個攻擊,包括我們右邊這個圖的話是 TCP/IP協議棧這樣的一個通用漏洞,所以整個來說IoT它這種碎片化的一個生態,再加上現在這種迭代開發,所以很多代碼其實是高度的複用,有些漏洞的影響面會非常大。

然後其中無線的路由器和網絡設備,就類似攝像頭這些遭受的攻擊會相對來說比較多一點,主要是由於它開放的服務比較多,像web服務、DNS還有UPS這些服務。還有一點就是它大量的連接在互聯網上。

 

 

然後我們就在想如何去檢測這些設備中的安全漏洞?整個學界大概是有這麼兩大類,類似動態的方法,動態方法的話就是像我們大家熟知的像Fuzzing,但是在將Fuzzing這種在傳統PC領域非常成熟的像AFL這些框架用在這種設備上的話就面臨一個問題,你需要把它模擬起來。所以說也就呼應我們前面說到碎片化,現在很難有一個非常統一的高效的這種恢復的環境,來支撐你做這種智能的Fuzzing。

所以整個來說,對IoT的安全研究是侷限性很大,然後會帶來比較複雜的一個局面。所以我們可以看到在安全頂會上面也有不少相關的研究工作在嘗試。比如,Ndss 2016有一個工作Firmdyne,其實這個工作是這方面做的比較大的貢獻。

 

 

然後第二塊的話就是靜態分析。靜態分析的話,學界比較推崇的是符號執行, 然而實際應用過程中,執行的時候面臨着很多的問題,第一個是它的開銷非常大,並且會碰到循環約束條件如何結束的問題,導致路徑爆炸。

然後還有你要準確的去模擬這種程序的上下文,比如跨進程的問題。如果你多進程通信的話怎麼來準確的模擬,因爲你是在沒有運行程序的狀態下,然後符號執行的話,經過這麼多年學界的不斷的推,它在現在的話是一種混合符號執行的狀態,也稱之爲動態符號執行。就是傳統的靜態符號之前基本上是不可用的。

所以近些年的話動態符號執行相對來說它用實際的值去替換符號值,所以會做一個路徑的探索。這一塊的話相對來說比之前的應用性要提高很多,其中的代表的工作是Karonte的,是UCSB發表在另外一個頂級安全會議 S&P 2020上面的。所以我們的工作大部分也是跟他們是聚焦在同一點,所以我們是在他們的基礎上又做了非常大的創新和改進。

 

 

好,我們講一下我們的方法——SaTC,簡而言之,方法來源於共享的關鍵字,基於這個關鍵字開展污點分析。我們可以看到像一個典型的這種路由器的話,像註冊的話,這裏是一個前端的一個界面,像前端的一個界面,然後右側的話就是它對應的二進制。像前端的話,你用戶發送的數據會由於前端代碼的這種解析來給到他一個標籤,然後後端的話會有相應的關鍵詞出現。所以說這是我們最開始爲什麼提出這種方法的一種出發點。

 

 

大家可以看一下這個漏洞是一個非常典型的漏洞,它是在一個路由器在插入U盤的情況下。可能可以觸發到他的一個命令出路,所以整個漏洞的一個出發過程分了4步,從最開始的操作U盤,然後到管理界面,在它的 response之這個迴應界面中再去點擊這個mod卸載這個指令,這樣的話在這個過程中它發生了一個命令注入,像這裏的右下角這是紅色字體這裏。

 

 

 

然後我們來看一下漏洞的深層次的原因,我們可以看到左邊的話是它前端的發現漏洞的一個代碼是JS代碼,我們看到它是用一個DOS內容這樣一個關鍵字來標註這段數據的,然後右邊是相應的二進制程序,它經過一系列非常複雜的函數調用之後,在最後他執行了一個命令叫form set usb unload,這個函數裏面它有個doSystem,所以在這裏的話他沒有去過濾發送過來 device name對應的字段的內容,所以就產生了命令注入。

所以整個攻擊來說,只要發送這樣一個惡意的鏈接,就可以完全控制路由器。

所以我們從這個例子可以看出,如果我們有一個非常高效的方法,從前端可以把這些關鍵字提取出來的話,那麼給我們帶來的直接的受益。就是我們在整個污點分析的過程當中的話,就可以跳過前面這些沒有太多意義的處理函數。

然而傳統的污點分析都是從前面開始的,前面這些函數有可能意味着類似於索賠的函道,然後也屬於文件系統的投入,對吧?這些內容都是完全跟我們後面的命令做系統來說沒有什麼太大的關係。

所以說給我們帶來的啓發,如果我們有這些關鍵字的話,會極大的縮減我們符號執行的路徑,就是讓它的可用性得到了進一步的提升。所以我們的一個非常簡單的想法就是說在前端的JS文件中,用戶輸入被一個字符串DOS等號來標記,然後在後端的二進制之中幾乎完全相同的字符串dos內容用於提取數據包裝對應的system。

所以說兩個同時出現的關鍵字就是我們標題裏面所講到的教學的Key words,所以我們的方法就是這樣子來的,就是用共享的關鍵字在後端的二進制中引入,引入點定位,並開始查找漏洞。

 

 

好,然後我們提出這個想法之後,我們需要去統計一下這種現象不是個例是不是隻有這個設備才存在。然後我們把手頭的各個廠商的路由器也收集一下,大概有這些廠商,都是比較主流的廠商,然後每個廠商的幾個型號,我們在利用真機調試的情況下,第8個的權限下面我們做了一個前端的黑盒的fuzzing,然後後端的話我們在相應的輸入點,把它的key-value這種參數對提出來,所以我們整個統計可以在這個表格中可以看出來。

有90%多的參數對是同時出現在後端的,然後進一步的我們在CV的官網上,近期54個已知漏洞裏面有35個可以獲取的固件,就是我們能夠分析的,我們發現其中有29個是可以通過共享關鍵詞來定位漏洞點的,所以這樣看來我們這個方法是具有一定的普適性。

我們來看我們要做這個工作大概面臨的幾個挑戰,第一個挑戰就是如何識別這種前端文件中的關鍵字。第二個就是如何定位這些關鍵是在後端的二進制裏面的處理位置。第三個就是如何跟蹤大量的用戶輸入的相關路徑,檢測是否存在安全漏洞。

所以我們可以看一下我們整個的一個設計,從最左邊開始是一些包的固件的預處理,然後右邊的話有最開始是一個輸入關鍵字的提取,然後第二個是第二個是輸入的點的識別,然後最後是一個污點分析,然後我們一個個看一下,我們輸入關鍵詞提取模塊,主要是我們對應的這些前端常見的資源文件,比如說像html裏面的這種JS還有html文件,然後包括xml文件這種描述文件,這裏面的關鍵詞都是我們需要去提取的,所以這裏的話我們其實也匹配了很多我們人工的一些經驗,對吧?

 

 

比如像 AST裏面的就是JavaScript,因爲它相對來說比較動態比較複雜,所以我們用ast來提取文本里面的對應節點的屬性,其實就是你可以簡單理解爲就是把JavaScript裏面所有變量的名字把它提出來,所以我們是對應的服務的話,除了HTTP服務,還有UPnP,還有HNAP服務。

然後在提取完之後,其實我們會發現裏面有非常多的無關的這種字符串,所以我們會制定一些規則,比如說這些跟輸入完全不相關的,我們就把它給剔除掉,然後如果字符串以“=”結尾的話,我們就留下左側部分,右側部分就把它捨去,還有一些比較短的這種字符串,所以我們整個的規則集合也是開放的,如果後續有嘉賓在使用的過程中,其實可以自己去定義。

 

 

然後我們主要是基於兩類,一個是基於前端經驗得到的這種篩選模式,還有一個是基於文件和字符串出現的頻率。你像這種其他文件裏面如果像共享庫中的字符串對吧?它大量的被引用,所以我們認爲字符串其實是跟輸入定製開發是完全沒有關係的。然後還有類似於通用字符串,我這邊舉的例子什麼Button和Cancel,這在大概率的情況下是不會有問題的。

所以我們在關注這種開發者定義的這些前端輸入的情況下,我們就開始做後端的匹配,就是把剛纔過濾完的字符串和後端的所有二進制裏面字符串做一個匹配,然後這裏還會有帶到帶來兩個非常好的,一個就是可以把邊界服務給識別出來,就是說其實在路由器裏面,你如果做過漏洞挖掘的話,其實你會發現因爲特別是那種cgi的模式下,其實你很難一開始去找到一個跟邊界相關的,因爲它的命名也不會有太多的這種規則。

如果出就是出了HTTP這種,非常常見的,所以說如果你的關鍵詞量特別大,比如說我跟包括服務相關的關鍵詞在二進制裏面匹配的數量特別大,我們就會認爲它是我們要關注的,可能存在安全漏洞的邊界服務,所以我們怎麼會做一個排序,把最高的關鍵字的對應的二進制來做布點分析。

然後所以緊接着第三個就是一個輸入點的識別模塊,這裏的話整個大概分了三個部分,第一個就是最簡單的就是它的一個直接引用,像圖裏面紅色框子裏的,對它直接對device裏面的引用。

 

 

那麼第二個的話就是類似於這種啓發式的,我們可以看到這裏有一個USB Name這個關鍵詞其實在前端裏面是提到的,但是我們通過啓發式的可以把它發現出來,因爲你可以看到它的上下文有非常多的其他的關鍵字,我們能夠突破的關鍵字,跟它出現在同一個上下文,而且它的數據都是一樣的,所以我們通過啓發式的把這些也找到了,而且這種的話很大的概率很有可能是一些開發者不小心留下來的,或者說是一些惡意的後門也是有可能的,因爲它在前端其實不可見的。

 

 

然後第三個的話這裏我們要提一下,還有一個是跨二進制的,我們可以看到紅色框裏面的有一個關鍵詞叫URL filter mode,其實它是跨了兩個進程。

所以說這種方式的話,其實我們最開始背景裏面介紹的UCSB的KARONTE的話,其實他是做了下面這一塊,但是他們第一塊是沒有做到的,他無法從源頭開始,所以說我爲什麼前面提到,其實我們是對他們是一個非常大的推進,就在這裏。

 

 

然後在關鍵字識別匹配出來之後,我們就要開始做一些輸入敏感的這種數據流分析,我們可以得到污點的數據源,然後依據輸入引入點的識別結果來標註污點源,可以是一個目標函數的這種參數,也可以使它的返回值。

比如說像我們圖裏面 cmd變量指針變量,這個字符串指針我們可以把它作爲一個標記、一個污點源,第一步是污點源的標記。

 

 

然後第二步的話我們會關注兩類這種漏洞,一類是這種內存破壞型的,還有類似命令注入,這樣的話我們會對應得到不同的兩類的Sink Point。

一種是類似於Memcpy這類函數,還有類似System的這類函數,就是調用這個系統需要的,可能主要面臨出路。

 

 

所以在這種情況下,我們會做一個整個從輸入剛纔我所提到的關鍵字的引入點到SInk Point的一個call,對所有的call trace是一個函數調用的序列,從引入點到潛在的危險函數,然後所有的call trace是我們會把它進行合併,就相當於土地這樣,左邊的話是一個很普通的call tree,大概有這裏面有我們舉了兩個例子,有兩個Sink Function Set,SinkX、SinkY這兩個函數,所以你有很多調用序列可以到達這裏。

但是我們發現如果你每個序列給到單個去執行的話,其實代價會比較大,我們就把它做了一個合併,就相當於我們不需要去運行每次的call trace,我們可以把它合併,把它改成了一個類似於塑形的探索。

然後angr其實非常也支持這樣子,所以我們在右邊這個函數集合裏面,我們就分了兩類,一類是叫改理方向,就是說碰到這種函數的話,你的符號執行引擎會step into進去。

然後下面一類的話就是一個方向去,就碰到這種自己函數的話,你就要去考察它的策略是不是出現了這種污點的違背,比如說有命令注入了對吧,注入對應的c端的函數,這個參數它是外部可以污染的。

 

 

然後我們做的是一個粗粒度的污點分析引擎,所以這是一個怎麼說是兼顧效率和準確性。

然後是運行在這個指令級別,然後針對函數調用的話,我們把它分成三類,就是我們可以發現在整個你的符號執行過程中,我們把它函數分成這三類,一個是可摘要函數,比如說我們常見的這種一個c的庫函數,要copy這種它是可摘要的,這樣的話你直接運行它對應的這種語義就可以了,所以不需要進入它的函數內部。

然後第二個是普通函數,就是其其實就是說它是裏面又沒有再深層次的嵌套,函函數調用或者它的調用的是可摘要函數,所以這種函數的話我們用angr去跑的話是完全可以解決它的,這樣子我們可以讓它跟錄進去其他工作。

然後還有一個是嵌套函數,嵌套函數就是我們這裏的粗力度的這種布點分析引擎的關鍵的策略所在。

我們會去看如果它的參數被我們污染,然後它的返回只是一個指針,同時在後續如果被使用的話,我們會去污染反饋指針,如果不是的話,我們就污染其他的場所,這是我們的一個方法上的策略。

 

 

然後整個來說的話,我們還有一個非常大的進步,就是我們對整個路徑做了一個優化,路徑它所做的優化。

我們可以看到在右邊的話,這是在符號使用中非常頭疼碰到的這種循環函數。因爲大家都知道如果你的循環變量是一個符號式的話,其實你很難去判斷什麼時候去接受這個循環,所以你的狀態空間是一直在增長的,然後哪怕是現在用這種混合符號執行,你給他一個具體值。

但是你像剛纔我們圖裏面這個我們圖裏面其實就是一個非常明顯的過濾函數,就是說如果有不同的字符,它對應的策略是不一樣的。

所以說在這個情況下,它的路徑探索,哪怕你給它一個具體的詞,它的探索的效率是非常低的,就是說他可能要運行很多次之後,才能夠把BBL所有的這些裏面的這些裏面的這種這個函數約束取出來。就是它的分支約束取出來,所以說你很難要要求這個陸續探索期,他每次都非常精確的選擇右邊,對吧?他只要一選擇,左邊他就回去了。

所以說你要是要把右邊這些標的的話全部攤下來的話,這個代價值是就是說你如果隨機的話,隨機的話是很難的。因爲現在的這種混合符號執行的話基本上是這樣,它在這個條件的時候一般是第一次選擇了左分枝,第二次就選擇右分枝了。

對他是這樣來迭代的,所以說這樣的爲了提升效率的話,就會我們有一個算法,我們就會去找這種業績點,這個業績點就非常的有特點,對吧?它的前期非常多,然後它的後期節點是吧?這隻有一個,所以他前期非常多,所以這種情況下我們有一個算法,類似於出現循環的函數裏面,如果有一個比較快,它的前向節點快大於50%以上的話,我們認爲這個函數就符合我們這種策略處理的特徵。

我們會在探索的過程中找到這種節點之後,我們會在控制流裏面直接把這個節點刪掉,因爲這個節點跟約束沒有關係,所以這樣的話反而大大提升了我們效率,把這個節點刪掉之後,一次性就把它全部走回來了。

所以這是我們整個對符號執行在理論上的一些貢獻。所以說我們這個方法也是得到了一些應用,在實際的過程中,特別是在你比如如果有這種ctf或者是網絡這種經驗的話,你找到一個命令錯誤的漏洞之後,可能都會想怎麼去過這種制服的比例。

你要把空格、雙引號什麼都要放進去,但是它肯定會是有過濾的,所以這個方法就能夠快速的把所有的過濾條件提取出來。

然後我們的實驗評估的話大概分了這三類,我們快速的過一下,第一個就是是否可以找到真實的安全漏洞,真實設備中的安全漏洞。然後第二個就是他是否可以準確的找到輸入關鍵字,他找到那些關鍵字裏面有哪些是錯誤的。然後第三個就是污點分析的效率和準確性如何

 

 

第一個的話我們整個看到我們是找了6個廠商14個情況,大概有39個部件裏面,然後包括了兩兩類架構,有路由器和攝像頭兩大類,然後總共發現了大概有33個是新發現的安全漏洞,裏面還有30個CVE、CNVD、PSV。

然後覆蓋的這種邊界服務的話,除了HTTP常見以外,還有HNAP是基於HTTP,然後還有UPnP。

然後對這裏的漏洞類型的話,除了我們之前提到的命令出路和緩衝以外,我們還找到一些訪問越界。

因爲我們在提取關鍵字的時候,其實也會碰到客戶端服務的那些跟接口相關的 F區相關的一些這種接口,我們可以去調後端的一些功能,然後有些功能其實它是存在越界的,所以我們直接就可以把它這種問題給發現出來。

 

 

然後第二個的話關鍵是提取這塊的效率的話,我們可以看到就結合我們人工去驗證的方法,大概整個以這裏Tenda爲例的話,我們整個的效率就是正確的關鍵字,就是跟輸入相關的關鍵詞大概有70%以上是正確的。

 

 

然後我們33個發現的漏洞當中,有22個關鍵字是在JavaScript裏面,然後有8個是在XML裏面,然後有4個是HTML。

然後引入點的識別效果裏面也可以看到,其實每一個廠商確實還是差別挺大的,然後你像Tenda的話可能就是第一類,所以就比較多,直接的這種識別就會比較多一點。

然後像Netgear的話好像是影視輸入的,就是需要啓發式算法的,然後包括 D-Link的話就是跨邊界的,跨邊界就是要多個版本來組合起來識別的是比較多的。

 

 

然後路徑合併的效果也可以看到,特別是我們這裏舉紅色框出來的,像D-Link的話,其實每個引入點存在的大量的trace都是在一個樹裏面,所以說它的壓縮比率非常高,整個壓縮下來只有5%不到,所以對效率的提升非常大,這也是爲什麼我們引擎確實能夠起作用的一個原因。

然後整個的誤報和漏報如何,就是SaTC的話總共是輸出了101個告警,有46個確認是正確的。

然後這裏的一些誤報是因爲缺少了一些常用函數的摘要,然後還有一些這些函數它可能就是會導致我們面臨注入時就成爲不報了,因爲他把所有的這atoi就轉換了,字符串對應的是二進制了,所以你就很難產生面臨錯誤了,所以是這種完全我們後續可以去擴展我們這個行業摘要來支撐把這些誤報給解決掉。

 

 

然後漏報的話,我們通過全量的測試,就是我們拋開效率不談,我們把所有的關鍵詞進行跑一遍之後,我們全量測試的時候發現確實有漏報,然後有一個是叫cmd input,這個很明顯是類似的一個後門,所以說它沒有出現在前端,所以我們就把它給漏了。

然後還有一個是對他的話,因爲出現在很多地方,我們因爲剛纔算法策略的問題,我們把這種大量同時出現了,我們把它給刪掉了,所以這是我被我們策略所顧上的。

然後我們總結一下,我們是提出了一種全新的這種物聯網設備的這種漏洞這個方法,然後基於物聯網設備中常見的這種前後端共享關鍵字的這樣一種狀態。

 

 

第三個的話就是我們是有一個系統,在實際應用中其實效果已經很突出了,我們最近在接觸了一個也是我們去國家的關鍵基礎設施的一個行業的類似於他們國家的分析,我們直接上去之後就可以報出真實漏洞,雖然說誤報率大概在20%多一點,所以說還是在實際應用中效果還是比較突出的,這是我們的Paper和Slides,還有我們的代碼也開源了在GitHub上面,所以歡迎各位可以有時間去試用,然後有問題的話可以隨時給我們提。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章