尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

FAT文件系统取证实战:从磁盘镜像手工提取隐藏文件

发布时间:2026/9/7 17:20:25

资讯中心
01
ARTICLE

FAT文件系统取证实战:从磁盘镜像手工提取隐藏文件

FAT文件系统取证实战:从磁盘镜像手工提取隐藏文件
BUUCTF Misc 的题我刷了不少大部分时候拿到手就是一张图、一个压缩包或者一段流量但“金3fat”这道题属于典型的“文件系统取证”方向光靠眼睛看和 strings 扫一遍是出不来 flag 的。这道题名字里那个“fat”其实已经给了很大提示它不是让你猜什么谐音梗而是告诉你附件大概率是一个 FAT 系列文件系统的磁盘镜像flag 就藏在文件系统的某个角落里。这篇复盘我会按照实际做题的顺序来写从拿到附件后的第一步侦查开始到 FAT 文件系统的底层结构分析再到如何手工提取被隐藏或删除的文件最后把同类题型常见的坑和排查思路一起整理出来。无论你是刚开始刷 BUUCTF 的新手还是被这道题卡住的老手这篇文章都能直接用上。1. 题目分析与思路拆解1.1 拿到题目先做基础侦查刚下载完附件别急着上高级工具先把最基础的三板斧轮一遍file看文件类型、binwalk扫文件结构、strings抽字符串。file 金3fat binwalk 金3fat strings 金3fat | head -50真实做题的时候file的输出最值得细看。如果显示的是 “DOS/MBR boot sector” 或者 “FAT (File Allocation Table) filesystem” 这类字样基本就锁定方向了——这是一个 FAT 文件系统镜像可能是一个软盘镜像常见的是 1.44MB 的 IMG 文件也可能是从 U 盘或 SD 卡里导出的分区镜像。如果file只显示 “data” 或者识别为普通的二进制文件也别急着放弃用binwalk再确认一次有时候文件头被抹掉了binwalk仍然能通过文件系统的特征值识别出 FAT 结构。1.2 为什么题目叫“金3fat”核心考点是什么这道题的题库名称带“fat”字样实际上是在引导做题人往 FAT 文件系统方向思考。FAT 是 File Allocation Table文件分配表的缩写是一种非常古老但至今仍被广泛使用的文件系统常见于 U 盘、SD 卡、软盘和一些嵌入式设备。它在取证和 CTF 里的考法非常固定几乎所有题目都围绕这几个点引导扇区Boot Sector里的关键参数比如每扇区字节数、每簇扇区数、保留扇区数、FAT 表数量、根目录项数等。FAT 表里的簇链关系用于还原文件在磁盘上的物理存储位置。目录项Directory Entry里的文件名、扩展名、文件属性、起始簇号、文件大小。被删除文件目录项首字节被改为 0xE5的恢复。隐藏文件属性字节被改为 0x02、0x04、0x06、0x07 等的发现。文件内容可能被标记为“坏簇”FAT 表项值为 0xFF7来隐藏数据。“金3fat”这道题基本把这几个考点串起来了它不是单纯考你工具操作而是考你对 FAT 文件系统底层结构的理解程度。我用“底层结构”这个词是因为很多现成工具能自动完成文件提取但 CTF 题目经常会在细节上做手脚比如把文件属性改成隐藏、把删除标记改掉、甚至手动篡改 FAT 表项这时候工具就不可靠了你得手工去看字节。1.3 从 Misc 分类反推常用工具链BUUCTF 的 Misc 题范围很广但凡是涉及文件分析与提取的我一般会准备好这样一套工具链file识别文件类型永远的第一步。binwalk扫描文件末尾追加数据或内嵌文件。foremost根据文件签名自动提取文件适合文件碎片重组。strings提取字符串快速看有没有直接出现的 flag 或关键路径。hexdump或xxd十六进制查看用于手工分析。7z或Bandizip破解压缩包、查看压缩包内文件。WinHex/010 EditorWindows 下的十六进制编辑器查看磁盘结构比命令行方便很多。FTK Imager/Autopsy/R-Studio专业的磁盘取证工具能一键列出分区和已删除文件。实际做题时foremost和FTK Imager这类工具能帮你快速发现问题但要拿到完整的 flag 思路还是得回到十六进制层面去理解 FAT 的结构。所以接下来的分析我会一边讲工具操作一边讲底层原理这样你以后遇到同类的 FAT 取证题就算换个马甲也能轻松识破。2. FAT 文件系统核心结构与原理2.1 引导扇区里的关键参数怎么看FAT 文件系统的第一个扇区是引导扇区一共 512 字节里面保存着整个文件系统的元信息。我直接在十六进制查看器里打开镜像从偏移 0x00 开始看重点关注这几个位置的字节偏移长度含义示例值十六进制0x003跳转指令EB 3C 900x038OEM 名称4D 53 44 4F 53 35 2E 300x0B2每扇区字节数00 025120x0D1每簇扇区数02每簇2扇区0x0E2保留扇区数01 0010x101FAT 表数量020x112根目录项数00 025120x162每 FAT 表扇区数09 0090x1C4隐藏扇区数00 00 00 000x1E4总扇区数00 10 00 004096这些参数不是摆设它们决定了你如何计算文件系统里各区域的起始位置。比如FAT 表数据区的起始位置可以这样算保留扇区数 (FAT 表数量 × 每 FAT 表扇区数) (根目录项数 × 32 / 每扇区字节数)拿上面这个示例来说就是1 (2 × 9) (512 × 32 / 512) 1 18 32 51也就是说从扇区 51 开始才是真正的文件数据区。这个计算在手工提取被隐藏文件时非常关键因为很多工具遇到属性被篡改的文件就直接不显示了这时候你必须自己定位数据区把文件内容按偏移量手动抠出来。2.2 FAT 表一张管理磁盘空间的“清单”FAT 表本身是一个数组每个表项对应磁盘上的一个簇。表项的值表示这个簇的当前状态具体含义如下0x0000空闲簇0xFFF8 - 0xFFFF文件结束簇EOF表示文件链到此为止0xFFF7坏簇其他值该簇的下一个簇号FAT12、FAT16、FAT32 的表项宽度不同分别是 12 位、16 位、32 位。对于 1.44MB 软盘镜像几乎都是 FAT12它的表项是 12 位的所以查看 FAT 表时要按 3 个字节一组来看比如字节: F0 FF FF 拆解: 0xFFF 0x0FF 0xFFF 含义: FAT[0]0xFFF FAT[1]0xFFF FAT[2]0x0FFFAT[0] 和 FAT[1] 是保留项从 FAT[2] 开始才是真正的数据簇映射。做题时你可以通过 FAT 表判断哪些簇被占用、哪些簇是空闲的。如果发现某个文件声称占用了一些簇但 FAT 表里的对应表项却是空闲值那就说明这个镜像被人动过手脚——这往往是定位隐藏数据的关键线索。2.3 目录项文件信息的“户口本”FAT 的根目录区或子目录区由一个个 32 字节的目录项组成每个目录项对应一个文件或子目录。关键字段如下偏移长度含义0x008文件名0x083扩展名0x0B1文件属性0x1A2起始簇号的高 16 位0x142起始簇号的低 16 位0x1C4文件大小字节文件属性字节很有讲究常见值0x01只读0x02隐藏0x04系统0x08卷标0x10子目录0x20归档0xE5文件已被删除目录项首字节CTF 题目常把文件属性改成 0x02隐藏或 0x06隐藏系统普通文件管理器里看不到但用十六进制查看器直接看目录项就能发现。另外如果目录项首字节是 0xE5说明这个文件被删除过FAT 表里的簇链信息也可能被部分清空但文件内容往往还残留在数据区里这时候要把数据区按簇逐个扫一遍看有没有类似 flag 的文件头。2.4 为什么工具会失灵必须学会手工定位很多同学做题时习惯直接用foremost一把梭但 FAT 取证的坑就在于如果文件不是连续的、或者文件头被篡改过工具基于文件签名提取的方式就会失效。举个例子FAT 文件系统里文件在磁盘上不一定连续存储。如果一张 1.44MB 软盘上只有几个小文件文件大概率是连续的工具能正常提取但如果镜像里包含大量小文件或者文件被不断增删文件就会碎成多段分散在不连续的簇里。这个时候只有通过 FAT 表把簇链串起来才能完整还原文件内容。所以我的建议是工具提取只是第一步验证性工作不能少。拿到一个提取结果先用file验证一下提取出来的东西是什么类型再用strings检查内容是否完整。一旦发现异常立刻切回手工分析。3. 实操过程与核心实现3.1 环境准备与工具安装这道题需要用到命令行工具所以先准备一个 Linux 环境虚拟机和 WSL 都行。我用的是 WSL Kali 的常用工具包组合模拟真实做题环境的操作路径如下sudo apt update sudo apt install binwalk foremostforemost默认可能在forensics-all工具组里如果单独安装失败可以一起装sudo apt install forensics-allWindows 用户建议备一个010 Editor或WinHex它们看十六进制比命令行里的xxd舒服很多。另外推荐一个离线工具FTK Imager绿色版就能用打开磁盘镜像直接显示文件系统和分区结构识别隐藏文件和已删除文件非常方便。3.2 第一步侦查文件类型与内嵌结构进入题目目录后我习惯先跑filefile 金3fat如果输出显示类似DOS/MBR boot sector, code offset 0x3c2, OEM-ID MSDOS5.0, root entries 512, sectors 4096 (FAT12), sectors/FAT 9那就很明确了——这是一个 FAT12 文件系统镜像大小 2MB4096 扇区 × 512 字节。接着用binwalk扫描binwalk 金3fatbinwalk通常会识别出 FAT 文件系统但它的输出对这道题帮助有限因为 FAT 结构本身不会像 JPG 那样有显著的文件签名。接下来用strings快速过一遍strings 金3fat | head -100 strings 金3fat | grep -i flag这一步可能直接出结果也可能啥也搜不到。如果搜不到说明 flag 被藏在文件内部或者被处理过了需要往文件系统的底层继续挖。3.3 挂载镜像看看文件系统里有什么最直接的方法是把它当软盘镜像挂载到 Linuxmkdir -p /mnt/fat mount -o loop,ro 金3fat /mnt/fat ls -la /mnt/fat如果挂载成功进去看看有没有什么可疑文件。如果提示需要制定文件系统类型可以用mount -t vfat -o loop,ro 金3fat /mnt/fat但有一个问题挂载上去之后操作系统会直接帮你解析并过滤隐藏文件、删除文件所以普通ls看不到的东西不代表不存在。这时候就需要回到十六进制层面去验证。挂载的作用是快速拿到“表面文件”的清单以及确认文件系统的健康程度。如果挂载失败大概率是镜像里的引导扇区参数被改过这本身就是线索。3.4 十六进制层分析从引导扇区开始用xxd或hexdump查看前 512 字节xxd 金3fat | head -32重点核对前面提到的引导扇区参数。拿一个典型值来举例每扇区字节数5120x0200每簇扇区数2保留扇区数1FAT 表数量2根目录项数512每 FAT 表扇区数9根据这些参数可以算出根目录区起始扇区 1 2 × 9 19 数据区起始扇区 19 512 × 32 / 512 51从根目录区起始扇区扇区 19开始看dd if金3fat bs512 skip19 count32 | xxd这里count32是因为根目录项数是 512每项 32 字节总共 16KB也就是 32 个扇区。如果你看到目录项里有一个文件名属性的字节是 0x02、0x06、0x07这说明有隐藏文件如果看到首字节是 0xE5说明有已删除文件。3.5 手工提取隐藏文件假设在根目录区看到一个目录项文件名区域显示3FAT TXT或者类似名称属性字节是 0x02隐藏起始簇号是 0x0002文件大小是 0x4001024 字节。此时用系统挂载是看不到这个文件的需要手工提取。数据区起始扇区是 51簇 2 对应的起始扇区是数据区起始扇区 (簇号 - 2) × 每簇扇区数如果起始簇号是 2就是51 (2 - 2) × 2 51所以文件内容从扇区 51 开始连续读 1024 字节即可dd if金3fat bs512 skip51 count2 hidden.txt cat hidden.txt如果文件大于 2 个扇区就要根据 FAT 表去追簇链。FAT 表起始于扇区 1因为保留扇区数为 1FAT12 的表项是 12 位。要找簇 N 的 FAT 表项位置先计算字节偏移字节偏移 扇区起始位置 (N * 3) / 2如果是 FAT12奇数簇号和偶数簇号的取值方式不同容易算错建议用脚本处理。这里我直接贴一段顺手写的 Python 脚本读取 FAT 表并追踪文件簇链import struct def read_sector(data, sector, sector_size512): offset sector * sector_size return data[offset:offset sector_size] def parse_fat12_entry(fat_table, index): offset (index * 3) // 2 two_bytes fat_table[offset:offset 2] value struct.unpack(H, two_bytes)[0] if index % 2 0: return value 0x0FFF else: return value 4 with open(金3fat, rb) as f: data f.read() sector_size 512 reserved_sectors 1 fat_count 2 sectors_per_fat 9 root_entries 512 sectors_per_cluster 2 fat1_offset reserved_sectors * sector_size fat1 data[fat1_offset:fat1_offset sectors_per_fat * sector_size] root_dir_start reserved_sectors fat_count * sectors_per_fat data_start root_dir_start root_entries * 32 // sector_size # 假设起始簇号为 2 start_cluster 2 cluster start_cluster output bytearray() while 0x002 cluster 0xFF8: sector data_start (cluster - 2) * sectors_per_cluster output read_sector(data, sector) output read_sector(data, sector 1) next_cluster parse_fat12_entry(fat1, cluster) if next_cluster cluster: break cluster next_cluster with open(extracted.bin, wb) as f: f.write(output)这样就能绕过操作系统的隐藏文件逻辑直接把文件原始字节提取出来。提取完再用file extracted.bin验证文件类型如果它是图片、压缩包或者文本就离 flag 更进一步了。3.6 已删除文件的恢复与深入扫描如果根目录区有很多 0xE5 开头的目录项就需要逐个恢复。命令是dd if金3fat bs512 skip19 count32 | xxd | grep -B 2 -A 2 e5删掉的文件目录项仍然保留文件名和起始簇号只是文件名的首字节变成了 0xE5。你可以把 0xE5 改回对应的文件名首字节然后按照目录项里的起始簇号和文件大小手工提取整条簇链。如果根目录区干净什么可疑项都没有那就换个思路——直接在数据区全盘搜索常见文件头。比如找 PNG89 50 4E 47、JPGFF D8 FF、ZIP50 4B 03 04grep -abo $\x89\x50\x4e\x47 金3fat如果搜到了文件头再用foremost在整盘上跑一次foremost 金3fat -o outputforemost会把识别出来的文件按类型放入不同的子目录。对于 FAT 取证题这种做法经常能直接把隐藏在数据区里的文件挖出来。如果发现foremost提取出来的文件不完整打开只有半张图或者半截文本说明文件不是连续存储的必须用 FAT 表做簇链追踪。这是 CTF 题里最常见的一个陷阱——通过把文件故意弄成碎片来考察做题人对 FAT 表机制的理解。4. 常见问题与排查技巧实录4.1 strings 搜不到 flag 怎么办很多人第一步就跑了strings 金3fat | grep flag搜不到就慌了。其实 flag 藏在图片文件、压缩包文件或二进制结构里的时候strings是直接扫不出来的因为那个位置没有可以作为 ASCII 字符串连续输出的内容。我自己常用的排查顺序是file识别文件类型。binwalk扫描有没有内嵌文件。foremost把可分离的文件全部提取出来。对提取出来的每一个文件执行file、strings、binwalk的深度检查。如果还是没有回到十六进制层面检查 FAT 结构的隐藏项。这个顺序能规避大多数“漏网之鱼”。4.2 binwalk 分离不完整怎么办binwalk对分片文件的支持有限它扫描的是静态签名。如果一个文件被拆成几段存放在不同簇或者文件头被覆盖binwalk可能检测不到或者检测到了但只能提取出第一部分。这个时候拿提取出来的残缺文件再看看十六进制xxd output/部分文件 | head如果文件头是PKZIP但后面被人为插入了其他数据修复思路是用zip -FF尝试修复或者手动删除中间垃圾字节后重新组合。不过在 FAT 取证题里更常见的是不连续存储导致的碎片这种情况下只有通过 FAT 表重建簇链才行。4.3 伪加密与压缩包密码的坑如果题目给的是压缩包还有个常见套路伪加密。ZIP 文件的伪加密通过修改通用位标志General Purpose Bit Flag的第 0 位来实现。用十六进制查看器打开 ZIP 文件找到本地文件头50 4B 03 04里的标志字段偏移 0x06如果值是09 00说明加密位被置位了把第 0 位清零变成08 00再用压缩软件打开很可能就能直接解压。如果是真加密也别急着爆破先试试弱密码比如123456、password、flag、题目名、平台名等。CTF 出题人常用的密码一般不会太复杂很多就是常见的弱口令或题目相关单词。4.4 遇到隐藏文件系统或未分配空间的处理有些 FAT 取证题文件被删除后保存到未分配扇区里这种时候用testdisk扫描未分配空间是个好办法testdisk 金3fat它会列出探测到的分区和文件包括已删除文件。但注意testdisk对被覆盖过的扇区无能为力。如果判断文件内容已经被覆盖那就只能朝“是否有备用副本”这个方向想了比如 FAT 有主备两份某些工具会在备份区域保留元数据这经常被忽略。4.5 FAT12 和 FAT16 的 FAT 表项读取差异上面提过 FAT12 表项是 12 位读取时候有奇偶规则FAT16 是 16 位相对简单一些FAT32 是 32 位但高 4 位保留。做题时先确认镜像到底是哪种 FAT 类型。在 Linux 里可以这样看fsck -t vfat -v 金3fat输出里会显示文件系统类型与参数。这一信息直接决定你写解析脚本的时候怎么取表项。写脚本时有个简单技巧先用一个已知文件验证脚本是否正确。比如通过系统挂载看到一个正常的文本文件用脚本去提取它的数据和系统读出来的内容做对比如果一致说明脚本正确如果不一致优先检查 FAT 表偏移和目录项解析逻辑。5. 这类题目后续还能怎么玩做完“金3fat”这道题我建议你顺着这个方向再试几个变体一是把 FAT 文件系统和 Linux 下的debugfs、Windows 下的Recuva结合使用练习各种环境下的文件恢复二是尝试用Autopsy或者FTK Imager打开同一个镜像看看专业取证工具是怎么自动标出隐藏文件和已删除文件的并和手工分析结果互相对比。我自己实际做下来的体会是工具能帮你节省 80% 的时间但剩下 20% 需要你完全理解 FAT 的目录项和 FAT 表机制才能补上。CTF 的题目设计往往就是冲着那 20% 来的它故意让工具失灵逼你回到数据结构本身。另外一个小技巧做题时尽早把镜像文件做成只读副本后续所有爆破、提取、写操作都在副本上进行避免污染原始证据。我见过不少人为了改一个字节直接用编辑器打开了原始镜像结果把 FAT 表改了本来能解的题被自己毁了。镜像文件先cp一份或者取个work后缀的副本成本几乎为零但能保住你排查问题时的退路。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。