MSDN系列(48)--NTFS Alternate Data Streams简介

admin 2022年4月27日00:58:45评论16 views字数 9603阅读32分0秒阅读模式
创建: 2022-03-17 11:21
更新: 2022-04-11 17:52
http://scz.617.cn:8/windows/202203171121.txt

目录:

    ☆ 前言
    ☆ NTFS ADS 操作手册
        1) 向"main stream"写入数据
        2) 新增ADS并写入数据
            2.1) 输出转向符">"
            2.2) powershell
            2.3) 其他方案
        3) 显示ADS
            3.1) dir /R
            3.2) streams from sysinternals
            3.3) Get-Item
        4) 查看ADS内容
            4.1) 输入转向符"<"
            4.2) Get-Content
        5) 复制ADS内容
            5.1) Get-Content + Set-Content
            5.2) Get-Content + WriteAllBytes
            5.3) 其他方案
        6) 删除ADS
            6.1) streams from sysinternals
            6.2) ren + type + del
            6.3) Remove-Item
            6.4) NTFS->FAT32->NTFS
            6.5) Win32 API DeleteFile
        7) notepad受限支持ADS
        8) 执行ADS中的PE
            8.2) wmic process call create
            8.6) psexec from sysinternals
            8.7) rundll32
            8.8) 利用ADS执行代码的其他讨论
        9) 附加在目录上的ADS
            9.1) 各盘根目录
    ☆ ADS的合法用途
        1) Zone.Identifier
        2) favicon
        3) Win32App_1
    ☆ 第三方工具
        1) streamtools
        2) GNU utilities for Win32
        3) AlternateStreamView
    ☆ 后记
    ☆ 参考资源

☆ 前言

本文在Win10企业版2016 LTSB 1607(OS Build 14393.4704)上测试。

NTFS ADS (Alternate Data Streams)当年是为了兼容Macintosh Hierarchical File System (HFS)而出场的,NT 3.1开始引入ADS。

文件、目录、根目录都可以有ADS。ADS与"main stream"共用DACLs,无权访问"main stream"时,也无权访问附在其上的ADS。目录可以有ADS,但目录没有"main stream"。

"A:B"存在歧义,OS为规避歧义,始终将之解释成A盘的B文件。若存在名为"A:B"的ADS,为访问它,比须带上路径,比如"A:B"。

WFP (Windows File Protection)会保护部分系统文件,但在过去,WFP不会阻止拥有相应权限的用户向这些受保护的系统文件追加ADS。sfc.exe (SFC/System File Checker)会检查受保护的系统文件,但不会检查附在其上的ADS。不知现在情况是否有变?

Windows Defender SmartScreen会检查ADS。

☆ NTFS ADS 操作手册

1) 向"main stream"写入数据

有个奇技淫巧,在cmd中echo,不出现结尾的rn,与本文无关,只是顺带演示

echo | set /p="unnamed data stream" > some.ext

2) 新增ADS并写入数据

2.1) 输出转向符">"

输出转向符">"支持ADS

echo | set /p="secret data stream 0" > some.ext:any_0
echo | set /p="secret data stream 1" > some.ext:any_1
echo | set /p="secret data stream 2" > some.ext:any_2

2.2) powershell

powershell -Command "Set-Content -Path '\?X:pathsome.ext' -Stream 'any_3' -Value 'secret data stream 3' -NoNewline"

2.3) 其他方案

下列命令或工具均是OS自带的,此处不罗列第三方工具

type some.exe > any.ext:some.exe
findstr /V /L Nonexist_Magic some.exe > any.ext:some.exe
expand some.exe any.ext:some.exe
esentutl /y some.exe /d any.ext:some.exe
powershell -Command "Get-Content -Encoding Byte -ReadCount 0 -Path some.exe | Set-Content -Encoding Byte -Path any.ext -Stream some.exe"
powershell -Command "&{(Get-Content -Encoding Byte -ReadCount 0 -Path some.exe | Set-Content -Encoding Byte -Path any.ext -Stream some.exe)}"
print /D:any.ext:some.exe some.exe

