【Windows 小知識】PE Section 大小

我們今天就來看這個 PE 的 Section 中 Raw Size 和 Virtual Size 的差別。
你可能會發現說大部分 Raw Size 會比 Virtual Size 還要大,這是為什麼呢?

要理解這一點,我們要先理解 Alignment 的概念。
每當系統在分配記憶體的時候,都需要進行 Alignment,確保記憶體位址是某個數值的倍數,這樣做不僅可以避免掉不少的麻煩,也讓記憶體管理變得更加簡單且直覺。

PE 的 Optional Header 中有定義兩種 Alignment

  • File Alignment: Raw Size 對齊的大小,預設是 0x200
  • Section Alignment: Virtual Size 對齊大小,預設是 0x1000

因此,回來看 Section 的大小會發現,PE 裡面寫的 Raw Size 其實是已經經過 File Alignment 處理過的大小,都是 0x200 的倍數。而 Virtual Size 是原始沒有進行 Section Alignment 處理的大小。

舉個上面那張圖的例子來看,程式跑起來的時候,.rdata 實際在記憶體中分配的大小是 0x2000 (0x1242 進行 Section Alignment 對齊 0x1000 完的結果),所以 .rdata 在記憶體的實際大小反而是比 Raw Size 大,而這些多出來的空間其實就是駭客最喜歡放 shellcode 的風水寶地啦xD

Read more

【Windows 小知識】檔案總管的排序規則

首先,先讓 ChatGPT 幫我開場一下,我覺得他腦補得好像還不錯xD

ChatGPT 小故事時間

曾經好奇過,當我們在 Windows 檔案總管中觀察文件列表時,是什麼魔法使它們按照這樣一個特定的順序排列的嗎?嗯,這就是我要告訴你的故事:一個叫做 StrCmpLogicalW 的神秘 Windows API 的故事。

想像一下,有一天,Windows 開發者們圍坐在一起,思考著如何讓檔案總管的排序更符合用戶的直覺。你看,當用戶看到 “img10.jpg” 和 “img2.jpg” 這兩個文件時,他們自然會認為 “img2.jpg” 應該在 “img10.jpg” 之前,即使從字母順序上看,“10” 確實是在 “2” 之前。但是,人們不是機器,我們的大腦認為 2 小於 10。這就是 Windows 開發者們需要解決的問題。

於是,StrCmpLogicalW 這個 API 應運而生。

我是某一天在找我的樣本的時候才發現這個神祕的排序
因為樣本大多是用檔案的 hash 當作檔名,所以會長的像下面這樣

1
2
3
4
5
6
7
8
9
10
11
1c8bb52633d0861e2137a984048bd224
4adc8224eb736aa10e168390ac8cc251
05ece5d005502c211d57c5028fcce17e
7c30d3db6f1a28c08a21fbf1bccf771f
9f6fc22fd9c97e68eda4e707e6200849
29d0984f03fd2cce2f57b17005ab8e0e
58f75d29b3675cadf8f4f25be1275838
0524df255a48254e8a7a39a20d7328e3
ae2219b53716336c3bb26f8a5ff693c0
d4a0c7c5ff0e88f31167a91085539fdd
d300c7c5ff0e88f31167a91085539fdd

一般正常排序會用字典序(Lexicographic order),所以第一個字母排起來應該要是 0, 0, 1, 2, ... 照順序排,但我們看到上面的例子,在檔案總管裡面,他是排成 1, 4, 0, 7, ... 這個奇怪的順序,到底在排什麼,我一開始注意到就是各種問號,後來查一查才發現他是用 StrCmpLogicalW 這個神祕的 Windows API 去比較兩個字串,這篇有比較細節的去介紹其中的機制,比官方文件詳細。

StrCmpLogicalW 在比較的時候是用 meta-character 當做單位,meta-character 有分三種

  • .
  • 數字
  • 其他字元

