授权与合规声明
本文全部操作对象均为自建隔离靶场(本机容器或隔离虚拟机),涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款,须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离,不含任何攻击步骤、利用载荷与绕过手法,请勿将文中环境指向任何非自有系统。
一、ls -l之后还有一层没显示
1.1 权限位后面那个@
在 macOS 上随手对一个文件执行ls -l,输出长这样:-rw-r--r--@ 1 wzk staff 5 Oct 25 06:09 note.txt。权限位那一段末尾多了一个@。
同一份文件传到一台 Linux 机器上,再ls -l,@不见了,剩下的是-rw-r--r-- 1 ...。文件没坏,字节数一样,校验值也一样。变的只有那个字符。
第一次看见它的人常有两种猜法,都不对:以为它是权限的一部分,以为它表示文件被锁。它确实跟权限位并排显示,但不属于权限位——那一段已有专文讲过,这里只处理跟在它后面的这个字符。
@的含义很窄,就一句:这个文件上还挂着扩展属性。它不告诉你挂了几条、叫什么、值是什么。想知道,得换命令。
1.2stat给得出的,和它给不出的
stat能吐出大小、块数、inode 号、链接数、三个时间、属主属组、权限位。这是文件系统为每个文件维护的那一组,POSIX 意义上的stat结构。
扩展属性不在这一组里。macOS 的man xattr把两者的关系写得很干脆:
Extended attributes are arbitrary metadata stored with a file, but separate from the filesystem attributes (such as modification time or file size).
这句话里有两个词要分开读。stored with a file:它是跟文件绑在一起的,文件在,它就在,不是外面另建的一张表。separate from the filesystem attributes:它不属于stat报的那一组,所以你用ls -l、stat、du都看不见它。
同一段手册还交代了值的形态:通常是以空字符结尾的 UTF-8 字符串,也可以是任意二进制。后半句后面会反复用到——打印出来是空白,不代表它是空的,可能是一段不可打印的字节,长度还在。
1.3 一个文件其实有三层信息
把这几件事摊开,一个文件身上能读到的信息至少分三层:
| 层 | 记录在哪 | 用什么看 | 换平台还认不认 |
|---|---|---|---|
| 内容层 | 文件的数据块 | cat、读文件、算校验值 | 认,字节就是字节 |
| 文件系统属性层 | inode 与目录项 | ls -l、stat | 大体认,字段名和精度有差异 |
| 扩展属性层 | 文件系统单独为它留的那块地方 | macOSxattr、Linuxgetfattr、Windowsdir /r | 概念在,名字和规则全不一样 |
第三列最容易被记混:前两层看哪条命令,基本是常识,第三层不是。也正因为它不参与ls -l的默认输出,在一次普通的复制里被丢掉时,没有任何提示。
本章可以带走的一句:ls -l末尾那个@只说明「有」,不说明「有什么」;扩展属性跟stat报的那一组是两套记录,不是一套的补充字段。
二、macOS:xattr的五个动作和一次本机实测
2.1 名字长什么样
macOS 上这一层的命令行入口是xattr。属性的名字是一串用点分隔的 ASCII 字符,实测里见到的两个是com.apple.provenance和com.example.demo,都是反向域名的写法。
这个写法是习惯,本文只描述实测到的名字,不推断命名约束——没核到能下定论的程度就不写。
值是另一回事。默认按 UTF-8 打印,遇到不可打印的字节就打不出来,屏幕上表现为冒号后面空空一片。这不是「属性没有值」,是「值不是文本」。要确认,用十六进制看,或者看长度。
2.2 五个动作,三个修饰
man xattr给的是一组选项。按用途归一下,真正算「动作」的是五个:
| 动作 | 选项 | 输出什么 |
|---|---|---|
| 列名字 | 不带选项 | 一行一个属性名,不给值 |
| 列名字和值 | -l | 名字加冒号加值,不可打印处留空 |
| 看单个值 | -p加属性名 | 只给那一条的值 |
| 写 | -w加名字和值 | 不输出,成功即返回 |
| 删一条 | -d加属性名 | 不输出 |
| 清全部 | -c | 不输出,一条不剩 |
严格说,表里是六行,-l是「列」的变体,所以习惯上说五个动作。
另有三个修饰选项,作用在动作上而不是自成动作:-x把值按十六进制显示,用来对付上面那种打不出来的值;-r递归到目录里的每一项;-s让命令作用于符号链接本身而不是它指向的目标。最后这个容易被忽略——默认情况下,你对一个软链接执行xattr,动的是链接指向的那个文件。
-d和-c的区别就一句:一个是点名删,一个是全删。后者会把这个文件上的属性清空,包括系统自己写的那条。
2.3 本机实测:两行属性,一行不是我写的
下面这段是 2026-10-25 在 macOS 上真跑的,命令和输出都原样贴。
printf'test\n'>/tmp/_xa.txt xattr-wcom.example.demo"hello"/tmp/_xa.txt xattr-l/tmp/_xa.txt输出是两行,不是我写进去的一条:
com.apple.provenance: com.example.demo: hello第一行是系统自己加的,我只写了一条。第二行是我写的那条,值就是hello,打印得出来。第一行的冒号后面是空的——按 2.1 说的,它的值不是可打印文本。
再换ls -l的扩展选项看一次:
ls-l@ /tmp/_xa.txt xattr /tmp/_xa.txt-rw-r--r--@ 1 wzk wheel 5 Oct 25 06:09 /tmp/_xa.txt com.apple.provenance 11 com.example.demo 5 com.apple.provenance com.example.demo这里能读出两件事。
第一,@的位置在权限位之后、链接数之前,它是个标记位,不是权限字符。顺带说一句边界:-rw-r--r--那九位怎么解读,本文不涉及,那是另一篇文章的事,这里只看@。
第二,ls -l@在下面列出两行,格式是名字加制表符加长度。com.example.demo是 5,跟我写进去的hello对得上;com.apple.provenance是 11,说明它确实有值,只是打印不出来。xattr不带选项则只列名字,两行干净——想知道有没有,用它最快。
一个能带走的观察:新建一个普通文件,你一条属性都不写,它上面也已经有一条了——系统会写自己的东西,这部分不在你的控制范围内。所以「有扩展属性」这件事本身说明不了任何问题,得看是哪一条。
本章可以带走的一句:@只提示存在,xattr列名字,-l给值,长度比内容更可靠——值打不出来不等于没有值。
三、Linux:名字必须带前缀,ACL 就住在这一层
3.1 定义几乎一样,规则完全不同
Linux 侧的手册xattr(7)开头是这么写的:
Extended attributes are name:value pairs associated permanently with files and directories, similar to the environment strings associated with a process.
跟 macOS 那句对照着看,前半段讲的是同一件事:名字值对,跟文件长期绑定。后半段那个比喻值得停一下——像进程的环境变量。像的是形态,不像的是生命周期:进程退出环境变量就没了,文件还在,属性就还在。这句permanently是理解后面所有限制的前提。
真正的差异在名字上。Linux 要求名字写成全限定形式namespace.attribute,前面的命名空间不是装饰,它决定了这条属性能不能被看见、被谁写。
3.2 四个命名空间
| 命名空间 | 谁在用 | 谁能看见 | 典型名字 |
|---|---|---|---|
security | 内核安全模块,如 SELinux、文件能力 | 由那套机制自己决定,本文不推断 | security.selinux |
system | 内核自己用,如 ACL | 跟内核功能绑定 | system.posix_acl_access |
trusted | 给特权程序留的 | 只有具备CAP_SYS_ADMIN的进程可见 | trusted.md5sum |
user | 普通属性,用户自己写 | 普通用户 | user.mime_type |
最该记住的是第三列。trusted那一行是个硬边界:没有那个能力,你连它存在都看不到。这不是权限位那种「看得见但改不了」,是列表里压根不出现。所以在某台机器上看不到一条属性,不能推出「这台机器上没有它」——先确认自己是拿什么能力集看的。
user那一行也有边界:这类属性只能加在普通文件和目录上;对某些目录另有额外限制。后半句在xattr(7)里是单独一段,本文不展开。
3.3 两个上限、整体替换,和住在这里的 ACL
上限有两个,都是 VFS 层的,跟具体文件系统无关:属性名最长 255 字节,属性值最长 64 kB。还有第三个:列出名字的那个调用,返回的名字列表总共也限 64 kB。
三个数字的实际含义是:扩展属性不是给你存大块数据的地方。64 kB 要装下所有属性值,名字列表那份还要装下所有名字;属性一多,列名字这个动作本身就会撞上限。
读写语义是另一条:getxattr(2)一次取回整个值,setxattr(2)整体替换旧值。没有「改中间一个字节」的接口,要改一个字符,也得把整个值写回去。
这条语义推下去有两个后果。一是并发写不安全:两个进程同时setxattr同一条,落盘的是后完成的那次,修改不会合并。二是它适合「标记」,不适合「状态」。
ACL 也是这一层里的一条,值得单独说。很多人把 ACL 当成跟扩展属性并列的另一套东西,xattr(7)里有一句把这个误会直接打消:
additional security features such as Access Control Lists (ACLs) may be implemented using extended attributes
也就是说,ACL 是用扩展属性实现的。落到名字上,就是system.posix_acl_access这一条。
价值在操作层面:「清空扩展属性」和「清掉 ACL」在某些命令下是同一个动作。你把一个目录上的属性全删掉,顺手也删了访问控制列表,屏幕上一句提示都没有。所以清理前先列一遍名字,看清有哪些条、属于哪个命名空间。
所以我建议用-d逐条删,而不是-c一把清干净:前者你至少知道自己删了什么。
⚠️代码待验证(Linux 侧命令按xattr(7)与 attr 工具手册写,本机是 macOS,未在 Linux 上执行)
getfattr-d-m- /tmp/example.txt setfattr-nuser.mime_type-v"text/plain"/tmp/example.txt getfattr-nuser.mime_type --only-values /tmp/example.txt第一条把文件上所有可读的属性连名字带值列出来,第二条写一条user.*,第三条只取值。跑之前先确认这台机器上装了 attr 这套工具——不是所有发行版都预装,这一点本文不给具体包名。
本章可以带走的一句:Linux 的扩展属性名字必须带命名空间,命名空间决定可见性;ACL 就住在system.*里,所以「清属性」和「清 ACL」可能是同一次操作。
四、Windows:一个文件至少有一个流
4.1 默认数据流与那个双冒号
Windows 那边的对应机制不叫扩展属性,叫流。[MS-FSCC] 对 NTFS 的描述第一句就把范围说清了:
All files on an NTFS volume consist of at least one stream - the main stream – this is the normal, viewable file in which data is stored.
注意at least one:一个文件不是「一块数据加若干附加信息」,而是「一个或多个流」,其中必有一个是主数据流——你在资源管理器里双击打开的那个。
完整的名字是三段式:<filename>:<stream name>:<stream type>。主数据流没有名字,所以一个sample.txt的主数据流,全名写出来是sample.txt::$DATA——中间那段是空的,双冒号就是这么来的。
| 写法 | 指的是什么 | 默认看得见吗 |
|---|---|---|
sample.txt | 主数据流,等价于sample.txt::$DATA | 看得见,就是那个文件 |
sample.txt:note:$DATA | 一条备用数据流,类型是$DATA | 不显示 |
目录的$I30段,类型$INDEX_ALLOCATION | 目录自己也有流 | 不显示 |
第三行容易被漏掉:目录也有流。目录项的索引本身就以$INDEX_ALLOCATION类型的一条流存在,默认流名是$I30。所以「流」不是文件专有的机制,它是这个文件系统描述一切东西的方式。
4.2 怎么看见:/R这个开关
[MS-FSCC] 里写得很直接:
These alternate data streams are not normally visible, but can be observed from a command line using the /R option of the DIR command.
这句话里两个词要分开看:not normally visible说的是资源管理器,can be observed说的是命令行加一个开关。
⚠️代码待验证(Windows 侧命令按 [MS-FSCC] 写,未在本机执行)
rem 在 cmd.exe 里对一个目录执行 dir /r输出里会在文件名之外多出以冒号分隔的那一段;具体排版随版本不同,本文不贴样例,也不猜格式。
边界划在这里:本文只讲它存在、怎么看见,不讲怎么用它放东西。看见和利用是两件事,很多讲这一层的文章就是在这一句上滑过去的。
4.3 三平台并排看
把前面三章压成一张表:
| 平台 | 这一层叫什么 | 怎么列出来 | 谁能看见 |
|---|---|---|---|
| macOS | 扩展属性(extended attributes) | xattr列名字,xattr -l连值,ls -l@看@与长度 | 属主可读写(2.3 实测);系统另写一批 |
| Linux | 扩展属性,名字必须是namespace.attribute | getfattr,或直接调listxattr | 取决于命名空间,trusted需CAP_SYS_ADMIN |
| Windows NTFS | 流(stream),主数据流加备用数据流 | dir /r,或按文件名:流名:$DATA拼完整名 | 主数据流就是文件本身;备用流默认不显示 |
表里没有明说、但最该记住的一点:只有 macOS 会在ls -l里留一个字符提示你有东西。Linux 和 Windows 什么都不提示。所以「看不见」在三个平台上一个意思:不等于没有,只等于「你用的这条命令不看这一层」。
本章可以带走的一句:NTFS 里文件是流的集合,主数据流没名字、全名带::$DATA;三个平台都不会在默认输出里提醒你这一层存在。
五、搬家的时候,这一层跟不跟着走
5.1 结论只有一句:默认不搬
这一段最容易被说过头。能确定的只有这一层:打包、复制这类动作,默认不会把扩展属性带过去,要带就得显式打开某个开关。至于每个工具默认开不开、开关叫什么、开了之后跨文件系统还成不成立,各工具不一样,本文不下结论,也不给参数写法。
原因可以从定义推出来,不需要查任何一个工具:这一层是stored with a file但separate from the filesystem attributes(2.1 引的那句)。一个「复制文件」的动作,常规做法是读数据、写数据、再按需要补几个stat字段。属性那一层不在数据里,也不在stat那一组里,所以它天然落在复制的默认路径之外。
5.2 四种搬家场景,要确认的东西不一样
| 场景 | 这一层跟不跟着走 | 需要确认什么 |
|---|---|---|
| 同一块盘上改名或移动 | 位置变了,没有写出新文件 | 仍建议前后各列一次,别假设 |
| 跨盘、跨文件系统复制 | 新文件被写出来,属性不自动跟 | 工具是否提供开关,开关在手册哪一节 |
| 打包再解开 | 中间产物是归档,属性要单独带 | 打包与解包两端都得支持,缺一端就丢 |
| 跨操作系统传递 | 目标平台未必有同名概念 | 名字空间规则不同,开关打开也可能无处落脚 |
最后一行最麻烦。macOS 是扁平的点分名字,Linux 要求namespace.attribute全限定,NTFS 那边是流、名字里带冒号。三种模型之间没有共同的表示,所以跨平台搬这一层,问题不在「能不能复制」,在「目标那边有没有这个概念可以接收」。
⚠️ 这一段按待验证处理:各工具的具体默认值本文不给,只保留「默认不搬、需要显式开关」这一层。要写进自己的操作手册,得拿目标版本的工具亲手试一遍。
5.3 为什么它丢得悄无声息
因为它丢的时候,所有你能想到的检查都是通过的。
- 文件大小一样——属性不在文件大小里。
- 修改时间一样——那是
stat那一组,跟这一层不相干。 - 校验值一样——属性不在数据块里,校验算的是内容。
- 打开也正常——读内容的程序根本不看这一层。
唯一的检查方式是列属性,不是比内容。搬完之后,用目标平台那条命令列一次名字,跟搬之前那份对一遍:名字少了就是少了,名字在而值变了,得单独看。
⚠️代码待验证(流程示意,本机未对真实跨机复制执行)
printf'%s\n''第 1 步:源端列一次属性名字,存成清单'printf'%s\n''第 2 步:执行复制,记录用了哪些开关'printf'%s\n''第 3 步:目标端再列一次属性名字,存成清单'printf'%s\n''第 4 步:两份清单对比,只比名字,先不比值'printf'%s\n''第 5 步:名字缺失的,回到第 2 步看开关;不要先怀疑文件损坏'第 5 步是我最想强调的:属性缺失和文件损坏是两件不同的事,表现却很像。先怀疑开关,比先怀疑磁盘划算。
完整版对照资料:这一章对照的三平台「怎么列属性、搬家前后怎么比对」的操作卡,我整理成了一页,跟靶场环境对照表放在同一个资料包里,扫码即可获取:
本章可以带走的一句:复制工具复制的是文件,不是文件在原来那台机器上的全部状态;属性丢没丢,只能靠搬家前后各列一次名字来判。
六、安全上为什么在意
6.1 有些判定读的是这一层,不是内容
把前面几章散落的点收一下,会发现这一层里装的并不都是「备注」:
- 访问控制列表在
system.posix_acl_access(3.3 那句原文)。 - SELinux 的标签在
security.selinux(3.2 的表)。 - 文件能力也挂在
security命名空间下(同一处)。 - Windows 上「文件来源」这类信息,是按流记录的([MS-FSCC] 的流模型,具体流名本文不展开)。
这些信息的共同点是:做访问判断时,系统读的是它们,不是内容。判断发生在你读到文件之前——能不能访问、以什么身份执行、这个文件从哪来。
第五章的结论到这里就变得更要紧了:属性默认不跟着走,意味着这些判定在新机器上读到的是「没有」。而「没有标签」和「标签是对的」是两种状态,前者通常落到那套机制的默认处理上,后者才是你在原来那台机器上验证过的。
默认处理具体是什么,取决于那套机制自己的策略,本文不给结论——不同策略答案不一样,写个通用答案就是在编。
6.2 两个方向:丢了,和被带过来
方向一:该在的不在了。一台机器上配好的访问控制、安全标签,经过一次打包和一次解包落到新机器上。文件能用,但那些判定读到的是空的。这种降级不报错,也不会有人察觉——除非有人专门去列一次属性。
方向二:不该在的来了。反过来,一个从别处来的文件,属性如果被完整带过来了,记录的就是它原来那台机器上的状态。1.3 那张表里我把它叫第三层,现在可以补一句:这一层记录的是过程,不是内容。
最典型的是系统自己写的那条。2.3 里新建一个空文件,com.apple.provenance就已经在了,我什么都没做。它的名字指向「来源」,但具体含义本文不推断——没人为它给出语义,我也不替它编。能确定的只有两点:它由系统写入;它的值不是给人读的文本。这就够支撑一条建议:看到com.apple.*开头的属性,先假设它不该被你手动删。
6.3 名字本身就是线索
判断一条属性该不该动,第一眼看的不是值,是名字。前缀基本就交代了它是谁写的:
com.apple.*:系统写的(2.3 实测)。删了文件内容不变,但那条记录就没了。system.*:内核用,ACL 就在这一类里。删它等于改访问控制,不是清理垃圾。security.*:内核安全模块用。删了可能让判定落到默认策略上,后果由那套策略决定。trusted.*:特权侧,普通身份连看都看不到,别把它算进「没有」。user.*:普通用户这一类,才是可以随手清的。
只有最后一行让人放心。前四行都属于「不是你的东西」,其中system.*和security.*尤其——看上去像备注,实际是判定输入。
这也回到了 2.2 提到的那个差别:-d点名删,-c全删。如果你连这些名字是谁写的都还没分清,就不该用全删。
本章可以带走的一句:安全判定读的是这一层,而「属性不在」不等于「属性和原来一样」;动它之前先看名字前缀,com.apple.*、system.*、security.*都不是清理对象。
七、三分平台自查清单
7.1 macOS:三条命令按顺序来
ls -l看末尾有没有@。有,才值得往下走。xattr 文件名列名字。这一步回答「有几条、叫什么」。xattr -l 文件名连值一起看。值打不出来的,回ls -l@看长度,或加-x看十六进制。
顺序不能反:先看值容易陷进「这一串是什么」,而多数时候你只需要知道有几条。
三个判读要点:@只表示存在;冒号后空白不代表没有值;-s不写,动的是链接指向的目标而不是链接本身。
7.2 Linux 与 Windows:各一条
Linux 侧用getfattr -d -m - 文件名把可读的都列出来,重点看名字前缀落在哪个命名空间。看不到某条,先确认自己的能力集——trusted.*在没有CAP_SYS_ADMIN时列表里就是不出现。
Windows 侧在 cmd 里dir /r,看文件名后面有没有多出一段以冒号分隔的名字。有,就是备用数据流;没有,也不代表这个文件「干净」,只代表这一层没有额外的流。
两边共同的注意点:这两个命令的输出格式在不同版本上不完全一样,别把某一次的排版当成标准答案。
7.3 三条判读纪律
第一,看不见不等于没有。三个平台默认都不提醒你这一层。macOS 好歹留了个@,Linux 和 Windows 连这个都没有。
第二,读不出来不等于空的。属性值可以是任意二进制,打印成空白是正常现象,长度才是它存在的证据。
第三,复制完内容一致,不等于这一层一致。大小、时间、校验值全对,属性可能一条没跟过来。要确认,只能列名单对比。
这三条其实是一句话的三个面:这一层的存在感和它的重要性成反比。越是不显示的东西,越容易在搬家时被丢掉,而丢掉之后又越难发现。
本章可以带走的一句:先确认有没有(看标记、列名字),再确认是什么(看值、看长度),最后才谈搬不搬得走——顺序对了,这一层就不神秘。
完整版对照资料:第七章这份三平台自查清单(macOS 三条、Linux 与 Windows 各一条、三条判读纪律),和第五章的搬家对照是同一套材料的两面,我都收在资料包里了,扫码即可获取:
附表 A:本文引用事实与官方出处对照表
| 序号 | 事实 | 出处 | 核验日期 | 本文位置 |
|---|---|---|---|---|
| 1 | 扩展属性是随文件存储、但与文件系统属性(修改时间、文件大小等)分离的任意元数据 | macOSman xattr(XA-02) | 2026-10-25 | 第一章 1.2 |
| 2 | 属性值通常是以空字符结尾的 UTF-8 字符串,也可以是任意二进制 | macOSman xattr(XA-02) | 2026-10-25 | 第一章 1.2、第七章 7.3 |
| 3 | 本机实测:用xattr -w把 hello 写进com.example.demo后,xattr -l输出com.apple.provenance:与com.example.demo: hello两行 | 本机命令输出(XA-01) | 2026-10-25 | 第二章 2.3 |
| 4 | 本机实测:新建文件会自动带com.apple.provenance,由系统写入 | 本机命令输出(XA-01) | 2026-10-25 | 第二章 2.3、第六章 6.2 |
| 5 | 本机实测:ls -l@在权限位后显示@,下方按名字与值长度列出两条(11 与 5) | 本机命令输出(XA-01) | 2026-10-25 | 第二章 2.3 |
| 6 | 各动作对应的选项:不带选项列名字、-l连名字带值、-p打印单值、-w写、-d删单条、-c清全部 | macOSman xattr(XA-03) | 2026-10-25 | 第二章 2.2、第六章 6.3 |
| 7 | 三个修饰:-x十六进制、-r递归、-s作用于符号链接本身 | macOSman xattr(XA-03) | 2026-10-25 | 第二章 2.2、第七章 7.1 |
| 8 | 「Extended attributes are name:value pairs associated permanently with files and directories, similar to the environment strings associated with a process.」 | xattr(7)(XA-04) | 2026-10-25 | 第三章 3.1 |
| 9 | 四个命名空间security、system、trusted、user的用途,名字一律写成namespace.attribute | xattr(7)(XA-05) | 2026-10-25 | 第三章 3.2 |
| 10 | trusted命名空间只有具备CAP_SYS_ADMIN的进程可见 | xattr(7)(XA-05) | 2026-10-25 | 第三章 3.2、第七章 7.2 |
| 11 | user.*只允许加在普通文件和目录上,对某些目录另有额外限制 | xattr(7)(XA-06) | 2026-10-25 | 第三章 3.2 |
| 12 | 属性名最长 255 字节、属性值最长 64 kB、名字列表也限 64 kB | xattr(7)(XA-07) | 2026-10-25 | 第三章 3.3 |
| 13 | 「additional security features such as Access Control Lists (ACLs) may be implemented using extended attributes」 | xattr(7)(XA-08) | 2026-10-25 | 第三章 3.3、第六章 6.1 |
| 14 | getxattr(2)一次取回整个值,setxattr(2)整体替换旧值 | xattr(7)(XA-09) | 2026-10-25 | 第三章 3.3 |
| 15 | 「All files on an NTFS volume consist of at least one stream - the main stream…」 | [MS-FSCC] 5.1(XA-10) | 2026-10-25 | 第四章 4.1 |
| 16 | 流全名形如<filename>:<stream name>:<stream type>,主数据流无名字,sample.txt的默认流全名是sample.txt::$DATA | [MS-FSCC] 5.1(XA-10) | 2026-10-25 | 第四章 4.1 |
| 17 | 「These alternate data streams are not normally visible, but can be observed from a command line using the /R option of the DIR command.」 | [MS-FSCC] 5.1(XA-11) | 2026-10-25 | 第四章 4.2 |
| 18 | 目录也有流,类型$INDEX_ALLOCATION,默认流名$I30 | [MS-FSCC] 5.1(XA-11) | 2026-10-25 | 第四章 4.1 |
| 19 | Windows 上「文件来源」这类信息按备用数据流记录(本文不展开流名与取值) | [MS-FSCC](XA-12) | 2026-10-25 | 第六章 6.1 |
| 20 | 待验证:打包与复制工具是否搬运扩展属性,各工具默认值不同;本文只写「默认不搬、需要显式开关」,不给参数写法 | 本批事实文件(XA-13) | 2026-10-25 | 第五章 5.1、5.2 |
| 21 | 本文范围:只用 ADS 说明「它存在、怎么看见」,不写任何用它放置数据的手法 | 本批纪律(XA-14) | 2026-10-25 | 第四章 4.2 |
| 22 | 本文范围:不涉及权限位的rwx、特殊位与目录的那套规则,仅在 2.3 作一句边界说明 | 本批纪律(XA-15) | 2026-10-25 | 第二章 2.3 |
附表 B:术语速查表
| 术语 | 一句话解释 |
|---|---|
| 扩展属性 | 跟文件绑在一起、但不在stat那一组里的名字值对;值可以是文本也可以是二进制 |
@标记 | macOSls -l在权限位后面加的提示,只表示「有扩展属性」,不表示内容 |
xattr | macOS 上操作这一层的命令行入口,列名字、看值、写、删、清都靠它的选项 |
| 命名空间 | Linux 名字的前缀(user/system/trusted/security),决定可见性与用途 |
CAP_SYS_ADMIN | Linux 的一个特权能力;没有它,trusted.*属性在列表里根本不出现 |
| ACL | 访问控制列表,在 Linux 上就是用扩展属性实现的(system.posix_acl_access) |
| 主数据流 | NTFS 里那个「没有名字」的流,就是你在资源管理器里看到的文件本身;全名以::$DATA收尾 |
| 备用数据流 | NTFS 里主数据流之外的那些流,默认不显示,跨平台复制时也没有对应物 |
$I30 | 目录自身那条流的默认名字,类型是$INDEX_ALLOCATION |
| 整体替换 | setxattr的语义:一次写完整个值,没有「改一半」的接口 |
写在最后:这篇用到的资料
写这篇文章时,我把三个平台的这一层并排摊在一张纸上,最费劲的是接受「它们压根不是同一个东西」——只在三个平台上都靠
ls -l那点信息,就永远对不上,顺手也整理了几份配套的东西:
- 靶场环境对照表:DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径
- Web 安全学习路线图:从基础打牢到安全管理,四个阶段各学什么
- 常用靶场清单:每个靶场练什么、适合哪个阶段
资料是我自己整理的,放在下面这个码上,扫码即可获取:
添加时备注「靶场」,优先通过。
拿到之后建议先看环境对照表那一份,先把手上这台机器的「看不见的那一层」列一遍,再谈环境怎么搭。