赖特在阴影中

这是关于我们为11月底举行CTFZone资格赛阶段所准备的任务之一的故事。您可以在此处阅读有关资格准备过程的信息

您从两个文件开始:decrypt_flag.py和ntfs_volume.raw。让我们看一下脚本。他打开一个名为key.bin的文件,然后使用循环尝试从文件中的每个偏移量获取34字节的二进制字符串,然后将其用作PBKDF2函数的输入。每个返回的密钥都用作XOR密钥,以解密缝合到代码中的加密字符串。如果其解密的MD5哈希与解密形式的预定值匹配,则脚本将使用接收到的数据来生成并打印标志。

因此,您需要找到key.bin文件。无法简单地对图像文件(ntfs_volume.raw)中的所有偏移量进行排序,因为查找密钥的过程太慢了。规则没有禁止这样做,但是您肯定不会在CTF结束之前有时间。

该映像文件包含一个单分区MBR分区表。它的偏移量是2048 512字节的扇区,它包含NTFS文件系统,但是key.bin文件不存在:

$ fls -o 2048 -r -p ntfs_volume.raw | grep -F key.bin | wc –l
0

NTFS存储UTF-16LE编码的文件名。让我们尝试搜索它!


文件记录

的搜索结果在研究了搜索结果之后,我们将重点放在以FILE签名[1]开头的文件记录。这是唯一这样的条目:


找到记录

目标已经接近!我们有一个文件记录,但是我们需要数据。在NTFS中,它们存储在$ DATA属性中,该属性可以是驻留的或不驻留的[2]。在我们发现的记录中,该属性从偏移量0×3AADD00开始,并指示非驻留数据(这意味着信息存储在文件记录之外)。

那么,所需文件的数据到底在哪里?为了回答这个问题,有必要对所谓的映射对或数据游程(对“块长度-块偏移”对)进行解码[3]。所需文件的数据运行如下(注意偏移量0×3AADD40):22 53 01 A0 4E 21 05 31 C1 11 38 3000。或者,如果我们重新排列它们:

1.	22 53 01 A0 4E
2.	21 05 31 C1
3.	11 38 30 00

该文件包含三个片段,其中一个片段的大小为339个群集,并且以群集#20128开始。对于使用PBKDF2的代码,此代码段很大。如文件系统标头所示,一个群集的大小为4096字节:

$ fsstat -o 2048 ntfs_volume.raw | grep 'Cluster Size'
Cluster Size: 4096

让我们看一下此偏移量的数据(以字节为单位):
2048 * 512 + 20128 * 4096 =83492864。我们将从此处提取大量信息(例如128字节),将其插入新文件中,我们将其称为key.bin,运行脚本...没有成功。

也许文件不是存储在当前文件中,而是存储在文件系统的先前版本中(以前的格式)-不要忘记,我们没有看到与已删除文件同名的记录。集群的大小是多少?让我们寻找带有NTFS签名[4]的文件系统头。也许我们很幸运,我们确实可以从以前的格式中找到标头。


文件系统标头

搜索结果搜索结果中的第一和最后位置是指当前文件系统,但是位于它们之间的文件系统标头似乎属于先前的格式。而且它们具有不同的群集大小!


从先前版本的文件系统头

00 02,或512。但是这样的群集大小被记录在一个0×0x4554800D的偏移:这样的扇区大小在一个0×4554800B的偏移写入F7,或247

因此,我们有簇大小(以字节计) 512 * 247 =126464。有些废话!如果您相信NTFS解析器[5],则该值必须带有符号并以特殊方式进行处理,因此实际群集大小(以扇区为单位)为1 <<-(-9)=512。或者,如果以字节为单位,则512 * 512 = 262144现在听起来更加可信。

数据从此处的偏移量开始(以字节为单位):
2048 * 512 + 20128 * 262144 =5277483008。让我们再次尝试对存储在此处的信息进行相同的操作……再次失败!怎么了?我们这里有CTF,这意味着“不可能”。

我们正在争夺的任务称为“阴影中”。它可能与卷的卷影副本有关。因此,我们有一个文件系统中先前存在于该卷中的文件。不幸的是,我们根本无法获取并安装其卷影副本,但是我们知道数据开始的确切偏移量!这是5277483008,或者在该部分的5277483008-2048 * 512 = 5276434432中。

根据VSS格式[6]的规范,重定向的数据块在包含64位字段的块描述符结构中进行了描述,在该字段中存储了原始偏移量(在卷内),并且也是描述目标块偏移量(在卷内)的64位字段。让我们将5276434432寻找为64位小尾数。

结果中只有两个结果,并且其中只有一个位于偶数偏移处。


找到的块描述符

目标偏移量:00 00 9B 03 00 00 00 00,或仅60489728。最终偏移量:60489728 + 2048 * 512 =61538304。从此处,将一定数量的数据导出到名为key.bin的新文件中,并...

$ ./decrypt_flag.py
ctfzone{my_c0ngr4t5_t0_u,w311_d0n3_31337}

做完了!

参考文献


  1. https://flatcap.org/linux-ntfs/ntfs/concepts/file_record.html
  2. https://flatcap.org/linux-ntfs/ntfs/attributes/data.html
  3. https://flatcap.org/linux-ntfs/ntfs/concepts/data_runs.html
  4. https://flatcap.org/linux-ntfs/ntfs/files/boot.html
  5. https://github.com/msuhanov/dfir_ntfs/blob/94bb46d6600153071b0c3c507ef37c42ad62110d/dfir_ntfs/BootSector.py#L58
  6. https://github.com/libyal/libvshadow/blob/master/documentation/Volume%20Shadow%20Snapshot%20(VSS)%20format.asciidoc#431-block-descriptor

Source: https://habr.com/ru/post/undefined/


All Articles