makecab some.exe tmp.cab
extrac32 /y tmp.cab any.ext:some.exe
del tmp.cab

不推荐print,无法完全保持PE原样,会多一个字节,但不影响执行。

type、findstr实际依赖输出转向符">",其余命令自身支持ADS。

3) 显示ADS

3.1) dir /R

从Vista开始dir有个/R开关可以显示ADS

$ dir /R some.ext

03/17/2022  11:51                19 some.ext
                                 20 some.ext:any_0:$DATA
                                 20 some.ext:any_1:$DATA
                                 20 some.ext:any_2:$DATA
               1 File(s)             19 bytes

注意最后一行,只显示"main stream"大小,19字节,未包含ADS大小。

3.2) streams from sysinternals

参[8]

$ streams some.ext

$ streams -s .

some.ext:
    :any_0:$DATA 20
    :any_1:$DATA 20
    :any_2:$DATA 20

这是sysinternals的工具之一,首行是"main stream",后面各行是ADS,最后一列是ADS大小,20字节。

3.3) Get-Item

powershell -Command "Get-Item -Path some.ext -Stream * | Where-Object Stream -ne ':$DATA' | Format-Table Filename,Stream,Length"
powershell -Command "Get-ChildItem | Get-Item -Stream * | Where-Object Stream -ne ':$DATA' | Format-Table Filename,Stream,Length"
powershell -Command "gci -Recurse | % { gi $_.FullName -Stream * } | where Stream -ne ':$DATA' | Format-Table Filename,Stream,Length"

gci、gi、where分别是Get-ChildItem、Get-Item、Where-Object的别名

4) 查看ADS内容

4.1) 输入转向符"<"

more不能直接访问ADS,但输入转向符"<"支持ADS

$ more < some.ext:any_2
secret data stream 2

type不支持ADS

type some.ext:any_2
The filename, directory nameor volume label syntax is incorrect.

很多工具不支持ADS,比如UltraEdit就不支持。

4.2) Get-Content

$ powershell -Command "Get-Content -Path some.ext -Stream any_2"
secret data stream 2

5) 复制ADS内容

先创建any.ext,其内空是一段文本;再向其追加ADS,其内容源自PE。

echo | set /p="unnamed data stream" > any.ext
type any.exe > any.ext:any.exe
dir /R any.ext

03/17/2022  17:24                19 any.ext
                            342,392 any.ext:any.exe:$DATA
               1 File(s)             19 bytes

假设在any.ext的ADS中隐藏了any.exe,现在想将any.exe还原出来。

下面这样干是不行的,因为ADS内容是二进制的、非文本的,more会破坏原始数据。

more < any.ext:any.exe > any_other.exe

看了一下more的帮助,没有保持raw格式的办法,至少Win10上如此。有人用源自Windows Resource Kit的cat,这不是自带工具,需要额外安装,此处不考虑。

5.1) Get-Content + Set-Content

Copy-Item不支持ADS,可以结合Get-Content、Set-Content复制ADS到普通文件

powershell -Command "Get-Content -Encoding Byte -ReadCount 0 -Path any.ext -Stream any.exe | Set-Content -Encoding Byte -Path any_other.exe"
dir /R any_other.exe

我的powershell不够新,不支持"-AsByteStream",只支持"-Encoding Byte",二者效果等价。"-ReadCount 0"表示一次性读取整个文件送往管道,缺省值是1。

5.2) Get-Content + WriteAllBytes

powershell -Command "[IO.File]::WriteAllBytes('any_other.exe', (Get-Content -Encoding Byte -ReadCount 0 -Path any.ext -Stream any.exe))"
dir /R any_other.exe

5.3) 其他方案

下列命令或工具均是OS自带的,此处不罗列第三方工具

