Flash應用程序安全攻防戰(zhàn)
原創(chuàng)【51CTO.com獨家特稿】Adobe的Flash技術已經(jīng)變得越來越流行,現(xiàn)在它不僅用于創(chuàng)建動畫和廣告,而且還用來開發(fā)復雜的互聯(lián)網(wǎng)應用軟件。Flash應用程序(即SWF文件)不僅可以通過web協(xié)議進行分發(fā),并且還能讀取本地或者遠程文件、建立網(wǎng)絡連接,以及跟其他SWF文件進行通信等。通過本文,您將了解具體的Flash攻擊手段,有用的Flash安全審查技巧以及安全有關的開發(fā)/配置技術。
一、XSS威脅
從事Web應用程序的開發(fā)或者測試工作的人都知道,Web應用程序有一個常見的安全漏洞,即通常所說的跨站點腳本攻擊(XSS)。一般地,如果一個應用程序接受不可信任的源提供的惡意代碼,并且在沒有對這些數(shù)據(jù)進行消毒處理的情況下直接將其返回給毫無防備的用戶的話,就會發(fā)生XSS。雖然Flash應用程序對XSS及其他類型的安全威脅也沒有免疫能力,但是web管理員和Flash應用程序開發(fā)人員卻能夠通過采取相應的安全措施來提高這種新興技術的安全性。
一般情況下,進行跨站點腳本攻擊時,攻擊者需要將惡意腳本代碼(諸如JavaScript或者VBScript代碼)注入到Web 應用程序中,這通常是通過哄騙用戶單擊一個鏈接或者訪問一個邪惡的網(wǎng)頁來完成的。隨后,該web應用程序將在受害者的web會話的上下文中顯示并執(zhí)行注入的代碼。這種攻擊通常能導致用戶帳戶失竊,但是卻不會導致執(zhí)行命令,除非同時利用了瀏覽器的安全漏洞。因為SWF程序可以嵌入到網(wǎng)站中,并對HTML DOM(文檔對象模型)有完全的訪問權,所以可以通過利用它們來發(fā)動XSS攻擊。想像一個顯示第三方Flash廣告的免費電子郵件web服務:一個惡意的廣告商可以創(chuàng)建一個惡意的SWF應用程序來劫持您的電子郵件帳號,以便發(fā)送垃圾郵件。默認時,F(xiàn)lash Player對同域的DOM具有完全的訪問權限。
下面介紹針對SWF應用程序的XSS攻擊的基本流程。第一步,攻擊者必須首先設法將代碼注入到應用程序中,以便讓代碼重新顯示給其他用戶。Adobe為程序員提供了各式各樣的用戶界面組件,諸如組合框、單選按鈕以及文本字段等,它們的用法跟HTML表單對象極為相似。此外,讓SWF應用程序接受從外部輸入的參數(shù)的方法也很多。
我們可以使用 < OBJECT > 和< embed >標簽將屬性FlashVar嵌入到一個HTML文檔中。
|
| 圖1 |
此外,還可以直接通過URL傳入數(shù)據(jù):
|
| 圖2 |
另外,可以利用類LoadVars來裝載外部數(shù)據(jù)。
|
| 圖3 |
對于ActionScript 2來說,F(xiàn)lashVars會被自動導入到Flash應用程序的變量空間,但是在ActionScript 3中,加載外部參數(shù)時需要額外的代碼來完成。一個常見的錯誤是,從FlashVars或者URL參數(shù)接受數(shù)據(jù)后,沒有經(jīng)過恰當?shù)妮斎腧炞C就直接將它們傳遞給了與瀏覽器直接通信的那些函數(shù)了。ActionScript 2中的函數(shù)getURL以及ActionScript 3中的函數(shù)navigateToURL具有將指定的URL裝載到一個瀏覽器窗口的能力??梢钥紤]一下以下ActionScript代碼:
|
| 圖4 |
該代碼直接利用一個來自外部源的變量來調用函數(shù)getURL,這會將用戶重定向至指定的URL。例如,攻擊者可能會建立如下所示的請求:
|
| 圖5 |
發(fā)出該請求之后,會彈出一個JavaScript警告框,并顯示站點cookie的內容。Cookie經(jīng)常用于存儲敏感的帳戶數(shù)據(jù),諸如會話標識符等。DOM是一種標準對象模型,用來以樹狀結構表示HTML;DOM可被JavaScript代碼用于動態(tài)刺探或者修改HTML頁面??梢钥紤]下面的JavaScript代碼,它將更改在這個HTML頁面上的第一個圖像的屬性source。屬性source被修改后,在該頁面上顯示的圖像也將隨之改變。
|
| 圖6 |
攻擊者常用的一種手法是,通過修改HTML DOM插入一幅新的圖像,并讓該圖像的屬性source指向在攻擊者所控制的服務器上的一個文件,同時將cookie內容作為一個參數(shù)。通過這種方法,攻擊者只要監(jiān)視他的計算機的日志就能夠獲取cookie數(shù)據(jù)。如果其中含有會話id的話,攻擊者就能夠完全控制用戶的帳戶,直至會話到期為止。還有一個ActionScript函數(shù)可用于發(fā)動XSS攻擊,它就是fscommand。SWF文件可以通過這個fscommand函數(shù)跟Flash Player或者托管Flash Player的程序進行通信。通常情況下,F(xiàn)lash Player會駐留于一個Web瀏覽器中,但是它也可以位于其他能夠托管ActiveX控件的程序中。函數(shù)fscommand由兩個部分組成:一個命令和一個參數(shù)。下面的fscommand函數(shù)將發(fā)送一個changeText命令,該命令的參數(shù)是由FlashVar來指定的。
|
| 圖7 |
清單 1 中的JavaScript代碼因此能留駐在處理SWF應用程序發(fā)送的命令的HTML文檔中。它只是取得參數(shù),然后修改由text指定的HTML 元素。開發(fā)人員應該注意從用戶那里接收的、用于fscommand函數(shù)的輸入數(shù)據(jù)的類型,以及各參數(shù)在HTML文檔中是如何使用的。
清單 1. 接收fscommand的代碼
|
| 圖8 |
清單 2. 簡單的密碼檢查代碼
|
| 圖9 |
上述的示例代碼為攻擊者直接向DOM注入HTML或者腳本代碼提供了方便之門,例如,下面的請求將包含并執(zhí)行一個存放在遠程主機上的JavaScript文件。
|
| 圖10 |
#p#
二、HTML格式的組件
Adobe可以支持標準的HTML標簽的一個子集,我們可以使用ActionScript 2.0中的Text Field 組件或者TextArea組件把這些受支持的HTML標簽可以放到Flash電影片段中。如果不對用于構造HTML的用戶輸入進行嚴格的驗證的話,這兩個組件都有可能被濫用。對image和anchor標簽的驗證需要格外仔細,因為它們尤其容易導致安全漏洞。在Flash中,利用< img >標簽不僅可以在SWF文件和電影片斷中嵌入外部圖象文件,而且還可以嵌入SWF文件和電影片斷,從而發(fā)起各式各樣的攻擊。下面的代碼會把來自外部源的數(shù)據(jù)賦給HTML的text組件:
|
| 圖11 |
將JavaScript嵌入圖像的嘗試將會失敗,因為Flash Player好像會驗證圖像是否真是一幅JPEG、GIF 或者PNG格式的圖像。
|
| 圖12 |
但是以下代碼將向您證明,F(xiàn)lash Player所做的驗證太小兒科。它只是檢查給定的source屬性是否以字符串.jpg結尾的,因此,只需添加一個類似C語言的行注釋,我們無需改變這個腳本代碼的功能便可哄騙Flash Player去執(zhí)行< IMG >標簽中的腳本。瀏覽器一旦加載了這個SWF文件,不需要人工介入該JavaScript就會被執(zhí)行,并出現(xiàn)一個彈出式窗口。
|
| 圖13 |
使用此方法我們可以很輕松地將JavaScript或者VBScript注入TextArea組件中。以下請求說明對于錨標簽沒有這樣的驗證,但是這類XSS攻擊要求人工介入。用戶必須單擊這個連接才會執(zhí)行代碼。
|
| 圖14 |
就像前面提到的那樣,< IMG >標簽不僅能夠裝載實際的圖象文件,而且還可以裝載SWF文件。這可能導致一個不懷好意的SWF文件被載入到一個受信任的應用程序中。當裝載其他SWF文件時,應該使用一個框罩來限制這個子SWF文件的顯示區(qū)。如果原始的SWF沒有設置框罩,那么子SWF文件就有可能覆蓋整個播放區(qū)域。這可用于欺騙受信任的應用程序。但是如果這個注入的SWF來自一個外部域的話,F(xiàn)lash安全策略仍舊對其有效。#p#
三、ActionScript的函數(shù)協(xié)議
上述的例子使用了JavaScript來演示用戶常見的XSS攻擊,但是有一個專門用于Flash的協(xié)議即asfunction,它可以致使一個連接調用一個ActionScript函數(shù)。例如,當用戶點擊了存放在TextArea組件中的錨點時,下面的代碼會調用帶兩個參數(shù)的本地函數(shù)foo。
|
| 圖15 |
顯而易見,這種能夠從HTML組件內部直接調用Actionscript函數(shù)的能力存在極大的安全隱患。可以考慮一下清單 2所示的一個簡單Flash應用程序,該程序通過接收用戶名和口令來進行身份驗證。當用戶輸入了錯誤的密碼時,用戶名以基于HTML的TextArea組件形式回顯給用戶。假設一個輸入了如下所示的用戶名,并隨意猜了一個密碼。
|
| 圖16 |
應用程序將通知這個用戶,提供的用戶名/密碼無效,同時用戶注入的錨也作為HTML輸出的一部分顯示了出來。當用戶點擊這個鏈接時,setPassword函數(shù)將會被調用,從而將密碼設為abc。上例說明了允許用戶執(zhí)行任意的Actionscript函數(shù)來操縱程序的應用程序數(shù)據(jù)是非常危險的。如果一個Flash應用程序中存在持久性的XSS安全漏洞,這會導致存心不良的用戶能夠讓其他用戶在受信任的沙箱中執(zhí)行任意的Flash函數(shù)。受本地信任的SWF文件甚至能讀取本地的文件,并向任意服務器發(fā)送消息。ActionScript包含有豐富的函數(shù)庫,因此攻擊者可以通過更高級的攻擊類型利用這些庫函數(shù)進行聯(lián)網(wǎng)和通信,以至于訪問本地的文件系統(tǒng)。 #p#
四、未初始化的變量
PHP程序員可能聽說過一種有爭議的特性,叫做Register Globals,該特性允許從POST和GET請求將請求中的變量注入到一個腳本的變量空間中。當然,該特性并不常用,甚至有的程序員都不知道該特性的存在,由于備受抨擊,所以將在新的PHP 6中去掉該特性。 理論上,使用register globals也有可能寫出完全安全的程序,但是現(xiàn)實中在Web應用程序中發(fā)現(xiàn)的大量漏洞都是由于該特性使用不當所導致的。
ActionScript也有一個類似的特性,不過在版本3的時候已將其取消了,但是因為ActionScript 2依舊在Flash社區(qū)內廣泛使用,所以這個問題仍然值得我們關注。任何未初始化的變量都可以作為FlashVar進行初始化。當程序員忘記給關鍵變量賦初值或者將變量指定為undefined的時候,很可能會帶來后患??梢钥紤]一下清單 3 中的代碼,它決定用戶是否被允許查看一些機密信息。
清單3. 依賴于未初始化變量的代碼示例
|
| 圖17 |
程序員依賴于這樣一個事實,即如果變量userLoggedIn沒有初始化,它就會被設為undefined。而undefined這個值在條件語句中被作為false對待。繞過ActionScript 2中的代碼很容易,因為變量userLoggedIn未經(jīng)初始化。只需在GET請求或者在HTML中作為一個對象參數(shù)將userLoggedIn設為true,如下所示:
|
| 圖18 |
在ActionScript 3中,F(xiàn)lashVars只能通過LoaderInfo類的parameter屬性進行訪問,這使得針對未初始化的數(shù)據(jù)的這種攻擊不再可行,不過,開發(fā)人員仍然應該仔細檢查傳給SWF的所有參數(shù)。#p#
五、SWF之間的通信
與瀏覽器的Cookie機制相似,本地共享對象(LSOs)為SWF應用程序提供了少量的持久性存儲空間。LSO會受到特定的域、本地路徑或者HTTPS連接等方面的限制。 在清單 4 中的代碼將生成一個共享對象,并且該對象可以被存儲在/a/b或者其子目錄(如a/b/c)下的其它SWF程序所訪問。函數(shù)flush將強制將這個對象寫到這個文件中。
清單4. SharedObject示例代碼
|
| 圖19 |
如果您打算把機密信息儲藏在一個本地共享對象之內,那么可以把標志secure設為true,這樣一來就只有通過HTTPS才能訪問這個SWF。不管它們是如何被傳輸?shù)模琇SOs是以明文的形式存放在客戶端的機器中的。由于ActionScript自身沒有提供加密類,所以如果想保護存儲在LSO中的重要的信息的話,就只好使用第三方加密程序庫了。
為了讓運行于同一個客戶端機器上的SWF應用程序之間可以直接相互通信,ActionScript提供了LocalConnection類。這時必須有一個swf應用程序充當接收方,另一個充當發(fā)送方。 這些SWF應用程序并不一定非要運行在同一個瀏覽器中不可,但是默認時,只有位于相同的域中的SWF程序才能相互通信。在調試階段,開發(fā)人員經(jīng)常使用allowDomain函數(shù)來放寬這個默認的安全限制。清單5中的代碼,讓LocalConnection來接收數(shù)據(jù)。
清單5. 接受 LocalConnection 的代碼
|
| 圖20 |
如果產(chǎn)品代碼中遺留了allowDomain(‘*”) 將是非常危險的,因為它允許來自任何域的任何SWF程序都能訪問你的應用程序的內部函數(shù)。通配符最好的使用方式是只允許相同的域或者子域之間的SWF可以進行通信。例如,allowDomain(“*.test.com”)將允許在www.test.com和mail.test.com之間的通信。為了發(fā)送數(shù)據(jù),可以使用LocalConnection函數(shù),如清單 6所示。 如果不使用函數(shù)connect的話,發(fā)送方可以使用想要函數(shù)名和參數(shù)來直接調用函數(shù)send。
清單 6. 發(fā)送LocalConnection的代碼
|
| 圖21 |
#p#
六、正確的輸入驗證
輸入驗證的常見方法是檢查一塊數(shù)據(jù)是否匹配一個正則表達式。正則表達式的作用是描述一個字符模式。ActionScript在版本3開始對正則表達式提供本地支持,并使用EMCAScript語言規(guī)范來實現(xiàn)正則表達式。仍然使用ActionScript 2的傳統(tǒng)開發(fā)人員在驗證數(shù)據(jù)時,卻無法借助正則表達式或者諸如As2lib之類的第三方程序庫。可以考慮一下以下有弱點的代碼:
|
| 圖22 |
不要盲目信任用戶提交的電子郵件,而要使用正則表達式進行雙重檢查來將惡意用戶拒之門外。清單7中的代碼給出了一個使用正則表達式測試一個電子郵件地址是否合法的函數(shù)示例。
清單 7.驗證電子郵件的規(guī)則表達式
|
| 圖23 |
如果您的應用程序必須遷移到ActionScript 3.0,那么即使不用正則表達式也能進行輸入驗證,盡管此解決方案不太優(yōu)雅并且不太合乎RFC標準。不用正則表達式驗證輸入時,一般地需要調用許多標準串函數(shù),如清單8所示。
清單8. 無規(guī)則表達式的電子郵件驗證
|
| 圖24 |
如果您必須使用用戶輸入的數(shù)據(jù)來供getURL函數(shù)或者HTML文本組件使用,那么可以利用正則表達式定義那些數(shù)據(jù)是可以接受的,并只接受http或者https協(xié)議處理程序用于有效的鏈接。不要依賴轉義函數(shù)來進行輸入驗證。按照Flash幫助文檔的規(guī)定,escape函數(shù)將參數(shù)轉換成一個字符串,并以URL編碼的格式對其進行編碼,其中非數(shù)字字母字符被替代為%十六進制序列。可以考慮一下以下代碼,它沒有正確地使用escape函數(shù)來進行輸入驗證。
|
| 圖25 |
Escape函數(shù)不能阻止惡意用戶潛入JavaScript函數(shù),并執(zhí)行他們自己任意的腳本代碼,例如請看以下請求:
|
| 圖26 |
#p#
七、安全地公布內容
不僅Flash開發(fā)人員應該花時間去驗證輸入,web管理員也應該通過設置安全措施來防止不可信的SWF文件訪問瀏覽器和/或網(wǎng)絡??梢酝ㄟ^ < OBJECT > < embed >標簽把SWF應用程序作為對象嵌入在一個HTML頁面中。您可以在影響安全策略的< embed >或者< object >標簽之內規(guī)定三個可選參數(shù)。 參數(shù)allowScriptAccess控制SWF文件是否能夠訪問HTML容器。而allowNetworking參數(shù)則控制SWF使用ActionScript的網(wǎng)絡API的能力。最后,allowFullScreen參數(shù)決定Flash應用程序是否被允許控制整個屏幕。
參數(shù)allowScriptAccess有三個可能的值:
◆always:允許SWF和HTML頁面通訊,不管加載這個HTML頁面的域名如何。 只有在完全信任這個SWF的時候才能使用這個選項,它是Flash Player 7和早先的版本的默認行為。
◆sameDomain:只有在兩者位于同一個域中時才允許SWF應用程序修改底層的HTML頁面。 位于域www.a.com中的Flash應用程序不能修改位于www.b.com中的HTML頁面。這個是Flash Player 8及隨后版本的默認行為。
◆never :絕不允許在HTML頁面和SWF應用程序之間進行通信。
參數(shù)allowNetworking也有三個可能的值:
◆all:SWF應用程序被允許使用網(wǎng)絡API建立無限制的網(wǎng)絡連接。
◆internal:SWF應用程序不允許調用瀏覽器的導航或者交互API,但是被允許調用其他網(wǎng)絡調用。
◆none:禁止SWF應用程序使用任何網(wǎng)絡API。
參數(shù)allowFullScreen僅僅有兩個可能的值:
◆true :SWF應用程序被允許占用整個屏幕。 這個選項可能被惡意用于誘騙攻擊。
◆false:fullscreen模式不被允許。
許多流行的論壇允許其管理員創(chuàng)建他們自己的BBCode以使得用戶可以格式化討論貼或者包含額外的內容。許多管理員已經(jīng)增加了支持SWF的BBCodes。可以考慮一下以下不安全的HTML代碼替換Flash BBCode。
|
| 圖27 |
在一個有敵意的你不可以信任任何張貼的swf應用程序設置中,必須將在< embed >標簽之內的allowNetworking、allowScriptAccess和allowfullscreen顯式設置,以防止惡意應用程序進行非本意的網(wǎng)絡或者腳本調用。不應依賴默認Flash Player安全設置,而應當假設一些用戶無法或不愿意更新軟件。清單 9中的HTML代碼給出了安全的設置。
清單 9. 為 HTML 的Object 標簽添加適當?shù)陌踩O置
|
| 圖28 |
#p#
八、安全分析工具
目前,可用來對Flash應用程序進行安全審計的工具仍然不多。Stefano Di Paola已經(jīng)編寫了精巧的工具用來發(fā)現(xiàn)跨站點腳本攻擊和跨站Flash漏洞,該工具名為SWFIntruder。這個工具提供了一組預定義的攻擊方式,這些是可定制的,并能以半自動化的方式進行XSS測試。這個工具運行在Web服務器上,可以通過瀏覽器進行訪問,它能顯示全部未定義變量和SWF應用程序中所有已經(jīng)實例化的變量。
用戶可以通過選擇一個參數(shù)來測試和執(zhí)行各種攻擊,并提供XSS掃描的輸出結果。 SWFIntruder的一個主要局限性是它僅僅能分析低于版本8或者ActionScript 1或者2創(chuàng)建的Flash應用程序。當審計封閉源碼的Flash應用程序或元件的時候,反編譯器就顯得尤為重要了。反編譯器提供了編譯程序的逆過程,因為它將低級計算機代碼轉換為一個高層的抽象化代碼。 Flash反編譯器接受swf應用程序的字節(jié)碼,然后生成相應的ActionScript代碼,而后者相對來說更易于人類閱讀。為了揭露安全性缺陷,使用靜態(tài)分析工具來針對生成的ActionScript代碼進行分析就更方便了。免費的反編譯器的一個例子是Flare,它將從一個swf應用程序中提取全部ActionScript文件。不過,就像SWFIntruder一樣,F(xiàn)lare 不支持ActionScript。 但是有商業(yè)產(chǎn)品可以從ActionScript1/2或者ActionScript3應用程序生成FLA文件,前提是必須掏錢。
九、結束語
在開發(fā)基于web的富應用程序的時候,許多Flash應用程序開發(fā)人員并沒有意識到它們正受到惡意用戶的各種安全威脅。盡管安全社區(qū)對XSS、未初始化的變量攻擊及其他輸入驗證漏洞并不陌生,但是Flash提供了一種新的攻擊類型,尤其是那些無防備的和未經(jīng)嚴格測試的Flash程序。不過,只要經(jīng)過程序員、測試人員和web管理員密切配合,經(jīng)過適當?shù)呐嘤柌斎攵诉M行嚴格檢查,就能夠有效減輕Flash應用程序中的跨站點腳本攻擊漏洞所帶了的威脅。
【51CTO.COM 獨家特稿,轉載請注明出處及作者!】
【編輯推薦】

















































