新聞中心
【.com獨家特稿】隨著惡意PDF文件日益增多,人們對這種文檔的惡意代碼分析技術也越來越感興趣。本文將教您如何分析一種特殊類型的惡意PDF文件:它們可以利用內嵌JavaScript解釋器的安全漏洞。通過閱讀本文,還有助于分析其他類型的惡意PDF文件,如利用PDF解析器內的安全漏洞的情形。雖然幾乎所有的惡意PDF文檔的攻擊目標都是Windows操作系統(tǒng),但是這里介紹的PDF語言是獨立于操作系統(tǒng)的,它同時適用于在Windows、Linux和OSX上的PDF文檔。

一、PDF中的Hello World
現在,我們從手工制作一個最簡單的PDF文檔開始入手,該文檔只是在一個頁面中顯示文字Hello World而已。您很可能從未見過如此簡陋的文檔,但是它很適合于本文的需要,因為我們只對一個PDF文檔的內部構造感興趣。我們的文檔僅僅包含顯示一個頁面所必需的最基本元素,如果您為該文件添加更多的格式的話,可讀性會更好一些。該文檔的特性之一是,只包含有一些ASCII字符,因此即使使用記事本這樣最簡單的編輯器,同樣也能閱讀它的內容。另一個特性是,其中含有大量(多余的)空格和縮排,這使得這個PDF的結構更加突出。最后一個特性是,其中的內容沒有進行壓縮處理。
二、頭部
每個PDF文檔必須以標明其為PDF文檔的一行代碼(即幻數)開頭;它還規(guī)定了用于描述這個文檔的PDF語言規(guī)范版本號:%PDF-1.1。
在一個PDF文檔中,以符號%開頭的行都是注釋行,注釋行的內容將被忽略,但是有兩個例外:?
文檔的開頭:%PDF-X.Y?
文檔的結尾:%%EOF
三、對象
在第一行之后,我們開始為我們的PDF文檔添加對象,對象是PDF語言的基本元素。這些對象在文件中的出現順序對頁面顯示時的布局沒有任何影響。不過為簡單起見,我們將按照邏輯順序來介紹這些對象。需要注意的是,PDF語言是大小寫敏感的。
我們首先介紹的是catalog(即目錄)對象,它告訴PDF閱讀程序(例如Adobe的Acrobat Reader),為了裝配這個文檔,需要從哪里開始查找對象:
這實際上是一個間接對象,因為它具有一個編號,并且可以通過該編號來引用該對象。其語法很簡單:一個編號、一個版本號、單詞obj、對象本身,最后是單詞endobj,如下所示:
通過聯(lián)合使用對象編號和版本號,我們就能夠唯一地引用一個對象。
我們第一個對象catalog的類型是字典類型,字典類型在pdf文檔中非常常見。該類型以符號<<開頭,并以符合>>作為結束,如下所示:
字典的元素由鍵和值兩部分組成,也就是說一個元素就是一個名/值對,即數據有一個名稱,還有一個與之相對應的值;字典不僅可以存放元素,而且還能存放對象甚至其他字典。 大部分字典都是利用第一個元素來聲明自身的類型,該元素以/type為鍵,其后跟一個類型本身的名稱(對本例而言就是/Catalog)為值:
對象catalog必須給出在這個PDF中能找到的頁面(對應于pages對象)和大綱(對應于outline對象),如下:
2 0 R和3 0 R 分別表示引用間接對象2和間接對象3。間接對象2描述大綱,間接對象3描述頁面。
下面開始為我們的PDF文檔添加第二個間接對象:
通過前面對間接對象1的說明,您現在應該對這個對象的語法并不陌生了。這個對象是一個/Outlines類型的字典。它具有一個鍵為/Count、值為0的元素,這意味著這個PDF文檔沒有大綱。我們可以通過編號2和版本0來引用這個對象。
讓我們總結一下我們的PDF文檔已有的內容:?
PDF標識行?
間接對象1:catalog?
間接對象2:outline
在添加文字頁面之前,讓我們演示PDF語言的另一個特性。我們的1號對象catalog引用了我們的2號對象outline,如圖1所示。
| 圖1 引用間接對象 |
PDF語言還允許我們把2號對象直接嵌入到1號對象中,如圖2所示。
| 圖2 被嵌入到對象中的間接對象 |
事實上,outline對象的長度只有一行,并且對語義也沒有什么影響,現在只是為了可讀性才加上。先不管它,我們繼續(xù)組裝我們的PDF文檔。我們前面定義了catalog(目錄)和outlines(大綱)對象,接下來還得定義我們的頁面。
除/Kids元素之外,下面的代碼應該很容易理解。Kids 元素是一個頁面列表;一個列表必須用方括弧括住。因此依據這個Pages對象來看,我們的文檔中只有一個頁面;這個頁面的具體規(guī)定,見間接對象4(注意引用4 0 R ):
要描述頁面,我們必須規(guī)定頁面的內容、用于顯示這個頁面的資源以及頁面的大小。這些任務可由下面的代碼來完成:
頁面內容是由間接對象5來規(guī)定的。/MediaBox 是頁面的尺寸。這個頁面所用的資源是字體和PDF文字繪制例程。我們在間接對象6中將字體規(guī)定為[F1]。
間接對象5中存放的是頁面內容,它是一種特殊的對象,即流對象。流對象可以用來保存由單詞stream和endstream包圍的對象內容。流對象的好處是允許使用多種類型的編碼技術(在PDF語言中稱為過濾器),例如壓縮(例如zlib FlateDecode編碼)。考慮到易讀性,我們沒有在這個流中實施壓縮處理:
這個流的內容是一組PDF文字繪制指令。這些指令是由BT和ET括起來的,實際上就是命令繪制例程做下面的事情:?
使用大小為24的F1字體?
轉到100 700位置處?
繪制文字:Hello World
在PDF語言中,字符串必須用圓括號括起來。
我們的PDF文檔已經基本上組裝好了。我們需要的最后一個對象是font(字體)對象:
現在,閱讀這個結構您應該沒有問題了。#p#
四、尾部
上面就是繪制一個頁面所需的全部對象。但是僅有這些內容還不足以使閱讀程序(即顯示pdf文檔的程序,如Adobe的Acrobat Reader)來讀取和顯示我們的PDF文檔。繪制例程需要知道文檔描述起始于哪個對象(即root對象),以及每個對象的索引之類的技術細節(jié)。
每個對象的索引稱為交叉引用xref,它描述每個間接對象的編號、版本和絕對的文件位置。PDF文檔中的第一個索引必須從版本為65535的0號對象開始:
標識符xref后面的第一個數字是第一個間接對象(這里是0號對象)的編號,第二個數字是xref表(7個表項)的大小。
第一欄是間接對象的絕對位置。第二行的值12表明間接對象1的起始地址距文件開頭為12字節(jié)。第二欄是版本,第三欄指出對象正在使用(用n表示)還是已經釋放(用f表示)。
定義交叉引用之后,我們在尾部中定義root對象:
不難看出,這是一個字典。最后,我們需要利用xref元素的絕對位置和幻數%%EOF來結束這個PDF文檔:
其中,644是在這個PDF文件內的xref的絕對位置。
五、PDF文檔基礎知識的回顧
我們一旦了解了PDF語言的語法和語義,就能輕松構建一個簡單的PDF文檔。為了便于閱讀,我們在清單1中給出了完整的PDF文檔。
清單 1 完整的PDF文檔頁面內容#p#
六、添加有效載荷
因為我們想要分析帶有JavaScript有效載荷的惡意PDF文檔,因此需要了解如何添加JavaScript代碼并設法使其運行。PDF語言支持為事件關聯(lián)相應的動作。舉例來說,當某個頁面被查看的時候,可以執(zhí)行相應的動作(例如 訪問一個網站)。我們感興趣的是在打開一個PDF文檔的時候執(zhí)行某個動作。通過為catalog對象添加一個/OpenAction鍵,我們可以讓PDF文檔在打開時無需人工介入就執(zhí)行某個動作。
當打開我們的PDF文檔的時候,間接對象7所規(guī)定的動作將被執(zhí)行。我們可以規(guī)定一個URI動作。一個URI動作能夠自動地打開一個URI,在我們這個例子中是一個URL:
七、內嵌的 JavaScript
PDF語言支持內嵌的 JavaScript。然而,這個JavaScript引擎在與底層操作系統(tǒng)的交互方面能力非常有限,所以根本沒法干壞事。 舉例來說,嵌入到一個PDF文檔的JavaScript代碼不能訪問任何文件。所以,惡意PDF文檔必須利用某些安全漏洞才能擺脫JavaScript引擎的限制來執(zhí)行任意的代碼。我們可以使用下面的JavaScript動作,在PDF文檔打開時添加并執(zhí)行一些JavaScript腳本:
下面的代碼將執(zhí)行一個向JavaScript調試控制臺顯示Hello的腳本:
#p#
八、安全漏洞的利用
去年,許多惡意PDF文檔利用了PDF的util.printf方法的JavaScript安全漏洞來發(fā)動攻擊。Core Security Technologies發(fā)表了一個通報,其中含有一個PoC,如下所示:
當這個JavaScript將被嵌入到一個PDF文檔并在(在 Windows XP SP2上使用Adobe Acrobat Reader 8.1.2)打開的時候,它將試圖執(zhí)行地址0x30303030的代碼而造成訪問越界。 這意味著,通過緩沖區(qū)溢出,執(zhí)行PoC將跳轉至地址0x30303030(0x30是ASCII字符0的十六進制表示法)(即PoC一執(zhí)行,控制流程(系統(tǒng)控制權)就交給0x30303030處的指令)。 因此要想利用該漏洞,我們需要編寫我們的程序(shellcode),當然該程序需要從0x30303030處開始執(zhí)行。
使用內嵌的JavaScript的問題是,我們不能直接寫內存。Heap Spraying(堆噴射)是一種較易獲得任意代碼執(zhí)行Exploit的技術手段。 每當我們在JavaScript中聲明字符串并為其賦值時,這個字符串就會被寫到一段內存中,這段內存是從堆中分配的,所謂堆就是專門預留給程序變量的一部分內存。 我們沒有影響被使用的那些內存,所以我們不能命令JavaScript使用地址0x30303030的內存。 但是如果我們分配大量的字符串,那么很可能其中的一個字符串分配的內存中包含了地址0x30303030。 分配許許多多的字符串稱為Heap Spraying(堆噴射)。
如果我們在堆噴射之后執(zhí)行我們的PoC,就很有可能得到一個從地址0x30303030之前的某處開始、從地址0x30303030之后的某處終止的字符串,這樣的話,該字符串中(起始于地址0x30303030)那些字節(jié)就會被CPU當作機器代碼語句來執(zhí)行。
但是,如何讓我們指定的字符串包含用來利用起始于地址0x30303030的機器指令的正確語句呢? 同樣,我們也無法直接完成這個任務;我們需要一種迂回戰(zhàn)術。
如果我們設法使一個字符串被CPU當作機器代碼程序(shellcode)來解釋的話,那么CPU將開始執(zhí)行我們從地址0x30303030開始的程序。 不過這個方法不太理想;我們的程序必須從它的第一條指令開始執(zhí)行,而不是從中間的某個地方開始執(zhí)行。為了解決這個問題,我們需要在程序前面填充大量NOP指令。 我們在用于堆噴射的字符串中存儲這個NOP-sled,繼之以我們shellcode。 NOP-sled是一個特殊程序,它的特性是每個指令的長度都是單字,而且每個指令都沒有時間的操作(NOP,即空操作 ),那就是說 CPU不斷執(zhí)行下一個NOP指令,如此下去直到它到達我們的shellcode并且執(zhí)行它(滑下NOP-sled)。
下面是一個堆噴射的范例,實際取自一個帶有NOP-sled和shellcode的惡意PDF文檔(參見 圖 3)。
| 圖3 JavaScript堆噴射 |
Sccs是帶有shellcode的字符串,bgbl是帶有NOP-code的字符串。
因為shellcode常常必須很小,所以它將通過網絡下載另一個程序(惡意軟件)并執(zhí)行它。對于pdf文檔來說,還有一種方法可用。第二階段的程序可以嵌入到PDF文檔,而shellcode可以從PDF文檔提取并且執(zhí)行。
九、分析惡意PDF文檔
事實上,所有的pdf文檔都包含非ASCII字符,因此我們需要使用一個十六進制編輯器來分析它們。我們打開一個可疑的PDF文檔,并搜索字符串JavaScript(參見圖 4)。
| 圖4 JavaScript 對象 |
雖然只是有一點用于格式化對象的空格,但是您應該認出PDF對象的結構:對象31是一個JavaScript動作/S /JavaScript,腳本本身沒有包含在這個對象中,但是可以在對象32(注意引用3 0 R)中找到。 搜索字符串“31 0 R”,我們發(fā)現對象16引用了對象31“/AA <> ”,以及一個頁面/Type /Page ,如圖5所示。
| 圖5 頁對象 |
/AA 是一個注釋動作,這意味著當這個頁面被查看的時候這個動作就會執(zhí)行。因此,我們知道:當這個PDF文檔被打開的時候,它將執(zhí)行一個JavaScript腳本。 讓我們看看這個腳本(對象32 )的樣子。
對象32是一個流對象,而且它是經過壓縮的(/Filter [/FlateDecode]),見圖 6。
| 圖6 流對象 |
為了對它進行解壓,我們可以提取二進制流(1154字節(jié)長),并通過一個簡單的Perl或者Python程序對它進行解壓。使用Python語言,我們只需要導入zlib,然后就可以對數據進行解壓了,假設我們已經將我們的二進制流存儲在data中了:
然而有一點非常清楚:那就是解壓后的腳本是惡意的,它會對函數collectEmailInfo中的一個安全漏洞加以利用,如圖7所示。
| 圖7 利用collectEmailInfo |
十、結束語
隨著惡意PDF文件日益增多,人們對這種文檔的惡意代碼分析技術也越來越感興趣。本文向讀者詳細介紹了如何分析一種特殊類型的惡意PDF文件:它們可以利用內嵌JavaScript解釋器的安全漏洞。當然,有了本文的基礎,在分析其他類型的惡意PDF文件,如利用PDF解析器內的安全漏洞的情形的時候,您也能觸類旁通。需要說明的是,雖然幾乎所有的惡意PDF文檔的攻擊目標都是Windows操作系統(tǒng),但是這里介紹的PDF語言是獨立于操作系統(tǒng)的,它同時適用于在Windows、Linux和OSX上的PDF文檔。
【.COM 獨家特稿,轉載請注明出處及作者!】
【編輯推薦】
- Adobe曝重大安全漏洞,小心打開PDF文件
- 看PDF和Flash中毒后快速解決方法
分享題目:深入淺出實戰(zhàn)攻防惡意PDF文檔
本文來源:http://m.5511xx.com/article/ccedidi.html


咨詢
建站咨詢