expand any.ext:some.exe some_other.exe
esentutl /y any.ext:some.exe /d some_other.exe

6) 删除ADS

先新增名为any_3的ADS

echo | set /p="secret data stream 3" > some.ext:any_3

del可以删除"main stream",也就是some.ext,此时会一并删除附在其上的所有ADS。但是,del没法在保持"main stream"不变的情况下删除指定ADS,del不支持ADS语法。

6.1) streams from sysinternals

sysinternals的streams可以在保持"main stream"不变的情况下删除所有ADS,但做不到删除单个指定ADS。

streams的"-s -d"可以一起用,千万不要对着系统目录用。

6.2) ren + type + del

有一种方案,只依赖cmd内部命令,不依赖其他PE,变相实现保持"main stream"不变的情况下删除所有ADS。为接近实际用途,用二进制目标文件进行演示。

假设有PE文件any.exe,现对其追加3个ADS

echo | set /p="secret data stream 0" > any.exe:any_0
echo | set /p="secret data stream 1" > any.exe:any_1
echo | set /p="secret data stream 2" > any.exe:any_2

下列操作可以变相实现保持"main stream"不变的情况下删除所有ADS

ren any.exe waitdel
type waitdel > any.exe
del waitdel

any.exe只剩下"main stream"。该方案利用了type命令只访问"main stream"的特点,而ren、copy、move等命令会带着ADS。

6.3) Remove-Item

Remove-Item可以只删除指定ADS而保留其他ADS及"main stream"

powershell -Command "Remove-Item -Path some.ext -Stream any_3"

6.4) NTFS->FAT32->NTFS

NTFS支持ADS,FAT32不支持,从NTFS复制文件、目录到FAT32,将自动丢弃ADS,只复制"main stream"过去。然后再从FAT32复制回NTFS,变相实现保持"main stream"不变的情况下删除所有ADS。现在硬盘不太可能出现FAT32了,但很多U盘格成FAT32。

6.5) Win32 API DeleteFile

标准Win32 API支持ADS语法,可以编程删除指定ADS

DeleteFile( "X:\path\some.ext:any_3" )

7) notepad受限支持ADS

notepad some.ext:any_3

上述命令在ADS名未尾自动增加".txt"扩展名,实际创建"some.ext:any_3.txt",无法改变此行为。

下列命令实际去找"some.ext:any_2.txt",但找不到,问你要不要新建,换句话说,notepad无法访问"some.ext:any_2"。

notepad some.ext:any_2

很奇怪,对于some.exe,notepad可以创建、访问附在其上的ADS。

$ notepad "some.exe:Zone.Identifier"

[ZoneTransfer]
ZoneId=3

若some.exe无此ADS,上述命令可以创建ADS,若已有此ADS,上述命令可以编辑ADS。

8) 执行ADS中的PE

echo | set /p="unnamed data stream" > any.ext
type calc_xp.exe > any.ext:some.exe

特意使用源自XP的calc.exe,这个版本不存在calc.exe.mui的困扰,便于演示。

8.2) wmic process call create

wmic process call create X:pathany.ext:some.exe

Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ProcessId = 3980;
        ReturnValue = 0;
};

上述输出表示成功执行位于ADS中的PE,PID为3980,计算器弹出。

用wmic执行PE时,应该用绝对路径,不要用相对路径。

8.6) psexec from sysinternals

该法依赖非自带软件,不推荐

psexec -d any.ext:some.exe

计算器弹出。psexec支持相对路径。

8.7) rundll32

del any.ext
echo | set /p="unnamed data stream" > any.ext
type netplwiz_xp.dll > any.ext:some.dll

特意使用源自XP的netplwiz.dll,这个版本不存在netplwiz.dll.mui的困扰,便于演示。

在管理员级cmd中执行如下命令

rundll32.exe any.ext:some.dll,UsersRunDll

8.8) 利用ADS执行代码的其他讨论

参[9]