這三大類之間的排序是 . < 數字 < 其他字元,之後才是比較大類裡面的大小
重點就是這裡的數字是把整串的數字當作一個數值在比較
比如 29d0 就是把前面兩個數字當作 29 這個數值比較,所以 9f6f < 29d0 (9 < 29)
之所以要這樣排,應該跟 ChatGPT 介紹得差不多,為了讓一般使用者看起來更直覺,像是 img1.jpg, img2.jpg, …, img10.jpg 就會照 1, 2, 3, ... 的順序排了,就不會因為用字典序排,所以變成先 1, 10, 11, ... 1 開頭的排完才換 2 的 2, 20, 21, ...,這種一般使用者比較不習慣的排法。


Read more

【漏洞分析】CVE-2022-41049

11/08 Windows 的 Patch Tuesday 中修補了兩個關於 Bypass Mark-of-the-Web (MOTW) 的漏洞,分別是 CVE-2022-41049 和 CVE-2022-41091,在 Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049) 這篇部落格中,有詳細的分析這個漏洞的細節,也是本篇部落格主要參考的來源

這個漏洞最早在 6 月在 twitter 上 Will Dormann 的貼文中 就有提及
並且在 10 月就有在野外觀察到這個漏洞被利用

Alternative Data Stream (ADS)

要解釋這個漏洞之前,要先說明一下什麼是 Alternative Data Stream (ADS)
ADS 是 NTFS 檔案系統的一個功能,允許一個檔案可以有多個 Stream,也就是雖然檔名是一樣的,但是透過不同的 Stream 可以存取到不同的資料
比如 test.txt 這個檔案可以有好幾種不同的 Stream

  • test.txt::$DATA
  • test.txt:Zone.Identifier
  • test.txt:Hello
  • test.txt:World

MOTW

瀏覽器會把從網路下載下來的檔案,新增一個 Zone.Identifier 的 Stream,這就是傳說中的 Mark-of-the-Web (MOTW)
我們可以用 Powershell 下指令 Get-Item <filename> -Stream * 來列出某個檔案的所有 Stream 如下圖所示

接著用 Get-Content <filename> -Stream Zone.Identifier 去印出 Zone.Identifier Stream 裡面的資料如下圖所示

可以看到 Zone.Identifier Stream 裡面存了 ZoneIdHostUrl 這些 metadata

那有 MOTW 的檔案可以做什麼?
有 MOTW 的檔案就等於給其他軟體們一個資訊,這個檔案是來自網路,像是 WORD, EXCEL, Visual Studio 等軟體以及 Windows 本身,在處理這些檔案的時候就會格外小心,並且對使用者發出額外的警告,像是如下圖的這些警告

CVE-2022-41049

背景知識都補充足夠了,那這個 CVE-2022-41049 的漏洞又是出了什麼問題
正常情況中,檔案總管 (Explorer) 在解壓縮 zip 的時候,會把 zip 檔案的 MOTW 複製到解壓縮出來的所有檔案上面
但是只要那個 zip 檔案是用某個特別的方法製作的時候,MOTW 就不會被傳遞下去,也就成功 Bypass MOTW

這個特別的製作方法,說起來也不是那麼特別,其實也是正常的 feature
只要你的檔案在壓縮的時候是 read-only 的
在解壓縮的時候,因為檔案是 read-only 的關係,所以檔案總管就無法去寫入 MOTW 到解壓縮出的檔案上面
就是這麼簡單,非常簡單就可以實作

這篇 Exploring ZIP Mark-of-the-Web Bypass Vulnerability (CVE-2022-41049) 部落格中,作者做了非常深入的調查,最後才發現只是這麼簡單的原因,原文分析的思路也推薦大家可以看看
除了 zip,其他的打包格式比如 iso, vhd, gzip 等,也是新的 bypass MOTW 的方法
整體來看,Mark-of-the-Web (MOTW) 其實不算是一個 Security Boundary,比較像是一個額外的警告功能,使用者在下載網路上的資源的時候還是要謹慎小心,多看幾眼xD


  1. https://breakdev.org/zip-motw-bug-analysis/
  2. https://www.ithome.com.tw/news/154096
Read more