便利檔案上傳的網路應用程式已成為許多組織的必要工具,可作為客戶、合作夥伴和員工分享各種類型檔案和檔案的入口網站。例如,人力資源公司可以讓使用者上傳履歷,公司也可以讓合作夥伴透過專門的網路平台更容易分享檔案。
即使有增強的安全措施和更嚴格的驗證程序,攻擊者仍繼續使用複雜的方法來利用漏洞。看起來是良性的檔案,例如圖片,也可以被篡改來危害網頁伺服器的安全性。
多重檔案是可以同時作為多種類型有效的檔案,讓攻擊者可以繞過以檔案類型為基礎的安全措施。範例包括 GIFAR(可同時作為 GIF 和 RAR 檔案)、JavaScript/JPEG 多重檔案(可同時解釋為 JavaScript 和 JPEG),以及 Phar-JPEG 檔案(可同時識別為 Phar 存檔和 JPEG 影像)。這些多重檔案可以透過欺騙性或空白的副檔名而不被偵測到,這些副檔名會「欺騙」系統,讓系統以為它們是良性檔案類型 (如影像或 PDF),但內含未被偵測到的惡意程式碼。
檔案上傳驗證
允許使用者在沒有適當或全面驗證的情況下上傳檔案,會對網路應用程式造成重大威脅。如果攻擊者成功上傳惡意檔案 (例如 web shell),就有可能取得伺服器的控制權,危及系統和敏感資料。為了降低這些風險,我們建立了最佳實務來引導開發人員應用有效的驗證措施。這些實務有助於確保檔案上傳的安全處理,從而最大限度地降低被利用的風險。
確保檔案上傳安全的重點領域包括
- 擴充碼驗證:實作檔案副檔名的 blocklist 或 allowlist,以確保只接受允許的檔案類型。
- 檔案名稱淨化:上傳時為檔案名稱產生隨機字串。
- Content-Type Validation(內容類型驗證):驗證上傳檔案的 MIME-type 以確保符合預期格式。
- 圖片標頭驗證:對於圖片上傳,可以使用 PHP 中的 getimagesize() 等函數,透過檢查其標頭來確認檔案的有效性。
檔案上傳過濾器繞過
儘管實施了這些保護措施,攻擊者仍不斷改進其方法,以繞過驗證機制。空字元注入、雙副檔名和空副檔名等技術可以破壞副檔名的驗證:檔案可能會以「file.php.jpg」、「file.php%00.jpg」、「file.PhP」或「file.php/」等名稱出現,以逃避偵測。MIME 類型驗證可透過修改檔案的初始魔法位元組 (magic bytes) 來規避,例如將其變更為 GIF89a (與 GIF 檔案相關的標頭),這會誘騙系統將檔案識別為合法格式。此外,惡意的 .htaccess 檔案可以上傳以操控伺服器設定,允許執行未經授權擴充的檔案。
多重檔案攻擊
即使實施了結合多重安全措施的嚴格驗證程序來防止檔案上傳過濾器繞過技術,針對多重檔案或多重影像的複雜攻擊仍然是一個重大的安全威脅。此方法可讓攻擊者製作符合影像檔案預期二進位結構的檔案 (例如影像),但在不同的上下文中解釋時,可同時執行惡意程式碼。這些檔案的雙重性讓攻擊者可以繞過傳統的驗證機制,並利用特定情境中的漏洞。
使用 ExifTool 的簡單多語言檔案
利用 ExifTool 是產生多元圖像的簡單技術。這個功能強大的應用程式可讀取、寫入和修改各種元資料格式,例如 EXIF、XMP、JFIF 和 Photoshop IRB。然而,惡意的人可能會利用 ExifTool 執行有害的動作,包括建立具有惡意意圖的多重圖像。藉由使用 ExifTool 將惡意程式碼嵌入影像的 EXIF metadata,尤其是 UserComment 和 ImageDescription 等欄位,攻擊者就能產生多重影像,並增加成功入侵的機會。
以下介紹影像的 EXIF 元資料,提供與影像相關的全面資訊。
利用 ExifTool,威脅份子可以在影像的 EXIF 元資料中嵌入惡意程式碼,從而建立一個可規避驗證機制的多重檔案。
儘管 MIME 類型驗證可以限制基本 Web shell 檔案的上傳,但此 polyglot 映像可以繞過這些限制,允許攻擊者上傳 polyglot Web shell。
攻擊者可隨後利用 polyglot Web shell 來控制 Web 伺服器。
Javascript/JPEG 多語言檔案
JavaScript/JPEG 多重檔案的結構是既可作為 JPEG 影像,也可作為 JavaScript script。為了達到這個目的,惡意行為者必須全面瞭解 JPEG 檔案的內部結構。這種知識可以將惡意的二進位資料精確地嵌入影像中,確保它可以被 JavaScript 引擎處理,而不會影響其作為 JPEG 影像的有效性。
JPEG 影像具有以下結構:
位元組 | 名字 |
0xFF、0xD8 | 影像開始 |
0xFF, 0xE0, 0x00, 0x10, ... | 預設標頭 |
0XFF, 0XFE, ... | 圖片評論 |
0xFF, 0xDB, ... | 量化表 |
0xFF, 0xC0, ... | 畫面開始 |
0xFF, 0xC4, ... | Huffman 表 |
0xFF, 0xDA, ... | 開始掃描 |
0xFF、0xD9 | 圖片結束 |
在 JPEG 影像結構中,標頭之後是長度資訊。如前一個範例所示,標頭以序列0xFF 0xE0 0x00 0x10 開始,其中0x00 0x10特別代表該區段的長度,表示 16 位元組。標記0xFF 0xD9標示影像的結束。
若要建立 JavaScript/JPEG 多重檔案,必須修改影像的十六進位值,以確保 JavaScript 引擎能辨識並處理這些值。
首先,在 JavaScript 中,序列0xFF 0xD8 0xFF 0xE0可以解釋為非 ASCII 值,但0x00 0x10 是無效的,必須更改。適合取代這些十六進位值的是0x2F 0x2A,也就是 /* 的十六進位表示法,這是 JavaScript 中用來開啟註解的語法。此取代方式可將剩餘的二進位資料忽略為註解的一部分。
然而,由於0x00 0x10原本代表 JPEG 標頭的長度,將其變更為0x2F 0x2A,十進位等於 12074,需要重新定義 JPEG 標頭以維持其有效性。為了達到這個目的,需要加入空位元組,JavaScript 的有效負載應該放在0xFF 0xFE標記之後,這個標記表示 JPEG 結構中的影像註解。
例如,如果有效負載為*/=alert(document.domain);/*,長度為 28 位元組,所需的空位元組計算如下:12074 (新長度) - 16 (原始標頭長度) - 2 (0xFF 0xFE標記) - 28 (有效負載長度) = 12,028 個空位元組。
因此,JPEG 影像中的 JavaScript 程式碼會與下列內容相似:
最後,序列0x2A 0x2F 0x2F 0x2F(對應於 *///)必須放在 JPEG 結束標記0xFF 0xD9 之前。此步驟會關閉 JavaScript 註解,並確保有效負載被正確執行,而不會擾亂 JPEG 檔案的結構。
經此修改後,影像仍可被詮釋為有效的影像,同時包含可執行的 JavaScript 程式碼。
當 HTML 檔案將此影像載入為 JavaScript 原始碼時,它仍會保持有效,並可執行內嵌的 JavaScript 程式碼:
多重圖像檔案不僅會帶來客戶端攻擊的風險,在特殊情況下也會造成伺服器端攻擊的風險。Phar/JPEG polyglot 檔案就是一個例子,它既可被解釋為 PHP 存檔 (Phar),也可被解釋為 JPEG 影像。Phar 檔案結構允許在元資料中嵌入序列化資料,這構成了反序列化漏洞的潛在風險,尤其是在某些 PHP 版本中。因此,Phar/JPEG 多重檔案可被利用來繞過檔案上傳驗證,並利用易受攻擊的伺服器。
Phar 檔案格式以存根 (stub/manifest/contents/signature) 的方式編排,並在清單中儲存 Phar 存檔所包含內容的重要資訊:
- 存根:存根是在可執行上下文中存取檔案時執行的 PHP 程式碼。對存根的內容沒有限制,除了它必須以 __HALT_COMPILER(); 結尾。
- Manifest:本節包含有關存檔及其內容的元資料,其中可能包括以 serialize() 格式儲存的序列化 Phar 元資料。
- 檔案內容:存檔中包含的原始檔案。
- 簽名(可選):包含完整性驗證的簽章資訊。
由於存根並未在 __HALT_COMPILER() 的規定之外施加任何內容限制,因此威脅者可以將影像的十六進位值注入存根。將這些值放在 PHAR 檔案的開頭,就可以識別為有效的影像。因此,只要在開頭附加 JPEG 影像的十六進位元組,就能輕鬆地建構 PHAR/JPEG polyglot,如以下範例所示:
透過此方法,所產生的 polyglot 檔案同時具有有效影像和合法 PHAR 檔案的功能,因此可以用來繞過某些檔案上傳驗證機制。
雖然此 polyglot 檔案可繞過檔案上傳過濾器,但目前無法入侵網路伺服器。若要使用 PHAR 檔案或 PHAR polyglot 檔案成功入侵網路伺服器,就必須在檔案的清單中注入惡意序列化的元資料。
當 PHAR 檔案在某些與檔案作業相關的 PHP 函式 (PHP ≤7.x) 中,例如 file()、file_exists()、file_get_contents()、fopen()、rename() 或 unlink(),透過 PHAR wrapper (phar://) 被存取時,會觸發 unserialize() 函式來處理序列化的元資料。最後,透過利用 PHPGGC (一種廣泛使用的 PHP 小工具鏈建構工具),威脅份子可透過 PHAR polyglot 檔案利用反序列化漏洞,進而入侵 網路應用程式伺服器。
PHAR/JPEG polyglot 檔案與反序列化漏洞的結合,讓攻擊者有能力滲透網路應用程式伺服器,即使已實施檔案上傳過濾器。值得注意的是,即使是在處理影像檔案的過程中,也可能發生這種攻擊。
透過利用 polyglot 檔案繞過檔案上傳過濾器,並在檔案位置附加 PHAR wrapper (phar://),攻擊者可操控網頁伺服器將檔案當作 PHAR 存檔。此操作可隨後引發反序列化漏洞,導致透過檔案操作功能執行遠端程式碼。
為了傳達應用程式中與 polyglot 檔案相關的風險,我們模擬了一個應用程式採用嚴格檔案上傳過濾器的環境,以防止惡意檔案或 web shell 上傳。儘管有這些防護措施,polyglot 影像仍可繞過驗證程序,並在某些情況下可能導致遠端程式碼執行,最終危及易受攻擊的 網路應用程式伺服器。
本範例說明一個可讓客戶、合作夥伴和組織之間共用檔案的傳統 網路應用程式:
MetaDefender Core 和MetaDefender ICAP Server 保護您的 網路應用程式免受這些威脅,並加強網路和基礎架構的安全性。
MetaDefender ICAP Server 和MetaDefender Core 攜手合作,以下列方式保護您的 Web 伺服器,抵禦涉及惡意 PHAR/JPEG 多檔案的複雜攻擊:
當 PHAR/JPEG 多重檔案上傳至 網路應用程式時,首先會透過MetaDefender ICAP Server 轉送至MetaDefender Core ,使用我們的Deep CDR ™ 技術進行全面的淨化處理。與簡單的檔案類型檢查器不同,Deep CDR 會徹底分析上傳檔案的結構,移除腳本、巨集和超出政策範圍的內容,重新建構 JPEG 檔案,使其只包含必要的資料。
此過程會移除附加在 JPEG 結尾標記(0xFF 0xD9) 之後的有害 PHAR 內容,確保經過淨化的檔案嚴格來說是 JPEG。因此,網路應用程式可防止 PHAR/JPEG 多重攻擊;即使攻擊者能改變檔案處理方案以注入 PHAR wrapper,他們也無法利用 Web 伺服器。
擁有既有網路安全基礎架構的組織,不論是使用 WAF(網路應用程式防火牆)、代理伺服器或入口控制器,現在都可以透過MetaDefender ICAP Server 來強化其防禦機制。此解決方案在現有 Web 伺服器與MetaDefender Core 之間建立介面,為所有傳入檔案建立透明的安全檢查點。任何經由ICAP 介面傳送的內容在到達您的網頁伺服器之前,都會先經過掃描與處理,以確保只有安全且合法的內容才會進入您的網路並傳送給終端使用者。
這種方法意味著組織可以充分利用其現有的安全投資,同時增加一個額外、強大的保護層。使用 NGINX 入口控制器的組織可以透過代理設定,將MetaDefender ICAP Server 與現有的基礎架構整合。
OPSWAT的方法超越了傳統的威脅偵測。MetaDefender Core 並非簡單地標示可疑檔案,而是主動解除潛在威脅,將危險檔案轉換為安全可用的內容。當與您的 Web 伺服器整合時,MetaDefender ICAP Server 可針對零時差威脅和多重攻擊提供全面保護。
以「不信任任何檔案。Trust no device.™ 」的理念,OPSWAT 在您基礎架構的每個層級,以專利技術解決全球客戶的挑戰,保護您的網路、資料和裝置,並防止已知和未知的威脅、零時差攻擊和惡意軟體。