作者:空虛浪子心【XGC】
【IT168專稿】引言
因為一個0day,讓作者對java applet心血來潮,隨著不斷的失敗,發現了一個又一個安全特性。本文提醒大家,除了activeX,還有這么一種東西,一旦出現了安全隱患,也會幫大 家做些什么。如果你要找“0DAY”,請掠過;如果你要找“如何使用APPLET下載木馬”,請看下集;如果你喜歡研究“applet可能存在的安全隱患 ”,請從這里開始。
第一部分 一個“0day”狂想
最近常聽見有朋友說“只有跨站執行腳本才是王道”,但是我想,每一門藝術(技術),都有自己的獨到的美(特性),就像后門除了使用“特洛伊”,還有可以用很多微小的途徑,拼合起來,就可能達到比它更加完美的效果。
論壇上某帖發出一篇通殺FF和IE的0DAY代碼:
說實話,剛拿到代碼時很興奮,看起來只要用戶只要瀏覽applet的頁面,就可以自動執行JAVA(applet),在用戶的機器上亂寫亂畫。 這是多么美妙的事情啊,只要用戶裝了jre,就完蛋了。于是跟貼發表評論,解讀這段代碼的含義,甚至還發表了改進的看法。但是等朋友讓我寫出改進的代碼, 才在不斷的實踐中發現自己的回帖完全是紙上談兵。
Java applet可以用來點綴html的頁面,讓它更加花哨,更加吸引MM的目光。某種程度上,它和微軟的activeX是一個級別的,都是用來擴展HTML 效果。如果搜索“java applet”,可能會搜索到《java applet向activeX下跪》這篇文章,applet曾經風光一時,后來被微軟的activeX壟斷。但是畢竟功能還在,也就是說,值得探究的安全 性因素還在。雖然必須要安裝JRE環境才可以執行,但是畢竟可以“禍害一部分人”,隨著sun的“進一步戰略”,也許這個家伙有一天還會冒出來。
在網上找了applet安全的文章,也就那么可憐兮兮的幾篇。大概內容都是先列舉了他的寫文件代碼,然后告訴讀者這些危險動作默認是不可做的, 只有用戶同意了安全證書,才會在用戶的policy里加入“讀,寫,執行”等權限。但是你如果真的在問用戶“嘿!哥們兒,咱有個東西,你先點同意,同意我 在哥們兒臉上寫點東西,同意我看看哥們兒暗戀的MM,同意我控制哥們兒幾天,同意。。。。”。作者沒那么深的釣魚功力讓用戶簽訂不平等條約,所以,本文就 不探討當用戶簽訂安全證書后發生的安全隱患了,因為那真的等于讓用戶使用最高權限執行一段不可預知的代碼。
要研究applet的安全,首先要打開瀏覽器(IE,FF),工具--?SUN java控制臺,右下角會出現冒火的咖啡,右鍵選擇“打開控制面板”,打開“高級”選項卡,選中“調試”里的勾。
選擇之后,在每次瀏覽applet頁面時,會看到控制臺上會出現每一步的程序執行信息,便于我們知道發生的異常和程序運行結果。
回頭看看這段“0day”代碼的執行,我為什么會說“紙上談兵”呢?分析“0day”的執行順序:“新建文件--利用HTTP協議取文件--把取得的文件內容寫入新建的文件--執行該文件”。好哇!整個就是一個下載者經典流程。看看我們執行后的控制臺信息吧。
執行過程很明確,打印出了“aaa”,說明代碼執行進入了start方法里。Applet的執行順序為“初始化類(構造方法)--調用init 方法—調用start方法--。。。。。”,你可以認為只要代碼寫在start里,就會執行。這些都是由瀏覽器執行的,我們的找茬范圍,就是當瀏覽器執行 這些代碼的同時:有沒有忽略什么、還能做什么、在做什么的同時會不會觸發什么。看這里的信息,并沒有去那個URL地址拿EXE文件,反而到了aaa就結束 了,是因為程序里抓了異常,但是故意不做處理。修改代碼,打印異常信息到控制臺。繼續執行。
除了上面的信息外,又打印了
原來,在執行
時,發生了安全異常,不允許新建文件“C:/windows/system32/Client.exe”。好了,連這個新建文件的權限都沒有,還談 什么去執行它。很顯然,這段代碼單純的執行并不能達到“0day”的效果,可能有些觸發條件沒有被貼出來吧,它只能算是一段shellcode罷了。 “0day”夢想暫時結束。那,不能新建文件也可以,如果能把用戶個人電腦的文件偷偷發出去,也是個不錯的選擇。
第二部分 嘗試操作文件
所謂的危險性操作,在applet的執行環境下可能發生的有:
讀文件
寫文件
執行
跨域取東西
跨域通知
跨域建立socket鏈接
調用外部引擎(JDBC等)
調用APPLET外的JAVA代碼
控制瀏覽器做一些不合理動作
等等。
發用戶機器上的文件給某人,不錯的想法,但是這里涉及兩個基本權限:讀文件,上傳文件。上一篇里,因為權限問題,寫文件的時候斷電了。試想畢竟是JAVA,一門龐大的語言,真的無懈可擊么?這次我們讀個東西試試。
Start代碼:
控制臺打印出:
不能讀文件,連最基本的“判斷文件是否存在”都過不去。
讀都不行,更別說執行了?
控制臺打印出:
不能執行,文件相關操作都控制的死死的。好吧,我不奢求直接用java控制文件了。記得在玩注入時,可以調用ACCESS等數據庫的引擎去寫文 件。如果可以在applet中訪問數據庫,那有意思了,一樣可以做些什么。間接訪問文件,只要沒有控制applet訪問JDBC驅動的權限,就能執行 sql。
再看看結果:
又是失敗,也就是說,applet控制了訪問其他packet中的內容,只準訪問自己內定的包,外部驅動不能用。我所知道的方法基本上都測試了,或許還有,但是這個層面上,最具代表性的都試了,其他的(跨域發送socket包等等)就不拿出來一一說明了。
第三部分 對瀏覽器的操作
幾天前看到一篇文章,提到“鬼域”,也就是“鬼頁”。文中提到可以控制子窗口內部FRAME,IE6可以控制子窗口執行JS,但是IE7,FF不能做。那么用applet來執行的結果,和這篇文章的內容對比,可以多做些什么,而又不能實現什么呢?
netscape.javascript.JSObject類可以在applet中調用JS,該類是個抽象類。這個類構造方法是 protected的,也就是說,不能直接new出來,只能由子類new,調用其中的靜態方法“getWindow(Applet applet)”返回它的一個實例。通常我們使用的時候,這樣的設計,就限制了必須要有個applet執行時才可以實例化這個類,也就是當瀏覽器加載 applet時才可以實例化JSObject。其中的eval方法顧名思義是執行js代碼的,applet都能做,只是在頁面上看不到JS代碼而已,當 然,在js中也可以調用applet的方法。這就有個安全隱患了,如果程序僅僅限制了<script>標簽,那么使用applet,一樣可以 達到繞過限制調用JS。當然如果直接限制了“<”,那也沒轍。
下面是一般調用applet的html代碼:
只要貼在HTML頁面,就能執行applet,CLASS文件是applet小程序的代碼,如果用戶瀏覽器不支持JVM虛擬機,會打出中間的信息。
為了探究applet的安全性,本文拿那篇“淺析瀏覽器的跨域安全問題”一文的內容(沒看過的自己去百度,如果不看該文,下面的內容會很生澀),來做個問題的模板,用applet來實現文中提到的一些技術,并對比一下和JS的安全性差異。
首先是“偽協議”問題
引用文章內容:
這段代碼取得子窗體的域,如果兩個HTML文件在同一個域,就可以做很多事情,比如用“AJAX”技術把該頁面的敏感信息提交到另一個頁面,并且只有同域下的iframe才可以控制父頁面。如下面這段JS,只能在同域下的iframe中執行。
為了做對比,使用Applet來實現偽協議的效果:
這段代碼第一行會彈出新的窗口,窗口名稱為“kxlzx”(在程序中可以使用“kxlzx”訪問彈出的窗口),第二行會在“kxlzx”這個窗口中繼續顯示"javascript:alert(document.domain)"。訪問頁面 http://192.168.0.3/test.htm,IE7和FF都彈出了“192.168.0.3”。請注意,這種情況發生在“當前頁面和彈出頁面都在同一個域”下。
父頁和子頁的關系
引用“淺析瀏覽器的跨域安全問題”一文的代碼:
再次使用applet實現以上效果:
IE和FF都執行成功,子窗口先訪問了sohu,過5秒,訪問了sina,子頁將永遠受制于父頁。
域與域之間的牽絆
那么不同域會出現什么情況呢?
這段代碼和前面第一節部分唯一的差別是,打開了http://192.168.0.3/test2.htm(父窗體)頁面后,父窗體的applet控制子窗體訪問到了另一個域“192.168.0.2”中。執行結果,IE拒絕訪問,FF卻彈出了
奇怪,分明是讓子窗體去訪問"javascript:alert(document.domain)",怎么會彈出父窗體的域名呢?更詭異的是,彈出框的title上居然寫著 “來自192.168.0.3的頁面說:”。猜測這個問題有兩種可能:
1、子窗口(http://192.168.0.2/php.php)仍然認為自己屬于父窗體的域(192.168.0.3)。
2、這個框(JS)根本就是由父窗體調出來的。
為了證明域的問題,我寫了段JS來判斷,在子窗體的頁面中,寫段AJAX,讓他去給父窗體送點東西。如果同一個域,就能拿,如果不同域會拒絕訪問。
幾經測試,寫出了可以通過的代碼:
請注意變紅的地方!代碼會先控制子窗體打開頁面,然后控制子窗體執行一段ajax代碼訪問a.asp。a.asp文件的作用是接收 context變量,然后把它的值保存在本地一個kxlzx.txt的文件里。從kxlzx.txt文件內容來看,執行成功了。也就是說,這段ajax成 功的訪問了位于192.168.0.3上的文件a.asp,并提交了參數。
這時的我非常興奮!跨域“0day”?!!別高興的太早,還有種可能就是父窗口執行了ajax。為了進一步擴大戰果和分辨父子窗體,我立刻修改 js,讓他把cookie傳過去,修改代碼中傳遞參數的值為 “a.asp?context=aa'+document.cookie+document.getElementById(‘who’)”。然后修改子 窗體訪問的php.php:
再修改父窗體訪問的頁面(加載applet的頁面test2.htm):
這兩段有什么用呢?首先是cookie問題,如果單純靠兩個頁的cookie判斷,可能達不到效果,別忘了他們的域是一樣的,很可能兩個頁面cookie都是test2.htm的cookie。但是再加個input就不一樣了,input的值可不會因為域而改變。
這樣,不同的頁面所調用ajax的結果就有所區別。測試結果很詭異,我在kxlzx.txt中只找到了test2.htm的cookie,沒有后面緊跟的input的值。兩個頁面都有input,怎么會拿不到值?打開ff的錯誤控制臺,看到了如下錯誤:
執行這段js的頁面根本就沒有這個input!兩種解釋:
1、還有個頁面偷偷執行了這段ajax,然后消失的無影無蹤。
2、這段JS在第二個頁面(子窗體)中執行,但是執行的時候子窗體還沒有訪問php.php。
至少不可能是test2.htm執行了js,如果他執行js,一定能拿到“who”的值,input在applet之前就加載了。無論是哪種可 能,跨域 0day夢,宣告結束。父窗體不能讓子窗體執行腳本,只能讓他訪問一些頁面。好吧,你狠!不過,我們回到一個話題來:“為什么要讓子窗體執行腳本?”,很 顯然,我們想要子窗體的cookie。
整理思路:
1、父窗體可以控制子窗體到處訪問。
2、父窗體不能讓子窗體執行腳本。
3、我們想拿子窗體的cookie。
4、只有同一個域下,才能取cookie。
你應該感到有趣才是,因為作者不可能把一段廢話一一列舉在這里,你能想到什么呢?公布答案!假設我們能控制父窗體的代碼,想要子窗體的cookie步驟:
1、我們可愛的IE瀏覽器打開/Article/UploadFiles/200808/20080808105155534.jpg時,如果 jpg里面其實是js,發生什么?很好!會執行JS!步驟一的關鍵就是,往子窗口的域名下(網站),傳一個jpg文件,里面是JS代碼。Js代碼用來:獲 取cookie,然后使用AJAX 技術將cookie提交到同一個域的某個能儲存東西的地方,比如留言本。
2、既然要獲取cookie,那瀏覽器至少要有子窗體的cookie,比如他登錄過就會有cookie。讓父窗體先打開子窗體的kxlzx.jpg,一秒,閃一秒就足夠代碼執行了,之后的事情就不用我說了。
如果步驟一的條件有出入,沒有可以儲存東西的地方,你可以嘗試以下代碼繞過AJAX的跨域限制:
以上步驟不僅僅可以應用于applet,還可以在js中實現。可以實現以上步驟的代碼,本文已經寫的夠多了,請在樓上找吧。
作者技術有限,目前研究到這里,給大家個研究方向:往applet底層實現進發,研究能繞過applet權限的函數,去年就出了一個。實踐出真 知,作者的研究思路一定不是最好的,甚至文中或許還會有錯誤,但是文中代碼都是作者通過無數次實踐,才精挑細選出了最能說明問題的部分,希望能對大家有所 幫助。
最后發幾個小技巧:
1、跨域調用class文件。突破XSS的時候,如果不能上傳class文件(通常都不可以),就可以把class文件放在其他地方。把class文件放在其他服務器上調用,有了這個功能,更利于我們沒有限制的跨域調用class文件。
2、調試的時候,如果編譯好了class文件,之后修改類,又重新編譯了class文件,一定要關閉瀏覽器重新打開,才能看到新的效果。因為瀏覽器有緩存,同樣會緩存class文件,如果不清空緩存或重新打開瀏覽器,就等于使用了原來的class文件。
3、調試的時候,一定要仔細考慮到整個流程執行順序,特別是當你以為自己不小心發現“0day”的時候。
4、最后提醒,applet只能執行在JVM環境中。
參考文獻:
《淺析瀏覽器的跨域安全問題》 Ph4nt0m Security Team rayh4c
《Java security evolution and concepts, Part 3: Applet security》 Raghavan N. Srinivas
《Applet Security》 SUN官方
《Java 2 Applet Security》 Abdul Habra, 2.7.2000
《JDK幫助》
附件說明:
a.asp ------- 接收變量,保存內容為kxlzx.txt的頁面
Applet_ODBC.java -------- 使用applet鏈接access數據庫的代碼
Applet_Control_Open.java -------- 父窗體控制子窗體到處訪問的代碼
Oday.java ---------- 第一部分提到的0day
ReadFile.java -------- applet讀文件
writeFile.java --------- applet寫文件
Xss.java ----- 控制子窗口彈cookie
test2.htm ------ 文中提到的加載applet頁面
php.php ----- 沒有這個文件,因為它代碼改來改去的,文中找吧。
文中提到的附件下載地址:
http://www.inbreak.net/attachment.php?id=5
|
新聞熱點
疑難解答