尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

磁盘取证实战:RCTF 2019 disk1镜像分析与删除文件恢复

磁盘取证实战:RCTF 2019 disk1镜像分析与删除文件恢复 前阵子整理CTF取证题又把RCTF 2019这道disk1拿出来复盘了一遍。磁盘取证这个方向外行看着就是拿工具扫一扫镜像找flag可真要动手你会发现它涉及文件系统、数据恢复、痕迹分析一堆底层知识。这篇不打算复述官方writeup而是从一名做题人和取证工程师的双重视角带你完整走一遍拿到disk1后的分析流程识别镜像、挂载、文件搜索、删除文件恢复再附上我踩过的坑和常用的筛选技巧。适合刚接触取证、或者刷了不少题但总在最后一步卡住的朋友。1. 拿到题目先别急着瞎翻整体思路与考点拆解1.1 磁盘取证题到底在考什么磁盘取证题的核心是模拟拿到一块“来历不明”的磁盘后如何在不破坏原始数据的前提下把有用的线索完整提取出来。出题人常见的操作是把flag伪装成普通文件、塞进压缩包、删除后再留痕迹或者藏在文件尾部、磁盘空闲区域。所以做题不能只想着“我能不能扫到flag字符串”而是要建立一套完整的工作流固定镜像、识别介质、分析分区、提取文件、恢复删除数据、串联上下文。一道合格的磁盘取证题考验的是三件事第一对磁盘镜像格式和文件系统布局的理解第二对常用取证工具链的熟练度第三从零散线索里组织证据链的能力。第一点尤其重要很多人卡住不是因为不会用工具而是不知道镜像到底是raw、vmdk还是E01不知道分区偏移怎么算结果后面所有操作全在碰运气。1.2 disk1这道题为什么值得认真做RCTF 2019的disk1从标题就能看出是系列取证题里比较基础的一道但它非常典型。这类题目通常不会让你直接挂载后就看到一个flag.txt而是需要你走完取证的基本流程可能涉及镜像格式判断、文件系统识别、隐藏文件查找甚至删除文件恢复。正因为难度适中它特别适合用来检验自己的取证基本功。如果你能不看任何writeup独立完成拿到镜像后先校验哈希、判断格式再通过分区表定位文件系统用只读方式挂载或使用Sleuth Kit提取文件最后在删除区或者文件尾部找到flag那说明你基本入了取证的门。后面再做更复杂的题目比如多分区、LVM卷组、NTFS备用数据流、内存取证也会顺畅不少。1.3 准备好这些工具少走一半弯路我推荐直接用Kali Linux做这类题不是因为Kali“看起来专业”而是它自带绝大多数取证工具省去编译安装的麻烦。如果不想用KaliUbuntu或Debian装了对应软件包也可以。工具用途典型命令file识别镜像格式file disk1.imgmd5sum/sha1sum记录镜像哈希固定证据sha1sum disk1.imgmmls/fdisk查看分区表mmls disk1.imgfsstat/fls/icat分析文件系统、列出文件、按inode导出fls -f ext4 -o 2048 disk1.imgmount只读挂载分区mount -o loop,ro,offset1048576strings提取可打印字符串strings -a disk1.imgbinwalk扫描文件尾部追加数据和嵌套文件binwalk -e target.jpgforemost/photorec按文件签名恢复数据foremost -t zip,png,jpg -i disk1.imgbulk_extractor自动提取未分配空间、URL、邮箱等特征bulk_extractor -o beout disk1.imgAutopsyGUI综合分析平台autopsy工具不在多关键是明白每个工具在哪个环节用。很多新手拿到镜像第一件事就是strings扫全场结果输出几万行人直接麻了。正确姿势应该是按流程走先摸清镜像结构再有目的地搜索和恢复。2. 从镜像文件到可读磁盘底层分析三步走2.1 镜像文件验明正身file 哈希拿到题目第一步永远是给镜像文件“验明正身”。我会先执行两条命令md5sum disk1.img file disk1.img哈希不是走过场。取证讲究可复现性如果你在分析过程中不小心改动了镜像哈希值对不上后面所有结论都失去依据。CTF题虽然不需要做司法鉴定但养成记录哈希的习惯能帮你排除“是不是镜像被改过”这类干扰。file的输出决定后续策略。常见情况有这么几种Linux rev 1.0 ext4 filesystem data说明这个镜像本身就是某个分区的文件系统镜像没有MBR/GPT分区表可以直接挂载或用Sleuth Kit分析。DOS/MBR boot sector说明是完整磁盘镜像包含分区表需要进一步用fdisk或mmls看分区布局。VMware4 disk image或Microsoft Disk Image说明是虚拟磁盘格式可能要用qemu-img转换后再分析。data最不确定可能文件头被抹掉、不是raw格式也可能是加密或稀疏文件。如果file输出data别急着放弃。用xxd disk1.img | head看看文件开头十六进制如果能看到7f 45 4c 46之类ELF头或者50 4b 03 04这种zip签名说明文件前面是有结构的file只是没认出来。2.2 查看分区表MBR还是GPT偏移量从哪里来如果file显示是MBR磁盘镜像接下来要看分区表fdisk -l disk1.img mmls disk1.imgmmls的输出很直观。假设看到类似这样的内容Slot Start End Length Description 00: Meta 0000000000 0000000000 0000000001 Primary Table (#0) 01: ----- 0000000000 0000002047 0000002048 Unallocated 02: 00: Linux 0000002048 0004194303 0004192256 Linux (0x83)这里最关键的一列是Start它表示分区的起始扇区。上面例子中Linux分区从2048扇区开始默认扇区大小是512字节所以这个分区在文件中的字节偏移量是2048×5121048576字节。这个数字后面挂载时要用到。如果镜像是GPT布局分区表结构会更复杂可能有一个EFI System Partition、一个MS Reserved分区再后面才是真正的数据分区。但分析方法一样找到包含目标文件系统的那个分区记录它的起始扇区然后让工具从这个偏移量开始读取。还有一种极端情况file直接显示ext4 filesystem data那说明镜像本身就是文件系统没有分区表这时候不需要算offset直接进入下一步。2.3 挂载操作的正确姿势只读优先偏移别算错确定分区偏移后可以用mount挂载mkdir -p /mnt/disk1 mount -o loop,ro,offset1048576 disk1.img /mnt/disk1loop让Linux把普通文件当作块设备挂载ro表示只读offset指明分区在文件中的起始位置。这里最大的坑是单位。mount的offset单位是字节不是扇区。如果你把2048直接写进去系统会从一个根本不存在的文件系统偏移开始读取自然挂载失败。为什么强调ro因为某些文件系统挂载时会尝试更新日志或修改访问时间如果对原始镜像做这些操作可能导致镜像内容变化也容易让后续取证工具产生误判。取证准则就是“分析副本保留原始镜像”。所以更稳妥的做法是先复制一份镜像再对副本操作cp disk1.img disk1-copy.img如果挂载失败不要死磕可以用Sleuth Kit以只读方式直接分析镜像fsstat -f ext4 -o 2048 disk1.img fls -f ext4 -o 2048 -r disk1.imgfls -r会递归列出文件前面带*的表示已删除条目。这种方法不需要root权限也不需要挂载对损坏镜像尤其好用。后面恢复删除文件时我们还要继续依赖它。3. 三种搜索策略strings、文件类型、上下文痕迹3.1 strings的有效姿势当磁盘结构摸清以后才开始真正的“信息搜索”。最常用也最容易用错的工具是strings。strings -a disk1.img | grep -iE flag|rctf|ctf|\{直接扫全盘虽然简单但输出量很大而且很多匹配项其实是二进制指令里碰巧出现的字节组合。稍微聪明一点的做法是缩小范围strings -a disk1.img | grep -E \{.*\} | grep -iE flag|rctf|key | head -50如果某个字符串的位置信息很重要可以让strings输出偏移量strings -t d -a disk1.img | grep -i flag拿到偏移量以后可以对照分区表估算这个字符串落在哪个分区、哪个文件附近。如果你想扫的是挂载目录里的所有文件也可以用grep直接扫grep -r -a -oE flag\{[^}]\}|RCTF\{[^}]\} /mnt/disk1/注意-a参数它让grep把二进制文件也当作文本处理。实战经验里直接找到明文字符串的概率并不高因为出题人会做各种变形base64编码、十六进制、rot13甚至把花括号换成全角所以要多试几种格式。常见做法是把可疑字符串用base64 -d或xxd -r -p还原后再看。3.2 按文件类型缩小目标别被海量文件淹没strings扫出来的候选太多时另一种更可靠的手段是从文件本身入手。挂载后先给所有文件做一次“人口普查”find /mnt/disk1 -type f -exec file {} \; /tmp/filelist.txt cat /tmp/filelist.txt | grep -vE ASCII|Unicode|empty这个命令把所有非文本文件筛出来重点看图片、压缩包、可执行文件、数据库文件。为什么重点看这些因为普通纯文本文件一眼就能看完没有藏东西的价值而图片和压缩包天然适合附加数据。拿到可疑文件后用binwalk扫一下binwalk secret.jpg如果输出里有ZIP archive那基本就是图片尾部被追加了一个压缩包。用binwalk -e可以直接提取binwalk -e secret.jpg -C extract图片尾部藏zip是CTF里最常见的隐藏方式。图片查看器会忽略文件末尾的多余字节但binwalk不会。另一个容易被忽略的是图片元数据exiftool secret.jpgExif信息里的Comment、Artist、Copyright等字段经常被用来藏提示有时候甚至直接就是flag。3.3 从“用户行为痕迹”找线索有些磁盘镜像会给你一整套模拟出来的用户环境比如home目录、root目录、浏览器配置、下载目录等。遇到这种镜像一定要养成看“用户行为痕迹”的习惯因为出题人埋线索时往往会模拟真实操作。几个必须看的位置cat /mnt/disk1/root/.bash_history ls -la /mnt/disk1/home/user/Downloads ls -la /mnt/disk1/home/user/.local/share/Trash sqlite3 /mnt/disk1/home/user/.config/google-chrome/Default/History select url,title from urls;.bash_history里可能会看到作者执行过的压缩命令比如zip -P password flag.zip flag.txt这种信息往往直接指向解密密码。回收站目录里则可能躺着“被删除”的线索文件。SQLite数据库文件需要用sqlite3查看但里面保存的URL、标题同样可能包含flag格式的字符串。这一节想说的是磁盘取证不是单纯的数据恢复它更接近“数字侦查”。你不仅要知道文件系统里有什么还要理解使用者留下了什么痕迹然后把零散信息串联起来。4. 删除文件与空闲空间flag藏在你看不见的地方4.1 为什么删除文件还能恢复很多人在这一步卡住是因为在挂载目录里翻来翻去都找不到flag就以为题目无解。其实出题人最爱干的一件事就是把flag写进一个文件再把它删除。这样ls看不到但底层数据还在。文件系统删除文件时通常不会清空数据块只是把目录项标记为删除并释放inode位图。数据还留在原来的扇区上只要没有被新数据覆盖就可以恢复。打个比方图书管理员只是把索引卡片丢掉了书本身还在书架上。只要没有新书占用这个位置你就有机会把书找回来。4.2 先用foremost/photorec做“粗暴”恢复最简单的恢复工具是foremost和photorec它们按文件签名去扫描原始磁盘块。foremost -i disk1.img -o recovered但我不建议直接全类型恢复因为默认配置会扫描很多文件类型恢复结果里会出现大量无关文件。对这个场景指定关键类型就够了foremost -t zip,png,jpg -i disk1.img -o recoveredphotorec更适合恢复照片类文件但恢复出来以后文件名会丢失需要你根据内容判断。下面是这两种方法的对比工具原理优点缺点foremost按文件头部和尾部签名定位速度快支持类型多对碎片化文件恢复效果差photorec基于扇区扫描按内容识别能恢复部分碎片文件名丢失输出量大如果foremost恢复出一堆文件先不要着急人肉看我在第5节会写一个批量筛选脚本。如果你的镜像更“干净”用foremost很可能直接找到被删的zip或png省掉很多后续步骤。4.3 更精细的删除文件恢复Sleuth Kit一条龙foremost不够精细因为它不看文件系统元数据。真正能保留文件路径和inode信息的是Sleuth Kit系列工具。先列出已删除文件fls -f ext4 -o 2048 -rd disk1.img-r表示递归-d表示只显示删除项。输出可能长这样* r/r 5328: flag.zip前面的*表示这个目录项已经被删除。中间的数字是inode号。接下来用icat按inode号导出内容icat -f ext4 -o 2048 disk1.img 5328 flag.zip file flag.zip unzip flag.zip如果导出的文件是压缩包解压时需要密码优先回到镜像里找密码线索比如.bash_history、文件名注释、图片Exif等。很多CTF题的密码都是弱密码但没有必要上来就爆破因为出题人往往会把密码“埋”在镜像的某个角落。如果镜像文件系统是ext2/ext3/ext4也可以用debugfs进入镜像交互式分析debugfs disk1.img lsdellsdel能列出已删除的inode再配合dump命令导出。Sleuth Kit和debugfs各有优势前者更适合脚本化批量分析后者对单文件操作更直接。4.4 空闲空间、slack空间与文件尾部追加数据如果删除文件也没有线索那就要把视野放到“不可见空间”。一个分区里有几种容易被忽略的地方文件slack空间文件内容占用未满整个块的剩余部分可能残留之前写过的数据。分区未分配空间删除且未覆盖的数据所在区域。文件尾部追加数据图片或音频文件结束后附加的压缩包或文本。Sleuth Kit提供blkls来提取这些区域。比如导出未分配空间blkls -e disk1.img unallocated.bin导出slack空间blkls -s disk1.img slack.bin对提取出来的数据继续用strings和binwalk分析。另一个好用的工具是bulk_extractor它会自动把镜像里的URL、邮箱、文件头、压缩包特征等抽出来bulk_extractor -o beout disk1.img grep -riE flag|rctf beout/bulk_extractor的输出目录里有很多txt文件每个文件对应一种特征类型。它能省去大量手写脚本的麻烦尤其是在面对大镜像时效率优势非常明显。5. 卡壳时怎么办问题排查与复盘清单5.1 恢复文件太多如何快速锁定flag使用foremost或photorec恢复后输出目录里可能有几十甚至上百个文件一个个看肯定不现实。我常用的方法是用一个小脚本自动做粗筛mkdir -p hits for f in $(find recovered -type f); do if file $f | grep -qiE zip|png|jpeg|gzip; then if strings $f | grep -qiE flag|rctf|ctf|key; then echo [] $f cp $f hits/ fi fi done这段脚本先通过file判断文件类型只保留压缩包和图片再对这类文件执行strings搜索关键词。命中的文件统一复制到hits目录后续可以再用binwalk和exiftool做细看。如果这样还没结果可能是flag被压缩包内层包裹或者被编码过。这时候再对hits目录里的每个文件执行for f in hits/*; do binwalk $f; done如果某个压缩包不是完整的zip头foremost可能只恢复了残缺文件binwalk反而能发现内部偏移。总之筛选的核心思路是“先按类型过滤再按内容过滤”不要拿肉眼去对抗海量输出。5.2 我遇到过的5个典型坑现象原因解决办法mount提示wrong fs typeoffset填错或镜像不是文件系统用mmls确认分区起始扇区用fsstat测试strings全盘扫不到flagflag被压缩、编码或加密先恢复删除文件再检查压缩包和编码格式foremost恢复出一堆0字节文件文件不连续或头部被覆盖改用fls/icat按inode恢复尝试blkls提取空闲空间挂载后看到空目录分区结构是LVM或RAID用lvscan/pvscan识别或直接string搜全盘删除文件用fls能看到但icat导不全文件碎片化用photorec恢复或人工拼接碎片offset算错是新手最容易犯的问题。fdisk/mmls里显示的是扇区号mount的offset要求字节数两者之间要乘以512。这个乘法看似简单但一旦漏掉后面全是白忙活。另一个容易被忽略的是镜像副本问题。有人图省事直接在原始镜像上开foremost虽然大部分时候没问题但一旦执行了写操作结果就不可信了。我习惯把原始镜像放一边所有分析都在副本上做。5.3 做完disk1之后下一步怎么练如果你能独立解决disk1说明已经掌握了磁盘取证的基础路径。接下来我建议做两件事。第一把手里的工具链做成一个固定流程。比如每次拿到镜像都按“哈希→file→mmls→fsstat→fls→foremost→blkls→bulk_extractor”的顺序走一遍形成肌肉记忆后面遇到复杂题就不会漏掉关键步骤。第二自己动手制造一个练习镜像。用dd取一个空分区往里面放一个隐藏文件再放一个删除文件再往一张图片尾部追加一个zip最后把整个分区做成raw镜像从零开始找flag。这个练习能帮你理解删除、隐藏、附加数据在文件系统层面的表现比盲目刷题有用得多。磁盘取证不是一门孤立的技术后面还会延伸到内存取证、日志取证、流量取证但底层思维是一致的在看似正常的数据里找到不正常的痕迹并且让每一步结论都有依据。把disk1吃透这个思维基础就打牢了。
返回列表