此处罗列了大量利用ADS执行代码的奇技淫巧。ADS内容可以是cscript、wscript所支持的脚本代码,二者支持ADS语法。如果考虑powershell介入,可能性更广。ADS内容是dll时,还有mavinject.exe可用。若有恶意需求,自行实践之。

9) 附加在目录上的ADS

向目录追加ADS

mkdir some.dir
echo | set /p="secret data stream 0" > some.dir:any_0
echo | set /p="secret data stream 1" > some.dir:any_1
echo | set /p="secret data stream 2" > some.dir:any_2

删除附加在目录上的ADS

streams -d some.dir

下面是另一组演示命令

cd /d X:pathsome.dir
echo | set /p="secret data stream 0" > :any_0
dir /R X:pathsome.dir
more < "X:pathsome.dir:any_0"

9.1) 各盘根目录

向X盘根目录追加ADS

echo | set /p="secret data stream 0" > X::any_0
echo | set /p="secret data stream 1" > X::any_1
echo | set /p="secret data stream 2" > X::any_2
dir /R X:

上述dir看不到附加在根目录上的ADS。这些ADS附加在X盘根目录下所有一级子目录的".."项上。

dir /R X:subdir

03/21/2022  13:59    <DIR>          .
03/21/2022  13:59    <DIR>          ..
                                 20 ..:any_0:$DATA
                                 20 ..:any_1:$DATA
                                 20 ..:any_2:$DATA
               0 File(s)              0 bytes

访问附加在根目录上的ADS

more < X::any_2

删除附加在根目录上的ADS

streams.exe -d X:

☆ ADS的合法用途

1) Zone.Identifier

用IE、Edge、Chrome等现代浏览器下载文件会自动添加名为"Zone.Identifier"的ADS,可以模拟这种场景。

(echo|set /p="[ZoneTransfer]"&echo=&echo|set /p="ZoneId=3") > some.exe:Zone.Identifier

ADS内容如下

[ZoneTransfer]
ZoneId=3

之后在some.exe右键General面板里出现Unlock字样,Unlock实际就是删除"Zone.Identifier"。

ZoneId的可取值有

0   My Computer
1   Local Intranet Zone
2   Trusted Sites Zone
3   Internet Zone
4   Restricted Sites Zone

Office也认"Zone.Identifier",打开docx、xlsx、pptx时会有不同。

有时"Zone.Identifier"内容更丰富。

2) favicon

据说IE生成的some.url可能包含名为"favicon"的ADS,用于存放favicon.ico,下面模拟一下此操作。

(echo|set /p="[InternetShortcut]"&echo=&echo|set /p="URL=https://stackoverflow.com/") > T:pathsome.url
type favicon.ico > "T:pathsome.url:favicon"

3) Win32App_1

未研究其用途,备忘

☆ 第三方工具

参[5],streamtools包含这些功能

cs  Copy Stream

    cs src:srcalt dst:dstalt

ds  Delete Stream

    ds some:alt

sf  Strip File (Delete All Alternate Streams)

    sf some

rs  Rename Stream

    rs some oldalt newalt

ls  List Streams

    ls some

32位工具,Win10上可用

2) GNU utilities for Win32

参[6],这里有一些用Win32 API编写的GNU工具,好像全部支持ADS,我测了cat、md5sum。

3) AlternateStreamView

参[13],GUI工具,可以对ADS进行View/Copy/Delete操作,操作方便,适合小白。

☆ 后记

本文主要科普NTFS ADS基本操作,未就ADS恶意应用展开科普,事实上许多恶意软件广泛使用ADS,与此同时,许多杀毒软件会检查ADS。

☆ 参考资源

(见TXT,略)

原文始发于微信公众号(青衣十三楼飞花堂):MSDN系列(48)--NTFS Alternate Data Streams简介

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月27日00:58:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   MSDN系列(48)--NTFS Alternate Data Streams简介http://cn-sec.com/archives/949593.html

发表评论

匿名网友 填写信息